कैसे एक विभाजन दोष में लिनक्स में एक कोर डंप उत्पन्न करने के लिए?


217

मेरे पास लिनक्स में एक प्रक्रिया है जो एक विभाजन दोष प्राप्त कर रही है। जब यह विफल होता है तो मैं इसे एक कोर डंप उत्पन्न करने के लिए कैसे कह सकता हूं


1
इसे कैसे देखें: पिछाड़ी: stackoverflow.com/questions/8305866/…
Ciro Santilli 病 ft ft ft

जवाबों:


249

यह इस बात पर निर्भर करता है कि आप किस शेल का उपयोग कर रहे हैं। यदि आप बैश का उपयोग कर रहे हैं, तो ulimit कमांड प्रोग्राम निष्पादन से संबंधित कई सेटिंग्स को नियंत्रित करता है, जैसे कि आपको कोर डंप करना चाहिए। यदि आप टाइप करते हैं

ulimit -c unlimited

तब यह बताएगा कि इसके कार्यक्रम किसी भी आकार के कोर को डंप कर सकते हैं। यदि आप चाहते हैं तो आप असीमित के बजाय 52M जैसे आकार निर्दिष्ट कर सकते हैं, लेकिन व्यवहार में यह आवश्यक नहीं होना चाहिए क्योंकि कोर फ़ाइलों का आकार संभवतः आपके लिए कोई समस्या नहीं होगी।

Tcsh में, आप टाइप करेंगे

limit coredumpsize unlimited

21
@lzprgmr: स्पष्ट करने के लिए: डिफ़ॉल्ट रूप से कोर डंप उत्पन्न नहीं होने का कारण यह है कि सीमा निर्धारित नहीं है और / या 0 पर सेट है, जो कोर को डंप होने से बचाता है। असीमित की एक सीमा निर्धारित करके, हम गारंटी देते हैं कि कोर डंप हमेशा उत्पन्न हो सकते हैं।
एली कोर्टराइट

6
यह लिंक गहराई तक जाता है और लिनक्स में कोर डंप की पीढ़ी को सक्षम करने के लिए कुछ और विकल्प देता है। एकमात्र दोष यह है कि कुछ कमांड / सेटिंग्स अस्पष्टीकृत छोड़ दिए जाते हैं।
सालसा

6
बैश पर 4.1.2 (1) -Mrease सीमाएं जैसे कि 52M निर्दिष्ट नहीं किया जा सकता है, जिसके परिणामस्वरूप एक अमान्य संख्या त्रुटि संदेश है। मैन पेज बताता है कि "मान 1024-बाइट वेतन वृद्धि में हैं"।
1

4
वैसे मेरे पास एक "छोटा" ओपनजीएल प्रोजेक्ट था, जिसने एक बार कुछ अजीब काम किया, और एक्स-सर्वर क्रैश हो गया। जब मैंने वापस लॉग इन किया, तो मैंने एक प्यारा सा 17 जीबी कोर फ़ाइल (25 जीबी विभाजन पर) देखा। यह निश्चित रूप से कोर फ़ाइल का आकार सीमित रखने के लिए एक अच्छा विचार है :)
IceCool

1
@PolarisUser: यदि आप यह सुनिश्चित करना चाहते हैं कि आपका विभाजन खाया नहीं गया है, तो मैं 1 गिग की तरह कुछ सीमा निर्धारित करने की सलाह देता हूं। यह किसी भी उचित कोर डंप को संभालने के लिए पर्याप्त होना चाहिए, जबकि आपके सभी शेष हार्ड ड्राइव स्पेस का उपयोग करने की धमकी नहीं दे रहा है।
एली कोर्टराइट 16

60

जैसा कि यहां पूछे जा रहे असली सवाल के ऊपर बताया गया है कि कैसे एक सिस्टम पर कोर डंप को सक्षम करना है जहां वे सक्षम नहीं हैं। उस प्रश्न का उत्तर यहाँ दिया गया है।

यदि आप यहाँ आये हैं तो यह सीखने की उम्मीद है कि त्रिशंकु प्रक्रिया के लिए कोर डंप कैसे उत्पन्न होता है, इसका उत्तर है

gcore <pid>

अगर आपके सिस्टम पर gcore उपलब्ध नहीं है तो

