मेरे पास लिनक्स में एक प्रक्रिया है जो एक विभाजन दोष प्राप्त कर रही है। जब यह विफल होता है तो मैं इसे एक कोर डंप उत्पन्न करने के लिए कैसे कह सकता हूं
मेरे पास लिनक्स में एक प्रक्रिया है जो एक विभाजन दोष प्राप्त कर रही है। जब यह विफल होता है तो मैं इसे एक कोर डंप उत्पन्न करने के लिए कैसे कह सकता हूं
जवाबों:
यह इस बात पर निर्भर करता है कि आप किस शेल का उपयोग कर रहे हैं। यदि आप बैश का उपयोग कर रहे हैं, तो ulimit कमांड प्रोग्राम निष्पादन से संबंधित कई सेटिंग्स को नियंत्रित करता है, जैसे कि आपको कोर डंप करना चाहिए। यदि आप टाइप करते हैं
ulimit -c unlimited
तब यह बताएगा कि इसके कार्यक्रम किसी भी आकार के कोर को डंप कर सकते हैं। यदि आप चाहते हैं तो आप असीमित के बजाय 52M जैसे आकार निर्दिष्ट कर सकते हैं, लेकिन व्यवहार में यह आवश्यक नहीं होना चाहिए क्योंकि कोर फ़ाइलों का आकार संभवतः आपके लिए कोई समस्या नहीं होगी।
Tcsh में, आप टाइप करेंगे
limit coredumpsize unlimited
जैसा कि यहां पूछे जा रहे असली सवाल के ऊपर बताया गया है कि कैसे एक सिस्टम पर कोर डंप को सक्षम करना है जहां वे सक्षम नहीं हैं। उस प्रश्न का उत्तर यहाँ दिया गया है।
यदि आप यहाँ आये हैं तो यह सीखने की उम्मीद है कि त्रिशंकु प्रक्रिया के लिए कोर डंप कैसे उत्पन्न होता है, इसका उत्तर है
gcore <pid>
अगर आपके सिस्टम पर gcore उपलब्ध नहीं है तो
kill -ABRT <pid>
किल-एसईजीवी का उपयोग न करें क्योंकि यह अक्सर सिग्नल हैंडलर का इस्तेमाल करेगा जिससे अटकी प्रक्रिया का निदान करना कठिन हो जाएगा
-ABRT
एक सिग्नल हैंडलर की तुलना में -SEGV
, एक गर्भपात के रूप में पुनर्प्राप्ति की तुलना में पुनर्प्राप्त होने की अधिक संभावना है। (यदि आप एक सेगफॉल्ट को संभालते हैं, तो आमतौर पर यह आपके हैंडलर के बाहर निकलते ही फिर से ट्रिगर हो जाएगा।) कोर डंप जनरेट करने के लिए सिग्नल का एक बेहतर विकल्प है -QUIT
।
यह जाँचने के लिए कि कोर डंप कहाँ उत्पन्न होते हैं, चलाएँ:
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/
। हालाँकि, यह स्थिर रिलीज़ में डिफ़ॉल्ट रूप से अक्षम है।
अधिक जानकारी के लिए, कृपया जांचें: मुझे उबंटू में कोर डंप कहां मिलेगा? ।
मैकओएस के लिए, देखें: मैक ओएस एक्स में कोर डंप कैसे उत्पन्न करें?
अंत में मैंने क्या किया था कि यह क्रैश होने से पहले प्रक्रिया में gdb संलग्न था, और फिर जब इसे segfault मिला तो मैंने generate-core-file
कमांड निष्पादित किया । कि एक कोर डंप की पीढ़ी मजबूर।
ge
)
ulimit -c
करने के लिए unlimited
है, लेकिन मूल फ़ाइल नहीं बनाई शांत है, generate-core-file
gdb सत्र में फ़ाइल मूल फ़ाइल, धन्यवाद पैदा करता है।
हो सकता है कि आप इसे इस तरह से कर सकते हैं, यह प्रोग्राम एक विभाजन दोष को कैसे फँसाता है और एक डिबगर को खोल देता है (यह मूल कोड के तहत उपयोग किया जाता है 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 प्राप्त करने के लिए अतिरिक्त पैरामीटर जोड़ना पड़ सकता है ।
अधिक चीजें हैं जो कोर डंप की पीढ़ी को प्रभावित कर सकती हैं। मैंने इनका सामना किया:
/proc/sys/kernel/core_pattern
। /proc/sys/fs/suid_dumpable
कोर को उत्पन्न होने से रोक सकता है।अधिक परिस्थितियां हैं जो मैन पेज में वर्णित पीढ़ी को रोक सकती हैं - कोशिश करें man core
।
कोर डंप को सक्रिय करने के लिए निम्नलिखित कार्य करें:
/etc/profile
लाइन में टिप्पणी करें:
# ulimit -S -c 0 > /dev/null 2>&1
/etc/security/limits.conf
लाइन में टिप्पणी करें:
* soft core 0
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
#
यह जांचने के लिए कि अगर कोरफाइल लिखा गया है तो आप संबंधित प्रक्रिया को cmd के साथ मार सकते हैं kill -s SEGV <PID>
(इसकी आवश्यकता नहीं होनी चाहिए, बस अगर कोई कोर फाइल नहीं लिखी गई तो इसे चेक के रूप में इस्तेमाल किया जा सकता है):
# kill -s SEGV <PID>
एक बार Corefile लिखा गया है तो संबंधित फ़ाइलों में फिर से coredump सेटिंग्स को निष्क्रिय करना सुनिश्चित करें (1./2./3।)।
उबंटू 14.04 के लिए
चेक कोर डंप सक्षम:
ulimit -a
लाइनों में से एक होना चाहिए:
core file size (blocks, -c) unlimited
अगर नहीं :
gedit ~/.bashrc
और ulimit -c unlimited
फ़ाइल के अंत में जोड़ें और सहेजें, फिर से चलाएँ टर्मिनल।
डीबग जानकारी के साथ अपना एप्लिकेशन बनाएं:
मेकफाइल में -O0 -g
अनुप्रयोग चलाएं जो कोर डंप बनाते हैं (कोर डंप फ़ाइल जिसका नाम 'core' है, को application_name फ़ाइल के पास बनाया जाना चाहिए):
./application_name
Gdb के तहत चलाएं:
gdb application_name core
ulimit -c unlimited
अस्थायी समाधान के लिए टर्मिनल में रख सकते हैं, क्योंकि केवल संपादन में ~/.bashrc
परिवर्तन करने के लिए टर्मिनल प्रतिबंध की आवश्यकता होती है।
डिफ़ॉल्ट रूप से आपको एक कोर फाइल मिलेगी। यह देखने के लिए जांचें कि प्रक्रिया की वर्तमान निर्देशिका लिखने योग्य है, या कोई कोर फ़ाइल नहीं बनाई जाएगी।
सिस्टम कॉल का उपयोग करके कोर डंप को प्रोग्रामेटिक रूप से चालू करना बेहतर है 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
कमांड लाइन के वातावरण में कोई ज़रूरत नहीं है, और फिर आवेदन को फिर से चलाएँ।
ulimit -c unlimited
। इसके अलावा, आप मार्को परिभाषा के साथ संकलन कर सकते हैं, आवेदन में enable_core_dump
प्रतीक शामिल नहीं होगा यदि रिलीज़ होने पर उस मैक्रो को परिभाषित न करें, और आपको डिबग संस्करण के साथ कोर डंप प्रतिस्थापित मिलेगा।
यह ध्यान देने योग्य है कि यदि आपके पास एक सिस्टमड सेट है, तो चीजें थोड़ी अलग हैं। core_pattern
Sysctl मान के माध्यम से, आमतौर पर सेट की जाने वाली कोर फाइलें पाइप की जाएंगी 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
उबंटू 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
मूल्य स्वचालित रूप से बदल गया हो सकता है जब आप वेब के अन्य उत्तर कोशिश कर रहे हैं। अपने कोर डंप निर्माण की स्थापना के दौरान इसे नियमित रूप से जांचना सुनिश्चित करें।संदर्भ: