void dump_stack(FILE *log)
{
void *bufs[100];
int n = backtrace(bufs, 100);
char **infos = backtrace_symbols(bufs, n);
if (!infos)
{
exit(1);
}
fprintf(log, "==================\n");
fprintf(log, "Frame info:\n");
char cmd[512];
char tmp[512];
sprintf(tmp, "addr2line -ifC -e %s", appName);
int len = snprintf(cmd, sizeof(cmd),
tmp);
char *p = cmd + len;
size_t s = sizeof(cmd) - len;
for (int i = 0; i < n; ++i)
{
fprintf(log, "%s\n", infos[i]);
if (s > 0)
{
len = snprintf(p, s, " %p", bufs[i]);
p += len;
s -= len;
}
}
fprintf(log, "src info:\n");
FILE *fp;
char buf[128];
if ((fp = popen(cmd, "r")))
{
while (fgets(buf, sizeof(buf), fp))
{
fprintf(log, "%s", buf);
}
pclose(fp);
}
fprintf(log, "==================\n");
free(infos);
// same as:
//backtrace_symbols_fd(bufs, n, STDOUT_FILENO);
}
void segv_handle(int s)
{
system("rm /opt/yl/wf.cfg");
dump_stack(stdout);
exit(127 + s);
}
main.cpp
signal(SIGSEGV, segv_handle);
这段代码是用于处理程序中的段错误(Segmentation Fault)的。当程序发生段错误时,它会执行segv_handle
函数。
-
dump_stack函数:
- 该函数首先使用
backtrace
函数来获取当前线程的堆栈信息,并将其存储在bufs
数组中。 - 接下来,它使用
backtrace_symbols
函数将这些地址转化为更有意义的函数名、文件名和行号信息,并将这些信息存储在infos
数组中。 - 如果无法获取堆栈信息,程序将退出。
- 然后,它将这些堆栈信息写入到指定的日志文件(通过
FILE *log
参数传递)。 - 之后,它使用
addr2line
工具(通过系统调用来执行)来获取源代码位置信息,并将这些信息也写入到日志中。 - 最后,它释放了
infos
数组。
- 该函数首先使用
-
segv_handle函数:
- 当程序发生段错误时,会调用此函数。
- 首先,它会删除一个名为
/opt/ylswt/swt.cfg
的文件。 - 然后,它调用
dump_stack
函数来记录当前的堆栈信息到标准输出(通常是终端或控制台)。 - 最后,它以特定的退出码退出程序。这个退出码是127加上段错误的信号码。
总体来说,这段代码的目的是在发生段错误时,提供详细的堆栈信息和源代码位置信息,以便于调试和解决问题。