スタックトレース出力をstderrに取得したり、ログファイルにダンプしたりする際に問題が発生します。Kubuntu10.04でgccコンパイラ(4.4.3)を使用してコードを実行しています。問題は、通常の実行モード(gdbなし)では、プログラムが「セグメンテーション違反」以外は何も出力しないことです。以下のprintステートメントのようにバックトレース出力を出力したいと思います。アプリケーションでgdbを実行すると、printf / fprintf /(関数呼び出し)ステートメントが表示され、次のステートメントでクラッシュします。
669 {
(gdb)
670 printf("Testing for stability.\n");
(gdb)
Program received signal SIGTRAP, Trace/breakpoint trap.
0x00007ffff68b1f45 in puts () from /lib/libc.so.6
奇妙なことに、同じファイル内でクラッシュする関数を呼び出すと機能し、正常に機能し、出力を適切に出力します。ただし、このファイルの外部の関数でプログラムがクラッシュした場合、出力は出力されません。したがって、printfまたはファイルダンプステートメントまたは関数呼び出しは処理されません。次のサンプルコードを使用しています。
void bt_sighandler(int sig, siginfo_t *info,
void *secret) {
void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;
ucontext_t *uc = (ucontext_t *)secret;
/* Do something useful with siginfo_t */
if (sig == SIGSEGV)
printf("Got signal %d, faulty address is %p, "
"from %p\n", sig, info->si_addr,
uc->uc_mcontext.gregs[0]);
else
printf("Got signal %d#92; \n", sig);
trace_size = backtrace(trace, 16);
/* overwrite sigaction with caller's address */
trace[1] = (void *) uc->uc_mcontext.gregs[0];
messages = backtrace_symbols(trace, trace_size);
/* skip first stack frame (points here) */
printf("[bt] Execution path:#92; \n");
for (i=1; i<trace_size; ++i)
printf("[bt] %s#92; \n", messages[i]);
exit(0);
}
int main() {
/* Install our signal handler */
struct sigaction sa;
sa.sa_sigaction = (void *)bt_sighandler;
sigemptyset (&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
/* Do something */
printf("%d#92; \n", func_b());
}
助けてくれてありがとう。