kill -ABRT <pid>

किल-एसईजीवी का उपयोग न करें क्योंकि यह अक्सर सिग्नल हैंडलर का इस्तेमाल करेगा जिससे अटकी प्रक्रिया का निदान करना कठिन हो जाएगा


मुझे लगता है कि यह कहीं अधिक संभावना है कि -ABRTएक सिग्नल हैंडलर की तुलना में -SEGV, एक गर्भपात के रूप में पुनर्प्राप्ति की तुलना में पुनर्प्राप्त होने की अधिक संभावना है। (यदि आप एक सेगफॉल्ट को संभालते हैं, तो आमतौर पर यह आपके हैंडलर के बाहर निकलते ही फिर से ट्रिगर हो जाएगा।) कोर डंप जनरेट करने के लिए सिग्नल का एक बेहतर विकल्प है -QUIT
सितंबर

32

यह जाँचने के लिए कि कोर डंप कहाँ उत्पन्न होते हैं, चलाएँ:

sysctl kernel.core_pattern

या:

cat /proc/sys/kernel/core_pattern

%eप्रक्रिया का नाम और %tसिस्टम समय कहां है । आप इसे बदल सकते हैं /etc/sysctl.confऔर फिर से लोड कर सकते हैं sysctl -p

यदि कोर फाइलें उत्पन्न नहीं होती हैं (इसे इसके द्वारा परीक्षण करें: sleep 10 &और killall -SIGSEGV sleep), द्वारा सीमाओं की जाँच करें ulimit -a:।

यदि आपकी कोर फ़ाइल का आकार सीमित है, तो चलाएं:

ulimit -c unlimited

इसे असीमित बनाने के लिए।

फिर से परीक्षण करें, यदि कोर डंपिंग सफल है, तो आप नीचे दिए गए विभाजन दोष संकेत के बाद "(कोर डंप्ड)" देखेंगे:

विभाजन दोष: 11 (कोर डंप)

यह भी देखें: कोर डंप किया गया - लेकिन कोर फ़ाइल वर्तमान निर्देशिका में नहीं है?


उबंटू

उबंटू में कोर डंपों को Apport द्वारा नियंत्रित किया जाता है और इसमें स्थित किया जा सकता है /var/crash/। हालाँकि, यह स्थिर रिलीज़ में डिफ़ॉल्ट रूप से अक्षम है।

अधिक जानकारी के लिए, कृपया जांचें: मुझे उबंटू में कोर डंप कहां मिलेगा?

मैक ओ एस

मैकओएस के लिए, देखें: मैक ओएस एक्स में कोर डंप कैसे उत्पन्न करें?


3
उबंटू के लिए, सामान्य व्यवहार (वर्तमान निर्देशिका में एक कोर फ़ाइल को डंपिंग) के लिए जल्दी से वापस करने के लिए, बस "सुडो सर्विस एपॉर्ट स्टॉप" के साथ ऐपॉर्ट सेवा को रोक दें। यह भी ध्यान दें कि यदि आप docker के भीतर चल रहे हैं, तो वह सेटिंग होस्ट सिस्टम पर नियंत्रित है, कंटेनर के भीतर नहीं।
दिगिरात

26

अंत में मैंने क्या किया था कि यह क्रैश होने से पहले प्रक्रिया में gdb संलग्न था, और फिर जब इसे segfault मिला तो मैंने generate-core-fileकमांड निष्पादित किया । कि एक कोर डंप की पीढ़ी मजबूर।


आपने प्रक्रिया में gdb कैसे संलग्न किया?
चनी

6
Ritwik G का उत्तर देने के लिए, gdb के लिए एक प्रक्रिया संलग्न करने के लिए, बस gdb लॉन्च करें और 'संलग्न करें <pid>' जहाँ <pid> उस प्रक्रिया की pid संख्या है जिसे आप संलग्न करना चाहते हैं।
जीन-डोमिनिक फ्रैटिनी

(संक्षिप्त रूप में ge)
user202729

यदि उनके पास कोई नया प्रश्न है, तो उन्हें टिप्पणी में पूछने के बजाय एक नया प्रश्न पूछना चाहिए ।
user202729

