在C程序中调用调试器

问题描述:

我正在阅读David Hanson的书 - “C接口和实现”。这次演习的问题似乎是有趣的,但无法找到一个解决方案:在C程序中调用调试器

在某些系统中,一个程序可以在自身调用调试器时,它已经 检测到错误。在断言失败可能很常见的情况下,此工具在开发 期间特别有用。

您可以提供一个关于如何调用调试器的简短示例。

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; 
} 
+0

不管你做什么,都要确保在信号处理程序中只使用[异步信号安全功能](http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html)。例如,在所有'exec'变体中,只有'execve'和'execle'在(异步信号捕获)信号处理器的上下文中可以安全执行。现在,做这件事通常是明智的(面对像SIGSEGV那样的“腐败信号​​”)是另一回事。我会选择(a)外部调试器或(b)检查coredump验尸。 – 2012-07-16 07:12:59

在阐述Christian.K的评论,fork()荷兰国际集团在像一个SIGFPE或SIGSEGV可能不是最好的想法,面对一个调试器,因为。 ..

  1. 你的程序是潜在的腐败开始说起,使得fork()不安全;
  2. 您可能想要使用与程序硬编码不同的东西来进行调试;
  3. 平均应用程序用户不知道如何处理调试器;
  4. 主管与调试器通常会喜欢信息转储在自动调用调试器。

我可以复制到测试平台的一个coredump在一天中的任何时间在我的客户工作场所打败一个调试器实例。调试器接口会导致糟糕的最终用户错误消息。

+0

我认为使用调试器附加只是出于调试的原因是个好主意。 – 2012-07-16 08:14:56

我有这样的:

#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; 
} 
+0

感谢您的帮助。 – user138645 2012-07-16 13:10:15