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 使えてるよなあ
[ツッコミを入れる]



