除了错误代码、错误字符串和日志之外,是否还有其他功能可以合并到代码中,以增加在代码运行时获取调试/跟踪信息,从而帮助在运行时调试问题(或让我们知道发生了什么)?
3 回答
2
- 无需优化即可构建,以尽可能多地保留代码的“意图”
- 以调试模式构建,添加符号信息
- 不要剥离可执行文件(在 Linux/Unix 系统上),以保留尽可能多的符号信息以供调试器使用
于 2010-02-01T15:12:20.327 回答
2
这是在分段错误时将堆栈跟踪发送到文件的代码示例
#include <stdio.h>
#include <信号.h>
#include <stdlib.h>
#include <stdarg.h>
静态无效信号处理程序(int);
静态无效转储堆栈(无效);
静态无效清理(无效);
无效初始化信号(无效);
无效恐慌(const char *,...);
结构 sigaction sigact;
字符 *progname;
int main(int argc, char **argv){
字符 *s;
程序名 = *(argv);
退出(清理);
初始化信号();
printf("即将通过将零分配给 *s\n 来分段故障");
*s = 0;
sigemptyset(&sigact.sa_mask);
返回0;
}
无效初始化信号(无效){
sigact.sa_handler = 信号处理程序;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(SIGINT, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGSEGV);
sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGBUS);
sigaction(SIGBUS, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGQUIT);
sigaction(SIGQUIT, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGHUP);
sigaction(SIGHUP, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGKILL);
sigaction(SIGKILL, &sigact, (struct sigaction *)NULL);
}
静态无效信号处理程序(int sig){
if (sig == SIGHUP) panic("致命:程序挂起\n");
如果(信号 == SIGSEGV || 信号 == SIGBUS){
转储堆栈();
panic("FATAL: %s Fault. Logged StackTrace\n", (sig == SIGSEGV) ? "Segmentation" : ((sig == SIGBUS) ? "Bus" : "Unknown"));
}
if (sig == SIGQUIT) panic("QUIT 信号结束程序\n");
if (sig == SIGKILL) panic("KILL 信号结束程序\n");
if (sig == SIGINT) ;
}
无效恐慌(const char *fmt,...){
字符缓冲区[50];
va_list argptr;
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
va_end(argptr);
fprintf(stderr, buf);
退出(-1);
}
静态无效转储堆栈(无效){
/* 从 http://www.whitefang.com/unix/faq_toc.html 得到这个例程
** 第 6.5 节。修改为重定向到文件以防止混乱
*/
字符 dbx[160];
sprintf(dbx, "echo 'where\ndetach' | dbx -a %d > %s.dump", getpid(), progname);
系统(dbx);
返回;
}
无效清理(无效){
sigemptyset(&sigact.sa_mask);
/* 在这里做任何清理工作 */
}
在函数dumpstack中,dbx需要更改以适合您的调试器,例如gdb对于 GNU 调试器,此代码是我几年前在 AIX 机器上编程时使用的。注意信号是如何设置的,如果发生 SIGSEGV 故障,处理程序会将堆栈转储到扩展名为.dump. 该代码演示了分段错误并转储堆栈跟踪。
这是我最喜欢的代码。
希望这会有所帮助,最好的问候,汤姆。
于 2010-02-01T15:26:29.300 回答