Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Go runtimeの歩き方/how to follow go runtime function

convto
April 23, 2022
590

Go runtimeの歩き方/how to follow go runtime function

Go Conference Sprint 2022 にて発表したLTです。
https://gocon.jp/2022spring/ja/sessions/lt7/

Go の runtime は plan9 ベースのアセンブリでの実装があったり、他ではあまり見かけない compiler directive を使用していたり、 初見だと builtin 関数の名称がわからなかったり、前知識なしにコードが追いづらいです。

そこでこれらの解説や go tool objdump で builtin 関数を追う手法を紹介し、 runtime パッケージを読むための前提知識をまとめます。

以下資料内URL

p4
- https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/builtin/builtin.go;l=135-156

p7
- https://go.dev/doc/asm

p8
- https://go.dev/play/p/gTlrfNa1v0l

p9
- https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/runtime/alg.go;l=46-47
- https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/runtime/asm_amd64.s;l=1077-1087

p11
- https://pkg.go.dev/cmd/compile#hdr-Compiler_Directives

p13
-
https://go.dev/play/p/0PpO7GicM2X

p14
- https://go.dev/play/p/tdVVRLwt3O6

p15
- https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/runtime/atomic_pointer.go;l=42-43
- https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/sync/atomic/doc.go;l=140-141
- https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/sync/atomic/asm.s;l=84-85

p17
- https://convto.hatenablog.com/entry/2022/04/02/222353

p18
- https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/cmd/compile/internal/typecheck/universe.go;l=32-62

p19
- https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/cmd/compile/internal/typecheck/const.go;l=538-540
- https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/cmd/compile/internal/typecheck/const.go;l=864-939

p20
- https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/cmd/compile/internal/walk/expr.go;l=265-267
- https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/cmd/compile/internal/walk/builtin.go;l=118-124

convto

April 23, 2022
Tweet

More Decks by convto

