从C程序中调用调试器
我正在读David Hanson写的《C接口和实现》一书。此练习问题似乎很有趣,我无法找到解决方案: 在某些系统上,程序可以在运行时调用自身的调试器 检测到一个错误。这项设施在工作期间特别有用 开发时,断言失败可能很常见 您能否提供一个关于如何调用调试器的简短示例从C程序中调用调试器,c,linux,gdb,systems-programming,C,Linux,Gdb,Systems Programming,我正在读David Hanson写的《C接口和实现》一书。此练习问题似乎很有趣,我无法找到解决方案: 在某些系统上,程序可以在运行时调用自身的调试器 检测到一个错误。这项设施在工作期间特别有用 开发时,断言失败可能很常见 您能否提供一个关于如何调用调试器的简短示例 void handle_seg_fault(int arg) { /* how to invoke debugger from within here */ } int main() { int *ptr = NUL
void handle_seg_fault(int arg)
{
/* how to invoke debugger from within here */
}
int main()
{
int *ptr = NULL;
signal(SIGSEGV, handle_seg_fault);
/* generate segmentation fault */
*ptr = 1;
}
我得到了这个:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
void exception_handler(int)
{
int pid = getpid();
if (fork() != 0) {
while(true) sleep(1000);
}
char buf[20];
sprintf(buf, "--pid=%u", pid);
execlp("gdb", "gdb", buf, NULL);
exit(-1);
}
int init()
{
if (signal(SIGSEGV, exception_handler) < 0) {
return errno;
}
if (signal(SIGILL, exception_handler) < 0) {
return errno;
}
if (signal(SIGFPE, exception_handler) < 0) {
return errno;
}
return 0;
}
int main()
{
if (int rc = init()) {
fprintf(stderr, "init error: %s\n", strerror(rc));
return 1;
}
*((char*)(0)) = 1;
}
#包括
#包括
#包括
#包括
#包括
#包括
无效异常处理程序(int)
{
int pid=getpid();
如果(fork()!=0){
而(真实)睡眠(1000);
}
char-buf[20];
sprintf(buf,“--pid=%u”,pid);
execlp(“gdb”、“gdb”、buf、NULL);
出口(-1);
}
int init()
{
if(信号(SIGSEGV,异常处理程序)<0){
返回errno;
}
if(信号(信号,异常处理程序)<0){
返回errno;
}
if(信号(SIGFPE,异常处理程序)<0){
返回errno;
}
返回0;
}
int main()
{
if(int rc=init()){
fprintf(stderr,“初始错误:%s\n”,strerror(rc));
返回1;
}
*((字符*)(0))=1;
}
详细阐述Christian.K的评论,fork()
面对SIGFPE或SIGSEGV这样的东西使用调试器可能不是最好的主意,因为
fork()
不安全李>
我可以复制到测试床上的coredump在一天中的任何时候都胜过客户工作场所的调试器实例。调试器界面会产生糟糕的最终用户错误消息。无论您做什么,请确保仅从信号处理程序中使用。例如,在所有
exec
变体中,只有execve
和execle
可以在(异步信号捕获)信号处理程序的上下文中安全执行。现在,不管这样做是否明智(面对像SIGSEGV这样的“国家腐败信号”),这是另一回事。我会使用(a)一个外部调试器,或者(b)事后检查coredump。我认为使用调试器attach只用于调试是个好主意。