प्रोग्राम को C / C ++ में कोर डंप कैसे करें


93

मैं अपने C ++ एप्लिकेशन में एक विशिष्ट स्थान पर एक कोर डंप को मजबूर करना चाहूंगा।

मुझे पता है कि मैं ऐसा कुछ करके कर सकता हूं:

int * crash = NULL;
*crash = 1;

लेकिन मैं जानना चाहूंगा कि क्या कोई क्लीनर तरीका है?

मैं जिस तरह से लिनक्स का उपयोग कर रहा हूं।


18
कोर डंप करने का एक "क्लीनर" तरीका? .... अच्छा एक;)
ओजे

5
यह प्यारा है। बेहतर अभी तक एक बूलियन का उपयोग करें (सी में enum?) ... अगर ( क्रैश = TRUE) {/ OH SHI ... * /}
एप-इनैगो

3
BTW, यह विधि सभी यूनिक्स में काम नहीं करती है। एचपीयूएक्स, एक के लिए, आपको नून को अशुद्धता के साथ पढ़ने और लिखने की अनुमति देता है (शुक्र है, यह विन्यास योग्य है)।
paxdiablo

1
मैंने सिर्फ 3 या 4 महान नई चीजों की तरह सीखा। धन्यवाद।
ट्रेवर बॉयड स्मिथ

@pax एक सामान्य तरीका खोजने के लिए एक कारण से अधिक thats;) धन्यवाद
hffez

जवाबों:


76

सिग्नल संख्या 6 ( SIGABRTलिनक्स में) का उठाना एक तरीका है, हालांकि यह ध्यान रखें कि SIGABRT को सभी POSIX कार्यान्वयन में 6 होने की आवश्यकता नहीं है, इसलिए आप SIGABRTमूल्य का उपयोग स्वयं करना चाह सकते हैं यदि यह क्विक। एन के अलावा कुछ भी हो 'गंदा डिबग कोड)।

#include <signal.h>
: : :
raise (SIGABRT);

कॉल करने abort()से एक कोर डंप भी होगा, और आप केवल बच्चे में उसके बाद कॉल करके अपनी प्रक्रिया को समाप्त किए बिना भी ऐसा कर सकते हैं - विवरण के लिए इस उत्तर को देखें।fork()abort()


7
SIGABRT को सिग्नल नंबर 6 होने की आवश्यकता नहीं है (हालांकि यह अक्सर होता है - और, विशेष रूप से, लिनक्स पर)।
जोनाथन लेफलर

4
नहीं, आप सही हैं, यह नहीं है, लेकिन मैं डिबग कोड की शुद्धता के बारे में बहुत अधिक चिंता नहीं करता हूं। अगर वह जंगल में भाग जाता है, तो मेरे कोड की सफाई मेरी चिंताओं से कम है :-)
paxdiablo

2
कुछ संकलक और कुछ C पुस्तकालयों (जैसे ARM पर gcc और glibc या uClibc) के साथ कुछ आर्किटेक्चर पर कॉलिंग एबोर्ट () बेकार हो सकता है क्योंकि abort () फ़ंक्शन को एक नोटरी विशेषता के साथ घोषित किया गया है और कंपाइलर पूरी तरह से सभी वापसी जानकारी का अनुकूलन करता है, जो कोर फ़ाइल को अनुपयोगी बनाता है। आप इसे () या गर्भपात () को कॉल करने के लिए अतीत में ट्रेस नहीं कर सकते। इसलिए उठाना (SIGABRT) को सीधे कॉल या मारना (गेटपिड (), SIGABRT), जो वास्तव में एक ही है, को कॉल करना बेहतर है।
अलेक्जेंडर अमेलकिन

3
क्षमा करें, ARM पर भी यही बात (SIGABRT) बढ़ाने के साथ होती है। तो एक ट्रेस करने योग्य कोर फ़ाइल का उत्पादन करने का एकमात्र तरीका किल (गेटपिड,),
एसआईजीएबीआरटी

ulimit -c unlimitedसुवेश प्रताप जवाब से संकेत , इस जवाब के लिए मेरी बहुत मदद की।
बोरिस डैपेन

74

कुछ साल पहले, Google ने coredumper Library को जारी किया था ।

अवलोकन

कोरडम्पर लाइब्रेरी को चल रहे प्रोग्राम के कोर डंप बनाने के लिए अनुप्रयोगों में संकलित किया जा सकता है - बिना समापन के। यह सिंगल और मल्टी-थ्रेडेड कोर डंप दोनों का समर्थन करता है, भले ही कर्नेल मूल रूप से मल्टी-थ्रेडेड कोर फ़ाइलों का समर्थन नहीं करता है।

