除了错误代码、错误字符串和日志之外,是否还有其他功能可以合并到代码中,以增加在代码运行时获取调试/跟踪信息,从而帮助在运行时调试问题(或让我们知道发生了什么)?
问问题
729 次
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 回答