问题描述
|
解决方法
汤米(Tommie)因解决这个问题而值得赞扬。
通过使用来自
<execinfo.h>
的某种标准standard0ѭ实用程序,我从GDB分离了他的答案。
static void dumpstack(void){
static void *backbuf[ 50 ];
int levels;
levels = backtrace( backbuf,50 );
backtrace_symbols_fd( backbuf,levels,STDERR_FILENO );
return;
}
您可以尝试打开文件并写入而不是STDERR_FILENO
,但是在崩溃的过程中,我会避免如此繁重的操作。
在我的系统上,输出如下所示:
Shadow:code dkrauss$ ./dumpy
0 dumpy 0x0000000100000d81 dumpstack + 25
1 dumpy 0x0000000100000d18 signal_handler + 47
2 libSystem.B.dylib 0x00007fff86b1766a _sigtramp + 26
3 ??? 0x0000000000000000 0x0 + 0
4 dumpy 0x0000000100000a18 start + 52
FATAL: Segmentation Fault
因此,它不提供文件名+行号,但提供函数名+代码偏移量,您可以轻松地对其进行翻译。
,嗯...您可以尝试通过这种方式...
struct sigaction g_sigact;
void panic(const char *fmt,...){
char buf[PANICBUF_LEN];
va_list argptr;
va_start(argptr,fmt);
vsprintf(buf,fmt,argptr);
va_end(argptr);
fprintf(stderr,\"%s\\n\",buf);
exit(-1);
}
void init_signals(void){
g_sigact.sa_handler = signal_handler;
sigemptyset(&g_sigact.sa_mask);
g_sigact.sa_flags = 0;
sigaction(SIGINT,&g_sigact,(struct sigaction *)NULL);
sigaddset(&g_sigact.sa_mask,SIGSEGV);
sigaction(SIGSEGV,SIGBUS);
sigaction(SIGBUS,SIGQUIT);
sigaction(SIGQUIT,SIGHUP);
sigaction(SIGHUP,SIGKILL);
sigaction(SIGKILL,(struct sigaction *)NULL);
}
static void signal_handler(int sig){
if (sig == SIGHUP) g_keepRunning = 0;
if (sig == SIGSEGV || sig == SIGBUS){
dumpstack();
panic(\"FATAL: %s Fault\\n\",(sig == SIGSEGV) ? \"Segmentation\" : ((sig == SIGBUS) ? \"Bus\" : \"Unknown\"));
}
if ((sig == SIGQUIT || (sig == SIGKILL) || (sig == SIGINT)) ;
}
static void dumpstack(void){
/* Got this routine from http://www.whitefang.com/unix/faq_toc.html
** Section 6.5. Modified to redirect to file to prevent clutter
*/
char dbx[160];
sprintf(dbx,\"echo -ne \'detach\\n\' | gdb --eval-command=where --pid=%d > %d.dump\",getpid(),getpid());
system(dbx);
return;
}
当捕获到分段错误时,将调用dumpstack
并打印最新的堆栈跟踪信息,直到出现分段错误并重定向到具有过程的数字pid的文件为止。
,为什么您完全不想运行gdb?如果使用它,您可以很容易地检测到段错误的位置。