http://shinh.skr.jp/d/backtrace.zip
Win32 上での D でハンドルされてない例外で main を脱出する際に、例外が起きた時のバックトレースを表示するものです。
行情報とファイル情報の取得では id:h_sakurai さんの仕事を激しく流用させてもらっています。
中に入っている phobos.lib を作業ディレクトリに放り込むなどして、そちらをリンクして下さい。 -g オプションをつけ、 -O オプションをつけないこと方が良いと思います。リリース時にはこの phobos.lib はどけると良いと思います。
やってることは、
- dmain2.d の main から try - catch を排除、 Win32 構造化例外が catch されないようにしておく。 backtrace_handler を登録する。
- deh.c の d_throw@4 の開幕で D 例外用の backtrace を秘かに作る。
- backtrace_handler では、 D 例外なら d_throw@4 を用いたものを使い、 Win32 構造化例外ならコンテキストを見て backtrace を作る。
- 適当にファイル情報やら行情報やらシンボル情報を表示。
あと、
- backtrace 取得は ebp をたぐってるだけなので激しく環境依存。
- throw hoge とかした時の行情報は下に一個ズレる気がする。
- スタックトレース表示はたぶん遅い。
- reflection.c は Win32 用のヤツ。 DLL のシンボル情報はたぐってないけど (WINEで確認しにくいから) 無くてもいいか…?
- dbginfo.d は h_sakurai さんのを適当にヒッコぬいたからよくわかってないという。
- デマングラは std.demangle 使ってるので dfilt 不要。
- インターフェイスとか超適当なので(標準出力決め打ちで出力とか) なんか意見あれば下さい。
こういう phobos をイジるアプローチにしたのは、まぁわりと色々考えた結果。
- invariant での横取りは非 throw 時にコストがかかるから避けたい。
- となると d_throw なり Win32 構造化例外を扱わなきゃいけない。
- phobos.lib を静的に改造するか、動的に自己書きかえでフックをかけるか。
- 前者の方がまだマシだろう…
で、 OMF 書き換えかぁ…と思ってなにかとハマりがちな OMF をある程度把握するために omfutils を書いたのですが、結局閲覧部分だけ作って書き換え部分はかなり大変そうだったので諦め、 phobos.lib を展開して挿し替えたいファイルだけ挿し替えるというアプローチに。