2012-07-16 87 views
5

我正在閱讀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

回答

4

在闡述Christian.K的評論,fork()荷蘭國際集團在像一個SIGFPE或SIGSEGV可能不是最好的想法,面對一個調試器,因爲。 ..

  1. 你的程序是潛在的腐敗開始說起,使得fork()不安全;
  2. 您可能想要使用與程序硬編碼不同的東西來進行調試;
  3. 平均應用程序用戶不知道如何處理調試器;
  4. 主管與調試器通常會喜歡信息轉儲在自動調用調試器。

我可以複製到測試平臺的一個coredump在一天中的任何時間在我的客戶工作場所打敗一個調試器實例。調試器接口會導致糟糕的最終用戶錯誤消息。

+0

我認爲使用調試器附加只是出於調試的原因是個好主意。 – 2012-07-16 08:14:56

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

感謝您的幫助。 – user138645 2012-07-16 13:10:15