बीएसडी लाइसेंस की शर्तों के तहत कोरिडम्पर वितरित किया जाता है।

उदाहरण

यह किसी भी तरह से एक पूर्ण उदाहरण नहीं है; यह बस आपको एक महसूस कराता है कि coredumper API कैसा दिखता है।

#include <google/coredumper.h>
...
WriteCoreDump('core.myprogram');
/* Keep going, we generated a core file,
 * but we didn't crash.
 */

यह आप के लिए पूछ रहे थे नहीं है, लेकिन शायद यह भी बेहतर है :)


3
जब मैं इस उत्तर पर दौड़ा तो मैं शुरू में बहुत उत्साहित था। लेकिन कोर डम्पर इन दिनों काफी पुराना और पुराना हो गया है। वहाँ भी संकेत है कि यह समकालीन लिनक्स कर्नेल पर अब और काम नहीं करता है: stackoverflow.com/questions/38314020/…
jefe2000

37

जैसा कि सिग्नल मैनपेज में सूचीबद्ध है , 'कोर' के रूप में सूचीबद्ध कार्रवाई के साथ कोई भी संकेत कोर डंप को मजबूर करेगा। कुछ उदाहरण निम्न हैं:

SIGQUIT       3       Core    Quit from keyboard
SIGILL        4       Core    Illegal Instruction
SIGABRT       6       Core    Abort signal from abort(3)
SIGFPE        8       Core    Floating point exception
SIGSEGV      11       Core    Invalid memory reference

सुनिश्चित करें कि आप कोर डंप सक्षम करें:

ulimit -c unlimited

धन्यवाद, कोर डंप सक्षम करने के बारे में आपकी टिप्पणी से ulimit -c unlimitedमदद मिली।

आप कोड के भीतर से किस प्रकार से ulimit सेट करेंगे? @ ks1322
करण जोशीर जूल

@KaranJoisher यह शायद खुद के लिए एक और सवाल के लायक है, लेकिन संक्षेप में आप के setrlimit(RLIMIT_CORE, &core_limits);माध्यम से उपलब्ध का उपयोग कर सकते हैं #include <sys/resource.h>। आप प्रकार की एक संरचना बनाते हैं rlimitऔर फिर rlim_curऔर rlim_maxसदस्यों को सेट करते हैं।
ब्रेंट राइट्स कोड


11

आह्वान

abort();

संबंधित, कभी-कभी आप वास्तविक कोर डंप के बिना एक बैक ट्रेस चाहते हैं, और प्रोग्राम को जारी रखने की अनुमति देते हैं: ग्लिब्क बैकट्रेस () और बैकट्रेस_सिमबोल () फ़ंक्शन: http://www.gnu.org/s/libc/ देखें मैनुअल / html_node / Backtraces.html


6

कोर डंप जनरेट करने का दूसरा तरीका:

$ bash
$ kill -s SIGSEGV $$

बस बैश का एक नया उदाहरण बनाएं और इसे निर्दिष्ट संकेत के साथ मार दें। $$खोल के पीआईडी है। अन्यथा आप अपने करंट बैश को मार रहे हैं और लॉग आउट, टर्मिनल बंद या डिस्कनेक्ट हो जाएगा।

$ bash 
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$

बहुत ही सरल और उपयोगी!
Firo

1
मुझे वह भी पसंद है। इसे सरल भी किया जा सकता है bash -c 'kill -SIGSEGV $$'
क्रिश्चियन क्रूस


2

कभी-कभी ऐसा कुछ करना उचित हो सकता है:

int st = 0;
pid_t p = fork();

if (!p) {
    signal(SIGABRT, SIG_DFL);
    abort(); // having the coredump of the exact copy of the calling thread
} else {
    waitpid(p, &st, 0); // rip the zombie
}

// here the original process continues to live

इस सरल दृष्टिकोण के साथ एक समस्या यह है कि केवल एक धागा coredumped होगा।


1
 #include <stdio.h>
 #include <stdlib.h>
 int main()
 {
   printf("\n");
   printf("Process is aborting\n");
   abort();
   printf("Control not reaching here\n");
   return 0;
 }

आप जहां चाहें इस दृष्टिकोण का उपयोग करें :)


0
#include <assert.h>
.
.
.
     assert(!"this should not happen");

संभवत: NDEBUG के साथ मेल करने की आवश्यकता है, इसलिए यह विशेष रूप से सक्रिय तब भी सक्रिय है, जब अन्य आरोही नहीं हैं।
Rhys Ulerich
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.