Transcript

  1. Go runtime ͷา͖ํ
    Go Conference 2022 Spring LT
    2022-04-23
    @convto

    View Slide

  2. @convto
    גࣜձࣾKyashॴଐ
    ϨΠϠ௿Ίͷٕज़΍҉߸ٕज़ʹڵຯ
    ͋Γ
    աڈʹ͸protobufͷ؆қతͳύʔα
    ʔॻ͍ͨΓplain RSA࣮૷ॻ͍ͨΓ
    ͠·ͨ͠

    View Slide

  3. ൃදͷ໨త
    • ͋Δ͍ͯͲGoΛॻ͍͍ͯΔͱ৭ʑͳཧ༝Ͱruntime͕ಡΈͨ͘ͳΔ
    • goroutine΍GCͷڍಈཧղ
    • ͦͷଞٕज़తڵຯ
    • ͱ͸͍͑runtime͸લ஌ࣝͳͩ͠ͱҰ෦ίʔυ͕௥͍ͮΒ͍
    • ؔ਺ఆٛͱ࣮૷͕ผϑΝΠϧʹ͋ΔΑ͏ͳέʔεͷ௥͍ํΛ͋Δఔ౓·ͱΊͯɺruntimeΛಡΉ
    લ஌ࣝΛ੔͑Δ͜ͱ͕໨త
    • runtime΍compilerଆͰ۩ମతʹߦΘΕ͍ͯΔॲཧʹ͍ͭͯɺৄࡉʹ͸৮Ε·ͤΜ
    • ͋͘·Ͱॲཧͷ௥͍ํΛ঺հ͢Δ͜ͱ͕໨తͰ͢ʂڵຯ࣋ͬͨํ͸ͥͻಡΜͰΈ͍ͯͩ͘͞

    View Slide

  4. ྫ: builtinؔ਺ https://cs.opensource.google/go/go/+/refs/tags/
    go1.18:src/builtin/builtin.go;l=135-156
    • builtin pkg ͸υΩϡϝϯ
    τ༻ఆٛͷΈ
    • ࣮૷͸Ͳͩ͜Ζ͏ʁ
    • unsafe pkg ͳͲ΋ಉ༷

    View Slide

  5. Contents
    1. ΞηϯϒϦʹΑΔ࣮૷
    • ॻ͖ํͷ঺հ
    • runtimeͷ࣮ྫ
    2. //go:linkname σΟϨΫςΟϒ
    • linknameσΟϨΫςΟϒͷ঺հ
    • runtimeͷ࣮ྫ
    3. builtin/unsafe
    • src/cmd/compile/internal/gc ͷ௥͍ํ
    • go tool objdump Λ࢖͏
    4. ·ͱΊ

    View Slide

  6. ΞηϯϒϦʹΑΔ࣮૷

    View Slide

  7. Goͷؔ਺࣮૷͸ΞηϯϒϦͰ΋Ͱ͖Δ
    • GoͰ͸ؔ਺ͷ࣮૷Λplan9ϕʔεͷΞηϯϒϦͰॻ͚Δ
    • ΞʔΩςΫνϟ΍OSࠩ෼Λߟྀ͢ΔύοέʔδͰར༻͞Ε͍ͯΔ
    • ͜ͷΞηϯϒϦ͸ந৅Խ͞Εͨ΋ͷͰ͋Γɺجຊ͸ର৅ͷΞʔΩςΫνϟͱ௚઀
    ݁ͼ͍͍ͭͯͳ͍ɻҰ෦໋ྩ͸CPUͷ໋ྩΛ௚઀දݱ͍ͯ͠Δɻ
    • https://go.dev/doc/asm ʹ΋هࡌ͕͋Δ௨Γɺͳʹ͕ந৅తͳ໋ྩͰɺͳʹ͕
    ۩ମతͳ໋ྩ͔ͷ໢ཏతͳυΩϡϝϯτ͸ͳ͍໛༷
    • Go࣮૷Ͱ֬ೝͨ͠ൣғͰ͸ɺx86_64ͷAESENCͳͲ͸ͦͷ··ͩͬͨ

    View Slide

  8. ॻ͖ํͷ঺հ https://go.dev/play/p/gTlrfNa1v0l
    • playgroundͰ࣍ͷΑ͏ʹॻ
    ͚Δ
    • ࣗ෼Ͱ༡ΜͰΈ͍ͨਓ͸
    https://go.dev/doc/asm
    ͱɺதͷϦϯΫΛҰ௨Γಡ
    ΉͱΑ͛͞

    View Slide

  9. runtimeͷ࣮ྫ
    https://cs.opensource.google/go/go/+/refs/tags/
    go1.18:src/runtime/alg.go;l=46-47
    https://cs.opensource.google/go/go/+/refs/tags/
    go1.18:src/runtime/asm_amd64.s;l=1077-1087
    • ࣮ࡍಡΉͷ͸ͪΐͬͱେ
    ม͔΋͠Εͳ͍
    • Ͱ΋࣮૷ͱఆٛͷؔ܎͕
    Θ͔Δͱɺ͍͔ͭಡΈͨ
    ͘ͳͬͨͱ͖ʹಡΊΔ

    View Slide

  10. //go: linknameσΟϨΫςΟϒ

    View Slide

  11. σΟϨΫςΟϒͱ͸
    • ಛघͳܗࣜͷίϝϯτͱ֤ͯ͠छཁٻΛ఻͑ΒΕΔ
    • ࠷ۙͩͱ //go: embed ͋ͨΓ͕هԱʹ৽͍͠
    • ίϯύΠϥͷڍಈʹؔ࿈͢Δ΋ͷ͸ https://pkg.go.dev/cmd/compile#hdr-
    Compiler_Directives ʹ͍͔ͭ͘هࡌ͕͋Δ(͜͜ʹॻ͔Εͯͳ͍΋ͷ΋ιʔ
    είʔυΈͯΔͱී௨ʹ͋ΔɻࠔͬͨΒ౎౓άάΔͳΓίϯύΠϥଆΛಡΉ
    ͳΓ͢Ε͹Α͍)
    • linknameͱ͔nosplit͸Α͘ݟ͔͚Δ

    View Slide

  12. linknameσΟϨΫςΟϒͱ͸
    • `//go:linkname localname [importpath.name]` ͷܗͰࢦఆ
    • localnameͰఆٛͨ͠ม਺/ؔ਺ͷobject fileͷγϯϘϧ໊Λimportpath.nameͷ΋ͷʹͰ͖Δ
    • Α͏͸ϓϩάϥϜ͔Β͸localnameͰݺ͹Ε·͕͢ɺόΠφϦ্Ͱ͸importpath.nameͷݺͼग़͠
    ʹͳΓ·͢
    • ඇެ։࣮૷Λݺͼग़͢Α͏ʹ͔ͭ͏ύλʔϯɺඇެ։࣮૷Λlocalnameͷఆٛ಺༰Ͱ্ॻ͖͢ΔΑ
    ͏ʹ͔ͭ͏ύλʔϯͳͲ͋Γ·͕͢ɺࠓճ͸࣌ؒͷ౎߹্ɺඇެ։࣮૷Λݺͼग़͢Α͏ͳύλʔ
    ϯͷΈ঺հ
    • importͯ͠ͳ͍(΋͘͠͸runtimeͰ࣮૷͞Ε͍ͯͳ͍)Ϟδϡʔϧͷม਺/ؔ਺ʹ޲͚Δͱɺଘࡏ͠
    ͳ͍޲͖ઌʹ޲͍ͯյΕΔ

    View Slide

  13. ॻ͖ํͷ঺հ https://go.dev/play/p/knFXmUPcsd-
    • ඇެ։ͷॲཧΛಡΈग़ͯ͠ͳΜ
    ΍͔΍΍ͬͨΓ
    • ༨ஊͰ͕͢reflectύοέʔδͷඇ
    ެ։ॲཧ typelinks() ΍ rtypeof()
    ͱ૊Έ߹ΘͤΔͱΰϦΰϦʹܕ
    ৘ใΛऔΓग़ͨ͠ΓͰ͖·͢

    View Slide

  14. յΕΔྫ https://go.dev/play/p/tdVVRLwt3O6
    • ͜Ε͸γϯϘϧஔ͖׵͑
    ઌͷstrconv.lowerΛ
    importͯ͠ͳ͍ྫ
    • ଘࡏ͠ͳ͍޲͖ઌʹlink͠
    Α͏ͱͯ͠ࢮ͵

    View Slide

  15. runtimeͷ࣮ྫ
    https://cs.opensource.google/go/go/+/refs/tags/
    go1.18:src/runtime/atomic_pointer.go;l=42-43
    https://cs.opensource.google/go/go/+/refs/tags/
    go1.18:src/sync/atomic/doc.go;l=140-141
    https://cs.opensource.google/go/go/+/refs/tags/
    go1.18:src/sync/atomic/asm.s;l=84-85
    • ίʔυྔগͳͯ͘આ໌͠΍͢
    ͍ྫ
    • ΞηϯϒϦܦ༝ͯ͠δϟϯϓ͠
    ͨΓͯ͠Δ͚ͲͪΌΜͱ௥͑Δ
    • linkname͸΄͔ʹ΋cgoܥͷॲ
    ཧͰ΋ଟ༻͞ΕͯΔ

    View Slide

  16. builtin/unsafe

    View Slide

  17. builtin/unsafe
    • runtime಺ʹ͸builtinͷ࣮૷ͱࢥΘ͖ؔ͠਺͕͍͔ͭ͋͘Δ͕ɺbuiltinؔ਺ͷ໊
    લ͔ΒٯҾ͖ͮ͠Β͍(newobjectΈ͍ͨͳͪΐͬͱҧ͏໊લʹͳͬͯΔ)
    • unsafe͸ͦ΋ͦ΋runtimeʹͦΕͬΆ͍࣮૷͕ͳ͍
    • ίϯύΠϥଆΛಡΉΞϓϩʔνͱɺgo tool objdumpͷΞϓϩʔνΛ঺հ͠·͢
    • ࣌ؒͷ౎߹্దٓ͸͠ΐΔͷͰৄ͘͠ίʔυ௥͍͔͚͍ͨํ͸ɺҎલ௥͍͔͚
    ͨͱ͖ͷϝϞ https://convto.hatenablog.com/entry/2022/04/02/222353 Λ͝
    ΒΜ͍ͩ͘͞

    View Slide

  18. ίϯύΠϥ࣮૷
    ͔Β௥͍͔͚Δ 1
    https://cs.opensource.google/go/go/+/refs/tags/
    go1.18:src/cmd/compile/internal/typecheck/
    universe.go;l=32-62
    • ίϯύΠϧ࣌ʹΑΈͱͬͨτʔΫ
    ϯΛதؒදݱʹ͢Δ
    • ͦͷͱ͖ʹbuiltin࣮૷ͱඥ෇͚ͨ
    Γunsafe࣮૷ͨ͠Γͯ͠Δ
    • →͸builtinͱ͔unsafeͷτʔΫϯ
    ͱதؒදݱͷOPඥ෇͚ͯΔͱ͜

    View Slide

  19. ίϯύΠϥ࣮૷
    ͔Β௥͍͔͚Δ 2
    unsafeฤ
    https://cs.opensource.google/go/go/+/refs/tags/
    go1.18:src/cmd/compile/internal/typecheck/
    const.go;l=538-540
    https://cs.opensource.google/go/go/+/refs/tags/
    go1.18:src/cmd/compile/internal/typecheck/
    const.go;l=864-939
    • தؒදݱͷOPͱඥ෇͍ͨͷͰɺͭ͗
    ͸OPಡΜͰΔͱ͜ΖΛݟͯΈΔ
    • ͍Ζ͍Ζ௥͍͔͚ΔͱˠͷՕॴ͕
    unsafeͷOPʹର͢Δ࣮૷ͳΑ͏
    • νϥݟͨ͠ൣғͩͱɺܕ͝ͱʹsizeͱ
    ͔͕Θ͔ΔͷͰͦΕΛݩʹؤுͬͯ
    ܭࢉͯ͠ΔͬΆ͍͚Ͳৄࡉ͸ׂѪ

    View Slide

  20. ίϯύΠϥ࣮૷
    ͔Β௥͍͔͚Δ 3
    builtinฤ
    https://cs.opensource.google/go/go/+/refs/tags/
    go1.18:src/cmd/compile/internal/walk/expr.go;l=265-267
    https://cs.opensource.google/go/go/+/refs/tags/
    go1.18:src/cmd/compile/internal/walk/
    builtin.go;l=118-124
    • close() Λྫʹ͓͍͔͚ʂ
    • walkExpr1() ͱ͍͏ॲཧͰbuiltinͷOP͔Βதؒද
    ݱ͕࡞ΒΕ͍ͯΔ
    • ͦͷͳ͔Ͱ͞Βʹ walkClose() ͕ݺ͹Εruntime࣮
    ૷ͱඥ෇͚ΒΕ͍ͯΔ
    • mkcall() ͸ࢦఆͨؔ͠਺callͷதؒදݱΛಘΔ΍ͭ
    • ͜ͷྫͰ͸࠷ऴతʹ͸runtimeͷ closechan() Λ
    call͢Δதؒදݱ͕ಘΒΕΔ

    View Slide

  21. go tool Λ࢖͏
    • ίϯύΠϥ࣮૷ಡΉͷ͸࣮͚֬ͩͲ໘౗
    • ͦΜͳͱ͖͸ `go tool objdump` Λ࢖͓͏ʂ
    • ద౰ͳ࠷খίʔυॻ͍࣮ͯߦ͢ΔͱͦΕͬΆ
    ͍ͷ͕ग़ͯ͘ΔͷͰ໨੕͚ͭΔͷʹ͓͢͢Ί
    • →͸print() ͷ࣮૷Λ୳͢ྫ
    • ͪͳΈʹ࣮ࡍʹruntimeͷ࣮૷ΛݟΔͱܕ͝
    ͱʹprintॲཧ͕४උ͞ΕͯΔ͜ͱ΋Θ͔Δ

    View Slide

  22. ·ͱΊ

    View Slide

  23. ίʔυ௥͍ํ·ͱΊ
    • ΞηϯϒϦͰ࣮૷͞ΕͯΔ͜ͱ͕͋Δ
    • σΟϨΫςΟϒ͍ͬͺ͍͋Δ
    • linknameͰ޲͖ઌ͕ஔ͖׵͑ΒΕͯΔͱ͖͕͋Δ
    • unsafe/builtin͸ίϯύΠϥಡΜͩΓ go tool Ͱ͓஡Λ୙ͨ͠Γ͠Α͏
    • Go͸runtimeଆͰඇಉظαϙʔτ͕͋ͬͨΓlibcґଘͳ͔ͬͨΓɺ͔
    ͳΓϢχʔΫͳݴޠͳͷͰ໘ന͍Ͱ͢ʂΈͳ͞Μ΋ڵຯ͋Ε͹ͥͻʂ

    View Slide

  24. ͓·͚
    • ࣮૷௥͍͔ͨϑϩʔνϟʔ
    τΛੜ࢈͠·ͨ͠
    • ΄͔ʹ΋ύλʔϯ͋Δ͔΋
    ͚ͩͲେମͳΜͱ͔ͳΔ͸
    ͣ
    • Α͔ͬͨΒͥͻ
    • cmd/compile/internal ΑΉ
    • go tool objdumpͰ໨੕Λ͚ͭΔ
    ஔ͖׵͑ઌͷ࣮૷ΛಡΉ
    ΞηϯϒϦͷ࣮૷Λ֬ೝ
    VOTBGF
    PSCVJMUJO
    MJOLOBNF
    Y
    Y
    N
    N
    ࣮૷͕ͳ͍ʂͷϑϩʔνϟʔτ

    View Slide

  25. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ

    View Slide