2012-07-16 25 views
5

के भीतर से डीबगर को आमंत्रित करना मैं डेविड हैंनसन द्वारा "सी इंटरफेस एंड इम्प्लिमेंटेशंस" पुस्तक पढ़ रहा हूं। इस अभ्यास सवाल दिलचस्प लगता है और एक समाधान खोजने के लिए असमर्थ हूँ:एक सी प्रोग्राम

कुछ सिस्टम पर, एक कार्यक्रम में जब यह एक त्रुटि का पता लगाया है खुद पर एक डिबगर आह्वान कर सकते हैं। यह सुविधा विकास के दौरान विशेष रूप से उपयोगी होती है, जब दावा विफलता सामान्य हो सकती है।

क्या आप डीबगर का आह्वान करने के तरीके पर एक छोटा सा उदाहरण प्रदान कर सकते हैं।

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

जो कुछ भी आप करते हैं, सुनिश्चित करें कि आप केवल अपने सिग्नल हैंडलर के भीतर से [async सिग्नल सुरक्षित फ़ंक्शंस] (http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html) का उपयोग करें। उदाहरण के लिए, सभी 'exec' प्रकारों में से केवल' execve' और 'execle' सिग्नल हैंडलर (एसिंक सिग्नल कैचिंग) के संदर्भ में निष्पादित करने के लिए सुरक्षित हैं। अब, गीलेर आमतौर पर ऐसा करने के लिए बुद्धिमान है (एसआईजीएसईजीवी जैसे "राज्य भ्रष्ट एकल" के रूप में) एक और बात है। मैं (ए) एक बाहरी डीबगर के साथ जाऊंगा या (बी) coredump पोस्ट मॉर्टम का निरीक्षण करें। –

उत्तर

4

Christian.K की टिप्पणी पर विस्तार से चर्चा करते fork() एक SIGFPE या SIGSEGV विचारों का सबसे अच्छा नहीं हो सकता है की तरह कुछ के चेहरे में एक डिबगर ing, क्योंकि। ..

  1. अपने कार्यक्रम के साथ शुरू हो, fork() असुरक्षित बना संभवतः भ्रष्ट है,
  2. आप प्रोग्राम को हार्डकोड किए गए डीबगिंग के लिए कुछ अलग उपयोग करना चाहेंगे;
  3. औसत एप्लिकेशन उपयोगकर्ता को डीबगर को संभालने का तरीका नहीं पता है;
  4. किसी सक्षम एक डिबगर के साथ आमतौर पर ऑटो लागू डिबगर से अधिक coredump का चुनाव करेगा।

एक कॉर्डम्प जिसे मैं टेस्टबेड में प्रतिलिपि बना सकता हूं, दिन के किसी भी समय मेरे ग्राहक के कार्यस्थल पर एक डीबगर उदाहरण देता है। एक डीबगर इंटरफेस एक लुभावनी अंत उपयोगकर्ता त्रुटि संदेश के लिए बनाता है।

+0

मुझे लगता है कि डीबगिंग कारणों के लिए केवल डीबगर संलग्नक का उपयोग करना अच्छा विचार है। –

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

संबंधित मुद्दे