Jun 14

ふと思い立ち、gccの秘密(?)関数_Unwind_Backtrace()を使って実行途中プロセスのbacktraceを取ってみようとしたら、驚くほど動かず、延々と調査するはめに。結局わかったことは以下:

  • C++のコードの中から使った場合は(試した範囲内では)いつでも動く
  • Cのコードから使った場合、x86_64(amd64)やIA64では動くが、x86(32ビット)とかsparcでは動かない。また、これらはOSにも依存しない
  • Cの場合で、x86_64とx86の違いは、ELFの.eh_frame section内に実行コードのframeに関するcall frame information(CFI)が含まれているかどうか。含まれていれば動くが、そうでなければ動かない。
  • x86におけるC++とCの差もELFの.eh_frame sectionの中身の違い
  • .eh_frame sectionに必要な情報がなくても、.debug_frame sectionに実行コードのCFIが含まれていれば、それをちょっといじって__register_frame()(さらに秘密な関数?)で登録すれば動くようになる
  • IA64の場合は上記とは別な扱いになっている模様。CでもC++でも、そもそも.eh_frame sectionが存在しないが_Unwind_Backtrace()はちゃんと動く

Cで動かすためのテストコードも公開しているので、万一このページを読んだ方がいらっしゃいましたら、(とくにi386やsparc以外で)動いたとか動かなかったとかご報告いただければ幸いです。

以下はとっても長い詳細。
More… »