यदि आप जानना चाहते हैं कि आप एक एसआईजी पंजीकृत कर सकते हैं एनएएल हैंडलर, की तरह कुछ:
void handler(int signum, siginfo_t *info, void *context)
{
struct sigaction action = {
.sa_handler = SIG_DFL,
.sa_sigaction = NULL,
.sa_mask = 0,
.sa_flags = 0,
.sa_restorer = NULL
};
fprintf(stderr, "Fault address: %p\n", info->si_addr);
switch (info->si_code) {
case SEGV_MAPERR:
fprintf(stderr, "Address not mapped.\n");
break;
case SEGV_ACCERR:
fprintf(stderr, "Access to this address is not allowed.\n");
break;
default:
fprintf(stderr, "Unknown reason.\n");
break;
}
/* unregister and let the default action occur */
sigaction(SIGSEGV, &action, NULL);
}
और फिर कहीं आप इसे रजिस्टर करने की आवश्यकता:
struct sigaction action = {
.sa_handler = NULL,
.sa_sigaction = handler,
.sa_mask = 0,
.sa_flags = SA_SIGINFO,
.sa_restorer = NULL
};
if (sigaction(SIGSEGV, &action, NULL) < 0) {
perror("sigaction");
}
मूल रूप से आप एक संकेत है कि आग जब SIGSEGV वितरित किया जाता है, और आप कुछ अतिरिक्त जानकारी प्राप्त कर रजिस्टर, उद्धृत करने के लिए आदमी पेज:
The following values can be placed in si_code for a SIGSEGV signal:
SEGV_MAPERR address not mapped to object
SEGV_ACCERR invalid permissions for mapped object
च दो बुनियादी कारणों की ये नक्शा या एक सीजी गलती प्राप्त करना - या तो आपके द्वारा उपयोग किया गया पृष्ठ बिल्कुल मैप नहीं किया गया था, या आपको उस पृष्ठ पर किए गए किसी भी ऑपरेशन को करने की अनुमति नहीं थी।
सिग्नल हैंडलर के बाद यह स्वयं अनियंत्रित करता है और डिफ़ॉल्ट कार्रवाई को प्रतिस्थापित करता है। यह ऑपरेशन का कारण बनता है जो फिर से निष्पादित करने में असफल रहा, इसलिए इसे सामान्य मार्ग से पकड़ा जा सकता है। यह पेज गलती का सामान्य व्यवहार है (एक सीजी गलती प्राप्त करने वाला अग्रदूत) ताकि मांग पेजिंग काम जैसी चीजें हों।
आप ['backtrace'] (http://linux.die.net/man/3/backtrace) फ़ंक्शन का उपयोग कर सकते हैं। लेकिन मैं वास्तव में आपको अपने प्रोग्राम को डीबगर में चलाने की सलाह देता हूं, यह आपको केवल बैकट्रैक न देखने की अनुमति देगा, लेकिन कॉल-स्टैक पर चलने और चर की जांच करने की अनुमति देगा। –
"कोर डंप फ़ाइलों के बारे में पढ़ें" - मैं दृढ़ता से उन्हें अनुशंसा करता हूं। वे स्मृति में सब कुछ डंप करते हैं और फिर आप उन्हें 'gdb' और सही निष्पादन योग्य के साथ खोल सकते हैं। इससे आपको यह देखने का मौका मिलेगा कि वास्तव में क्या हुआ (जब तक कि स्मृति गड़बड़ न हो जाए, लेकिन यह बहुत दुर्लभ मामला है) - किसी भी चर के मूल्य, बैकट्रैक, थ्रेड इत्यादि देखें (बेशक, यह अधिकतम डीबग होना अच्छा होगा स्तर और इस प्रकार की जांच के लिए कोई अनुकूलन नहीं) –
हम्म .. '* पीआरटी' का प्रकार' char' है, लेकिन "हैलो" का प्रकार 'char *' है। आपको शायद एक वर्ण ('* ptr = 'h';') असाइन करना चाहिए या सही होने के लिए उदाहरण के लिए 'memmove() 'या समान का उपयोग करना चाहिए।जैसा कि है, यह स्ट्रिंग स्थिरांक का पता लेता है, इसे पूर्णांक में रखता है, इसे 1 बाइट तक दबा देता है, और फिर इसे * * ptr' – SingleNegationElimination