从C程序中调用调试器

时间:2012-07-16 07:05:45

标签: c linux gdb systems-programming

我正在读大卫汉森的书“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;
}

2 个答案:

答案 0 :(得分:4)

阐述Christian.K的评论,{{1}面对像SIGFPE或SIGSEGV这样的调试器可能不是最好的想法,因为......

  1. 您的程序可能已开始腐败,使fork()不安全;
  2. 您可能希望使用与程序硬编码不同的调试内容;
  3. 普通应用程序用户不知道如何处理调试器;
  4. 使用调试器的任何主管通常更喜欢 coredump而不是自动调用的调试器。
  5. 我可以复制到测试平台的coredump在一天中的任何时间在我的客户工作场所击败调试器实例。调试器接口会产生糟糕的最终用户错误消息。

答案 1 :(得分:3)

我有这个:

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