अजीब बात यह है कि मैं पहले से ही सेट किया गया है ulimit -cकरने के लिए unlimitedहै, लेकिन मूल फ़ाइल नहीं बनाई शांत है, generate-core-filegdb सत्र में फ़ाइल मूल फ़ाइल, धन्यवाद पैदा करता है।
CodyChan

19

हो सकता है कि आप इसे इस तरह से कर सकते हैं, यह प्रोग्राम एक विभाजन दोष को कैसे फँसाता है और एक डिबगर को खोल देता है (यह मूल कोड के तहत उपयोग किया जाता है AIX) और स्टैक ट्रेस को एक विभाजन दोष के बिंदु तक प्रिंट करता है। आपको लिनक्स के मामले में sprintfउपयोग करने के लिए चर को बदलना होगा gdb

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <stdarg.h>

static void signal_handler(int);
static void dumpstack(void);
static void cleanup(void);
void init_signals(void);
void panic(const char *, ...);

struct sigaction sigact;
char *progname;

int main(int argc, char **argv) {
    char *s;
    progname = *(argv);
    atexit(cleanup);
    init_signals();
    printf("About to seg fault by assigning zero to *s\n");
    *s = 0;
    sigemptyset(&sigact.sa_mask);
    return 0;
}

void init_signals(void) {
    sigact.sa_handler = signal_handler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigaction(SIGINT, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGSEGV);
    sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGBUS);
    sigaction(SIGBUS, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGQUIT);
    sigaction(SIGQUIT, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGHUP);
    sigaction(SIGHUP, &sigact, (struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask, SIGKILL);
    sigaction(SIGKILL, &sigact, (struct sigaction *)NULL);
}

static void signal_handler(int sig) {
    if (sig == SIGHUP) panic("FATAL: Program hanged up\n");
    if (sig == SIGSEGV || sig == SIGBUS){
        dumpstack();
        panic("FATAL: %s Fault. Logged StackTrace\n", (sig == SIGSEGV) ? "Segmentation" : ((sig == SIGBUS) ? "Bus" : "Unknown"));
    }
    if (sig == SIGQUIT) panic("QUIT signal ended program\n");
    if (sig == SIGKILL) panic("KILL signal ended program\n");
    if (sig == SIGINT) ;
}

void panic(const char *fmt, ...) {
    char buf[50];
    va_list argptr;
    va_start(argptr, fmt);
    vsprintf(buf, fmt, argptr);
    va_end(argptr);
    fprintf(stderr, buf);
    exit(-1);
}

static void dumpstack(void) {
    /* Got this routine from http://www.whitefang.com/unix/faq_toc.html
    ** Section 6.5. Modified to redirect to file to prevent clutter
    */
    /* This needs to be changed... */
    char dbx[160];

    sprintf(dbx, "echo 'where\ndetach' | dbx -a %d > %s.dump", getpid(), progname);
    /* Change the dbx to gdb */

    system(dbx);
    return;
}

void cleanup(void) {
    sigemptyset(&sigact.sa_mask);
    /* Do any cleaning up chores here */
}

आपको इस ब्लॉग में यहां दिखाए गए अनुसार कोर को डंप करने के लिए gdb प्राप्त करने के लिए अतिरिक्त पैरामीटर जोड़ना पड़ सकता है ।


16

अधिक चीजें हैं जो कोर डंप की पीढ़ी को प्रभावित कर सकती हैं। मैंने इनका सामना किया:

  • डंप के लिए निर्देशिका लेखन योग्य होना चाहिए। डिफ़ॉल्ट रूप से यह प्रक्रिया की वर्तमान निर्देशिका है, लेकिन इसे सेटिंग में बदला जा सकता है /proc/sys/kernel/core_pattern
  • कुछ स्थितियों में, कर्नेल मान /proc/sys/fs/suid_dumpableकोर को उत्पन्न होने से रोक सकता है।

अधिक परिस्थितियां हैं जो मैन पेज में वर्णित पीढ़ी को रोक सकती हैं - कोशिश करें man core


9

