D言語 / スタックトレース


D言語でスタックトレースを取ろうというものです。

shinichiro.hさんが作ったreflection.dに dmd の -g オプションを付けてコンパイルした際にexeファイルに格納されるデバッグ情報を元に、シンボル名、アドレス、ライン情報を取得する機能を追加し、さらにスタック情報を元にスタックトレースを取れるようにしたものです。

デバッグ情報を元にシンボル名などを取得しているため、mapファイル読み込みよりも高速な起動が実現できます。

デバッグ情報を読み込むには、PEヘッダ、.debugディレクトリ、codeviewフォーマットの解析が必要です。

現在デバッガを作ってちゃんとした行データを取得できるようにしています。

問題点

  • Windowsのみ対応。
  • クラスのメソッド(static以外)しかスタックトレース出せません。
  • ライン情報は、メソッドのライン情報でしかありません。

クラスのメソッドが呼ばれたときのスタック情報を見て、スタックトレースを実現しているため、メソッドのライン情報しか取れていません。戻りのアドレスも取れるのですが、表示していません。

  • スタック情報の消し忘れ

クラスのメソッドが呼ばれたときのスタックのアドレスを見て、スタックトレース用のスタックの情報を消しています。そのため、ローカル変数の数によりスタックのアドレスが変ってしまうため、消すのに失敗することがあります。

コンパイル

dmd -g test.d reflection.d

実行結果

デバッグ情報を元にスタックトレース

コンパイル

gオプションをつけてコンパイルします。

dmd -g test.d reflection.d

実行

test

結果

error
  at test.C.go4(62)

error
  at test.C.go6(68)
  at test.C.go5(65)

error
  at test.C.go7(71)
  at test.C.go5(65)

error
  at test.C.go8(77)

error
  at test.C.go9(80)

g3
ArrayBoundsError test.d(60)
  at test.C.go3(56)
  at test.C.go2(53)
  at test.C.go(50)

map情報を元にスタックトレース

コンパイル

dmd -L/map test.d reflection.d

L/mapオプションをつけてコンパイルします。

実行

マップファイルを指定して実行します。若干起動に時間がかかりますが、linux等でも動きます。

test test.map

結果

error
  at test.C.go4

error
  at test.C.go6
  at test.C.go5

error
  at test.C.go7
  at test.C.go5

error
  at test.C.go8

error
  at test.C.go9

g3
ArrayBoundsError test.d
  at test.C.go3
  at test.C.go2
  at test.C.go

スタックトレースなし

コンパイル

dmd test.d reflection.d

オプションをつけずコンパイルします。

実行

test

結果

error

error

error

error

error

g3
ArrayBoundsError test.d

Download.

開発中

デバッガを作ってしまって、行番号とか完全に取ってしまおう作戦!!

  • filedebugger.zipver0.01 D言語で作ったデバッガと、スタックトレース。

参考URL

参考URL(デバッガ)

*MenuBar

人気の10件

  • counter: 9265
  • today: 1
  • yesterday: 0
  • online: 1