2012-06-22 :-(
_ [backtrace][c][バックトレース][execinfo]普通のやつらの下を行け: C でバックトレース表示 - bkブログ
#include <stdlib.h> #include <execinfo.h> #include <signal.h> void stacktrace(int signal) { void *trace[128]; int n = backtrace(trace, sizeof(trace) / sizeof(trace[0])); backtrace_symbols_fd(trace, n, 1); } int foo() { return 1 /0; } void bar() { foo(); } int main() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = stacktrace; sa.sa_flags = SA_ONESHOT; sigaction(SIGFPE, &sa, NULL); bar(); return 0; }
ビルド
% gcc execinfo.c execinfo.c: In function 'foo': execinfo.c:12: warning: division by zero execinfo.c: In function 'main': execinfo.c:21: warning: incompatible implicit declaration of built-in function 'memset' execinfo.c:23: error: 'SA_ONESHOT' undeclared (first use in this function) execinfo.c:23: error: (Each undeclared identifier is reported only once execinfo.c:23: error: for each function it appears in.)
('A`)
SA_RESETHAND
シグナルハンドラが呼ばれる度に、シグナルの動作をデフォルトに戻す。 このフラグはシグナルハンドラを設定する際にのみ意味を持つ。 SA_ONESHOT はこのフラグと同じ意味だが、廃止されており、非標準である。
修正
#include <stdlib.h> #include <execinfo.h> #include <signal.h> void stacktrace(int signal) { void *trace[128]; int n = backtrace(trace, sizeof(trace) / sizeof(trace[0])); backtrace_symbols_fd(trace, n, 1); } int foo() { return 1 /0; } void bar() { foo(); } int main() { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = stacktrace; sa.sa_flags = SA_RESETHAND; ←←←← sigaction(SIGFPE, &sa, NULL); bar(); return 0; }
ビルド。-L 要るんだっけ
% gcc -L/usr/pkg/lib -lexecinfo -I/usr/pkg/include execinfo.c
共有ライブラリのための環境変数
% export LD_LIBRARY_PATH=/usr/pkg/lib
実行
% ./a.out 0xbbb5eab0 <__sigtramp_siginfo_2+0> at /usr/lib/libc.so.12 0x80487d0 <_init+832> at ./a.out 0x804881b <_init+907> at ./a.out 0x80485e4 <_init+340> at ./a.out zsh: floating point exception (core dumped) LD_LIBRARY_PATH=/usr/pkg/lib ./a.out
-rdynamic をつけるとシンボルを表示するらしい。
% gcc -rdynamic -L/usr/pkg/lib -lexecinfo -I/usr/pkg/include execinfo.c
% ./a.out 0xbbb5eab0 <__sigtramp_siginfo_2+0> at /usr/lib/libc.so.12 0x80488a0 <bar+8> at ./a.out 0x80488eb <main+73> at ./a.out 0x80486b4 <___start+156> at ./a.out zsh: floating point exception (core dumped) LD_LIBRARY_PATH=/usr/pkg/lib ./a.out
execinfo.h 使えてるよなあ