कोर डंप को सक्रिय करने के लिए निम्नलिखित कार्य करें:

  1. /etc/profileलाइन में टिप्पणी करें:

    # ulimit -S -c 0 > /dev/null 2>&1
  2. /etc/security/limits.confलाइन में टिप्पणी करें:

    *               soft    core            0
  3. cmd निष्पादित करें limit coredumpsize unlimitedऔर इसे cmd के साथ जांचें limit:

    # limit coredumpsize unlimited
    # limit
    cputime      unlimited
    filesize     unlimited
    datasize     unlimited
    stacksize    10240 kbytes
    coredumpsize unlimited
    memoryuse    unlimited
    vmemoryuse   unlimited
    descriptors  1024
    memorylocked 32 kbytes
    maxproc      528383
    #
  4. यह जांचने के लिए कि अगर कोरफाइल लिखा गया है तो आप संबंधित प्रक्रिया को cmd के साथ मार सकते हैं kill -s SEGV <PID>(इसकी आवश्यकता नहीं होनी चाहिए, बस अगर कोई कोर फाइल नहीं लिखी गई तो इसे चेक के रूप में इस्तेमाल किया जा सकता है):

    # kill -s SEGV <PID>

एक बार Corefile लिखा गया है तो संबंधित फ़ाइलों में फिर से coredump सेटिंग्स को निष्क्रिय करना सुनिश्चित करें (1./2./3।)।


9

उबंटू 14.04 के लिए

  1. चेक कोर डंप सक्षम:

    ulimit -a
  2. लाइनों में से एक होना चाहिए:

    core file size          (blocks, -c) unlimited
  3. अगर नहीं :

    gedit ~/.bashrcऔर ulimit -c unlimitedफ़ाइल के अंत में जोड़ें और सहेजें, फिर से चलाएँ टर्मिनल।

  4. डीबग जानकारी के साथ अपना एप्लिकेशन बनाएं:

    मेकफाइल में -O0 -g

  5. अनुप्रयोग चलाएं जो कोर डंप बनाते हैं (कोर डंप फ़ाइल जिसका नाम 'core' है, को application_name फ़ाइल के पास बनाया जाना चाहिए):

    ./application_name
  6. Gdb के तहत चलाएं:

    gdb application_name core

चरण 3 में, टर्मिनल को to री-रन ’कैसे करें? क्या आपका मतलब रिबूट है?
नवीन

@ नवीन नहीं, बस नज़दीकी टर्मिनल और नया खोलें, यह भी लगता है कि आप बस ulimit -c unlimitedअस्थायी समाधान के लिए टर्मिनल में रख सकते हैं, क्योंकि केवल संपादन में ~/.bashrcपरिवर्तन करने के लिए टर्मिनल प्रतिबंध की आवश्यकता होती है।
मर्ग्लोम

4

डिफ़ॉल्ट रूप से आपको एक कोर फाइल मिलेगी। यह देखने के लिए जांचें कि प्रक्रिया की वर्तमान निर्देशिका लिखने योग्य है, या कोई कोर फ़ाइल नहीं बनाई जाएगी।


4
"प्रक्रिया की वर्तमान निर्देशिका" से क्या आपको लगता है कि प्रक्रिया चलने के समय $ cwd था? ~ / abc> / usr / bin / cat def अगर बिल्ली दुर्घटनाग्रस्त हो जाती है, तो वर्तमान निर्देशिका प्रश्न में है ~ / abc या / usr / बिन?
नाथन फेलमैन

5
~ / एबीसी। हम्म, टिप्पणियों को 15 वर्ण लंबा होना चाहिए!
मार्क हैरिसन

5
यह SEGV के समय की वर्तमान निर्देशिका होगी। इसके अलावा, वास्तविक उपयोगकर्ता / समूह की तुलना में एक अलग प्रभावी उपयोगकर्ता और / या समूह के साथ चलने वाली प्रक्रियाएं कोर फाइलें नहीं लिखेंगे।
डैरन

2

सिस्टम कॉल का उपयोग करके कोर डंप को प्रोग्रामेटिक रूप से चालू करना बेहतर है setrlimit

उदाहरण:

#include <sys/resource.h>

bool enable_core_dump(){    
    struct rlimit corelim;

    corelim.rlim_cur = RLIM_INFINITY;
    corelim.rlim_max = RLIM_INFINITY;

    return (0 == setrlimit(RLIMIT_CORE, &corelim));
}

यह बेहतर क्यों है?
नाथन फ़ेलमैन

