我有一个Linux程序,该程序不时以分段故障结束。该程序每小时定期运行,但是分段故障有时仅发生。
我有一个问题要调试此问题,因为如果我再次使用相同的输入运行程序,则不会报告错误,一切都可以。
有没有办法,如何"报告"代码错误的哪一部分或引起问题的原因?
通常的方法是让崩溃程序生成核心文件并在崩溃后分析。确保:
- 最大的核心尺寸大小足够大(即 unlimited ),通过在shell中调用
ulimit -c unlimited
,这开始了该过程。 - CWD由segfaulting Process进行了写作。
然后您可以用
分析文件 gdb <exe> <corefile>
由于您的代码没有每次崩溃,因此您也可以使用backtrace
。使用此情况,您可以在崩溃时看到function call stack
。有很多示例可用。在我的项目中,我通常使用以下代码进行回溯。
/*
* call reg_usr2 function from main
* gcc -rdynamic myfile.c -o output
*/
#include <stdio.h>
#include <stdarg.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <execinfo.h>
#define FILE_NAME "/tmp/debug"
#define MODE 0xFFFF
void dbgprint(int flag, char* fmt, ...)
{
if(flag & MODE) {
char buf[100];
va_list vlist;
FILE *fp = fopen(FILE_NAME,"a");
va_start(vlist, fmt);
vsnprintf( buf, sizeof( buf), fmt, vlist);
va_end( vlist);
fprintf(fp,"[%x]->%sn", flag, buf);
fclose(fp);
}
}
/** Here is the code to print backtrace **/
void print_stack_trace ()
{
void *array[20];
size_t size;
char **strings;
size_t i;
size = backtrace (array, 20);
strings = backtrace_symbols (array, size);
dbgprint(0xFFFF, "Obtained %zd stack frames.", size);
dbgprint(0xFFFF, "-------------------------");
dbgprint(0xFFFF, "---------Backtrace-------");
for (i = 0; i < size; i++)
dbgprint (0xFFFF, "%s", strings[i]);
dbgprint(0xFFFF, "-------------------------");
free (strings);
}
void sig_handler(int signo)
{
FILE *fp = fopen(FILE_NAME,"a");
if (signo == SIGUSR2){
dbgprint(0xFFFF, "received SIGUSR2");
dbgprint(0xFFFF, "----------------");
}
print_stack_trace();
exit(0);
}
void reg_usr2()
{
if (signal(SIGUSR2, sig_handler) == SIG_ERR)
printf("ncan't catch SIGUSR2n");
}
int main()
{
reg_usr2(); //should be first line of main after variables
//Code.....
return 0;
}
您可以通过捕获Sigsegv信号来生成回溯,并查看应用程序在何处投掷无效的访问权限。请参阅https://stackoverflow.com/a/77336/4490542
但是有更容易的解决方案,请尝试使用CatchSegv
运行您的应用程序catchsegv'./program args'
和更好的替代方案,valgrind
valgrind -tool = none./program args