バックトレースの実装
Cのプログラムでバックトレースを表示したい場合,Linux(glibc)にはbacktrace(3),Solarisにはprintstack(3)なんてライブラリ関数が用意されているので,それらを使えばいい.なければsetjmp(3)やgetcontext(3)を使って,自力でスタックをたどることになる.と言ってもスタックフレームの構造がわかっていれば簡単で,見栄えを気にしなければ,こんな感じになる.
void mybacktrace() { jmp_buf env; void **fp, **ip; setjmp(env); fp = (void **)env[0].__jmpbuf[JB_BP]; while (fp != NULL) { ip = (void **)fp[1]; fp = (void **)fp[0]; printf("%p\n", ip); } }
後はdladdr(3)使って,関数名やオフセットを調べれば,十分使いものになる.
こんなのをPlan9で書いてみようかなと思ったんだけど,jmp_bufにはPCとSPしか保存されないのね...
(追記:2007-02-04) 最近のglibcは,PCやSPはエンコードされているのでこれじゃ動かないらしい.setjmp用の__jmpbuf の スタックポインタがエンコードされている件