Slide 1

Slide 1 text

gob バイナリが Go バージョンによって 出力が変わることについて調べてみた 2024/09/13 Asakusa.go #3

Slide 2

Slide 2 text

自己紹介 @convto 株式会社LayerX所属 (読みはこんぶとです)

Slide 3

Slide 3 text

gob ってなに? - Go が標準パッケージで実装してる独自のエンコーディング! - 仕様とかくわしく知りたい人はこちらをご覧ください https://speakerdeck.com/convto/understanding-gob-encoding - きょうは 5min LT なので全員完全理解者だと思って話を進めます

Slide 4

Slide 4 text

ある日知人から以下のタレコミをうける

Slide 5

Slide 5 text

タレコミ - なんか Go のバージョンによって gob の出力が異なるんだけど - marshal/unmarshal 間の互換性はありそう - どこで変わったんだろうね

Slide 6

Slide 6 text

確認してみる

Slide 7

Slide 7 text

確認してみる

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

cnt: 36 id: -64 cnt: 12 id: 64 cnt: 37 id: -65 cnt: 12 id: 65

Slide 10

Slide 10 text

なんか typedef / value の id がずれてそう - たしかに出力は変わっている - id の値が変わっている - id = 65 だと typedef がちょうど 1byte で表現できないため、古い方は ちょっと勿体無い - 先頭 1bit が終端判定、末尾 1bit が正負判定。値が 6bit で収まる なら 1byte で表現できる。65 はちょうどたりない

Slide 11

Slide 11 text

どこで入った? - 霊感で 1.21 まで比べてみたら 1.23 と一致してた $ diff -s <(go1.21.0 run main.go) <(go1.23.0 run main.go) Files /dev/fd/11 and /dev/fd/12 are identical - 1.20.1 系では挙動に差がない $ diff -s <(go1.20.1 run main.go) <(go1.20.14 run main.go) Files /dev/fd/11 and /dev/fd/12 are identical - 1.21 に上がる時に入っているはず!

Slide 12

Slide 12 text

見つけた! https://go-review.googlesource.com/c/go/+/460543/4 /src/encoding/gob/type.go#b184

Slide 13

Slide 13 text

id ずれた理由 - firstUserId = 64 が定義されてて user 定義の型は id = 64 から始ま る - とりあえず nextId +1 から確保してたのが止まって 64 から使えるように なったという話っぽい!

Slide 14

Slide 14 text

スッキリ

Slide 15

Slide 15 text

知人に伝えて平和が訪れた

Slide 16

Slide 16 text

感想 - marshal/unmarshal の互換を担保した上で encoded な値が変わるこ とはちょいちょいある - よくあるのはフィールド順番担保されないとか。今回は typeid が揃わな かった - encoded な値に対して一致するか確認する、みたいな処理は秘孔をつく 可能性があるのでやめておきましょう

Slide 17

Slide 17 text

ご清聴ありがとうございました