Help us understand the problem. What is going on with this article?

SwiftのstructのメモリレイアウトサイズをdSYMから取り出す

More than 3 years have passed since last update.

環境

Xcode 8.3.2 (Swift 3.1)

動機

EXC_BAD_ACCESS on devices if nested structs are used with Xcode 8.3 and Swift 3.1
https://bugs.swift.org/browse/SR-4432

このバグを踏んだ。
コンパイルは通るがランタイムでその周辺を実行したときにクラッシュする系。(さいわい、最適化により回避されるので、デバッグ端末(しかもarm64に限る)でしか発生しない。)

内容は追っていないが、仮説としてstructのサイズが大きくなったとき、というのがあり、実際にBox化などでstructのサイズを減らすことで回避できた。

structサイズがトリガーとなる仮説に基づき、あるアプリで使っているstructを大きい順に並べたい。(4Kを超えているものがあればアプリ実行してみて確認したい)

メモリレイアウトサイズの取り出しかた

dSYMに含まれているDWARFファイルを dwarfdump する。
structのメモリサイズ順に並べる全部入りのワンライナー:

f=path-to-.dSYM/Contents/Resources/DWARF/*; for a in $(dwarfdump -arch arm64 "$f" | grep 'TAG_structure_type' | cut -f1 -d:); do dwarfdump --debug-info=$a $f | grep -E '(AT_name|AT_byte_size)' | paste -d, -s - | awk '{print strtonum($5) "\t" $2}'; done | sort -g | uniq

出力例

:
721 "_TtRTC..."
721 "_TtTC..."
1185    "_TtRTC..."
1185    "_TtTC..."
2134    "..."
2134    "Optional"
2139    "Result"
2139    "_TtRGO..."
4537    "..."
4537    "_TtRV..."

最大で4537バイトのstructがあることがわかる。
(nominal以外の合成型も出現する)

解説

ただのgrep,awk芸だが‥

dwarfdump すると含まれている各 TAG_* が出力される。
struct がほしいので TAG_structure_type だけ取り出す (でいいのか?)。
TAGの行にアドレスがあるので、それを各々 dwarfdump に渡して、 AT_nameAT_byte_size を取り出して1行にして awk 整形、ソートする。

課題

dwarfdumpTAG_structure_type でフィルタしてその AT_nameAT_byte_size だけ取り出したい、みたいなオプションの書き方は分からなかった。

demangle

結果表示のなかでmanglingされている名前を戻したい場合は swift-demangle を使う。

xcrun swift-demangle ...

他の方法

MemoryLayout<T>.size をつかう

なんらかの方法で T を収集し、デバッガで実行すればよいが、import が必要だったり、遅かったり、ある数以上実行すると返ってこなくなったりで、使いづらかった。

コード内で print(MemoryLayout<T>.size) するには、可視性の問題があった。

アプリの実行ファイル・frameworkのバイナリから取り出す

structのメモリレイアウトサイズは、実行バイナリに入っているのだろうか・・・?

zozotech
70億人のファッションを技術の力で変えていく
https://tech.zozo.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away