क्रैश के बाद उत्पन्न कोर फ़ाइल, ulimit -c unlimitedकमांड लाइन के वातावरण में कोई ज़रूरत नहीं है, और फिर आवेदन को फिर से चलाएँ।
किग्राबुक

मैं हर बार क्रैश होने पर कोर डंप नहीं चाहता, केवल तब जब कोई उपयोगकर्ता इसे देखने के लिए डेवलपर के रूप में मुझसे संपर्क करता है। यदि यह 100 बार क्रैश हो जाता है, तो मुझे देखने के लिए 100 कोर डंप की आवश्यकता नहीं है।
नाथन फ़ेलमैन

था मामले में, बेहतर उपयोग करने के लिए ulimit -c unlimited। इसके अलावा, आप मार्को परिभाषा के साथ संकलन कर सकते हैं, आवेदन में enable_core_dumpप्रतीक शामिल नहीं होगा यदि रिलीज़ होने पर उस मैक्रो को परिभाषित न करें, और आपको डिबग संस्करण के साथ कोर डंप प्रतिस्थापित मिलेगा।
किलोबुक

भले ही यह मैक्रो द्वारा योग्य हो, फिर भी मुझे पुनर्मिलन की आवश्यकता होती है यदि मैं कोर डंप उत्पन्न करना चाहता हूं, बजाय इसके कि केवल पुनरावृत्ति से पहले शेल में एक कमांड निष्पादित कर रहा हूं।
नाथन फेलमैन

1

यह ध्यान देने योग्य है कि यदि आपके पास एक सिस्टमड सेट है, तो चीजें थोड़ी अलग हैं। core_patternSysctl मान के माध्यम से, आमतौर पर सेट की जाने वाली कोर फाइलें पाइप की जाएंगी systemd-coredump(8)। मुख्य फ़ाइल आकार का मुख्य भाग आमतौर पर "असीमित" के रूप में कॉन्फ़िगर किया जाएगा।

इसके बाद कोर डंप का उपयोग करके पुनः प्राप्त करना संभव है coredumpctl(1)

कोर डंप आदि का भंडारण द्वारा कॉन्फ़िगर किया गया है coredump.conf(5)। कोरडंपैक्टल मैन पेज में कोर फाइलें कैसे प्राप्त करें, इसके उदाहरण हैं, लेकिन संक्षेप में, यह इस तरह दिखाई देगा:

मूल फ़ाइल ढूँढें:

[vps@phoenix]~$ coredumpctl list test_me | tail -1
Sun 2019-01-20 11:17:33 CET   16163  1224  1224  11 present /home/vps/test_me

मूल फ़ाइल प्राप्त करें:

[vps@phoenix]~$ coredumpctl -o test_me.core dump 16163

0

उबंटू 19.04

अन्य सभी जवाबों ने खुद मेरी मदद नहीं की। लेकिन निम्नलिखित योग ने काम किया

~/.config/apport/settingsनिम्नलिखित सामग्री के साथ बनाएँ :

[main]
unpackaged=true

(यह ऐप्पर्ट को कस्टम ऐप के लिए कोर डंप लिखने के लिए भी कहता है)

जाँच: ulimit -c। यदि यह 0 से आउटपुट करता है, तो इसे ठीक करें

ulimit -c unlimited

बस मामले को फिर से शुरू करने के लिए:

sudo systemctl restart apport

अब क्रैश फाइलें लिखी गई हैं /var/crash/। लेकिन आप उन्हें gdb के साथ उपयोग नहीं कर सकते । उन्हें gdb के साथ उपयोग करने के लिए

apport-unpack <location_of_report> <target_directory>

अग्रिम जानकारी:

  • कुछ जवाब बदलने का सुझाव देते हैं core_pattern। ज्ञात हो, कि फ़ाइल को पुनरारंभ करने पर ऐपॉर्ट सेवा द्वारा अधिलेखित हो सकती है।
  • बस एप्पर रोककर काम नहीं किया
  • ulimit -cमूल्य स्वचालित रूप से बदल गया हो सकता है जब आप वेब के अन्य उत्तर कोशिश कर रहे हैं। अपने कोर डंप निर्माण की स्थापना के दौरान इसे नियमित रूप से जांचना सुनिश्चित करें।

संदर्भ:

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.