5

我正在阅读 David Hanson 的《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;
}
4

2 回答 2

4

详细阐述 Christian.K 的评论,fork()在面对 SIGFPE 或 SIGSEGV 之类的东西时使用调试器可能不是最好的想法,因为......

  1. 您的程序一开始就可能已损坏,从而导致fork()不安全;
  2. 您可能希望使用与程序硬编码不同的东西进行调试;
  3. 一般的应用程序用户不知道如何处理调试器;
  4. 任何能胜任调试器的人通常会更喜欢coredump 而不是自动调用的调试器。

我可以复制到测试平台的核心转储在一天中的任何时间都在我客户的工作场所击败调试器实例。调试器界面会导致糟糕的最终用户错误消息。

于 2012-07-16T08:12:26.017 回答
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;
}
于 2012-07-16T07:54:26.963 回答