2008-08-20 11 views
7

यूनिक्स सिस्टम पर स्टैक ट्रेस प्राप्त करने के लिए कौन सी विधियां हैं? मेरा मतलब यह नहीं है कि सिर्फ कोर फाइल प्राप्त हो या जीडीबी के साथ अंतःक्रियात्मक रूप से संलग्न हो, लेकिन एक एसआईजीएसईजीवी हैंडलर जो पाठ फ़ाइल में बैकट्रैस को डंप करता है।यूनिक्स सिस्टम पर स्वचालित रूप से

निम्नलिखित वैकल्पिक सुविधाओं के लिए

बोनस अंक: (। उदाहरण के लिए config फ़ाइलें)

  • अतिरिक्त जानकारी दुर्घटना समय में जमा हो।
  • डेवलपर्स को क्रैश जानकारी बंडल ईमेल करें। एक dlopen एड साझा लाइब्रेरी में जोड़ने के लिए
  • क्षमता
  • एक जीयूआई

उत्तर

7

नहीं की आवश्यकता होती है आप उपलब्ध बीएसडी backtrace कार्यक्षमता (लिनक्स, OSX 1.5, निश्चित रूप से बीएसडी), आप कर सकते हैं के साथ सिस्टम पर कर रहे हैं अपने सिग्नल हैंडलर में प्रोग्रामेटिक रूप से करें।

उदाहरण के लिए

(backtrace code derived from IBM example):

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

void sig_handler(int sig) 
{ 
    void * array[25]; 
    int nSize = backtrace(array, 25); 
    char ** symbols = backtrace_symbols(array, nSize); 

    for (int i = 0; i < nSize; i++) 
    { 
     puts(symbols[i]);; 
    } 

    free(symbols); 

    signal(sig, &sig_handler); 
} 

void h() 
{ 
    kill(0, SIGSEGV); 
} 

void g() 
{ 
    h(); 
} 

void f() 
{ 
    g(); 
} 

int main(int argc, char ** argv) 
{ 
    signal(SIGSEGV, &sig_handler); 
    f(); 
} 

आउटपुट:

0 a.out        0x00001f2d sig_handler + 35 
1 libSystem.B.dylib     0x95f8f09b _sigtramp + 43 
2 ???         0xffffffff 0x0 + 4294967295 
3 a.out        0x00001fb1 h + 26 
4 a.out        0x00001fbe g + 11 
5 a.out        0x00001fcb f + 11 
6 a.out        0x00001ff5 main + 40 
7 a.out        0x00001ede start + 54 

यह (एक जीयूआई की जरूरत नहीं को छोड़कर) वैकल्पिक सुविधाओं के लिए बोनस अंक नहीं मिलता है, तथापि, यह है बहुत सरल होने का लाभ, और किसी भी अतिरिक्त पुस्तकालयों या कार्यक्रमों की आवश्यकता नहीं है।

2

Dereks समाधान शायद सबसे अच्छा है, लेकिन यहाँ एक वैकल्पिक वैसे भी: करने के लिए पाइप कोर एक स्क्रिप्ट या कार्यक्रम के लिए उदासीनता

हाल लिनक्स कर्नेल संस्करण आप अनुमति देते हैं। आप कोर डंप को पकड़ने के लिए एक स्क्रिप्ट लिख सकते हैं, आपको आवश्यक अतिरिक्त जानकारी एकत्र कर सकते हैं और सब कुछ वापस भेज सकते हैं। हालांकि यह एक वैश्विक सेटिंग है, इसलिए यह सिस्टम पर किसी भी क्रैशिंग प्रोग्राम पर लागू होगा। इसे स्थापित करने के लिए रूट अधिकारों की भी आवश्यकता होगी। इसे/proc/sys/kernel/core_pattern फ़ाइल के माध्यम से कॉन्फ़िगर किया जा सकता है। इसे '|/घर/MyUser/bin/मेरी कोर-हैंडलर-स्क्रिप्ट '।

उबंटू लोग इस सुविधा का भी उपयोग करते हैं।

4

यहां एक उदाहरण है कि डेमंगलर का उपयोग करके कुछ और जानकारी कैसे प्राप्त करें। जैसा कि आप देख सकते हैं कि यह फ़ाइल को स्टैकट्रैक भी लॉग करता है।

#include <iostream> 
#include <sstream> 
#include <string> 
#include <fstream> 
#include <cxxabi.h> 

void sig_handler(int sig) 
{ 
    std::stringstream stream; 
    void * array[25]; 
    int nSize = backtrace(array, 25); 
    char ** symbols = backtrace_symbols(array, nSize); 
    for (unsigned int i = 0; i < size; i++) { 
     int status; 
     char *realname; 
     std::string current = symbols[i]; 
     size_t start = current.find("("); 
     size_t end = current.find("+"); 
     realname = NULL; 
     if (start != std::string::npos && end != std::string::npos) { 
      std::string symbol = current.substr(start+1, end-start-1); 
      realname = abi::__cxa_demangle(symbol.c_str(), 0, 0, &status); 
     } 
     if (realname != NULL) 
      stream << realname << std::endl; 
     else 
      stream << symbols[i] << std::endl; 
     free(realname); 
    } 
    free(symbols); 
    std::cerr << stream.str(); 
    std::ofstream file("/tmp/error.log"); 
    if (file.is_open()) { 
     if (file.good()) 
      file << stream.str(); 
     file.close(); 
    } 
    signal(sig, &sig_handler); 
} 
+1

सिग्नल हैंडलर में सी ++ का उपयोग करके - जीनोम में बग। –

15

FYI करें,

सुझाव दिया समाधान (एक संकेत हैंडलर में backtrace_symbols का प्रयोग करके) खतरनाक तरीके से टूटी हुई है। उसका उपयोग नहीं करते -

हाँ, पश्व-अनुरेखन और backtrace_symbols एक पश्व-अनुरेखन का उत्पादन करेगा और एक प्रतीकात्मक नाम इसका अनुवाद, तथापि:

  1. backtrace_symbols malloc का उपयोग कर स्मृति आवंटित करता है और आप इसे मुक्त करने के लिए स्वतंत्र उपयोग करें - आप तो स्मृति भ्रष्टाचार के कारण दुर्घटनाग्रस्त हो रहा है आपका मॉलोक क्षेत्र भ्रष्ट होने की संभावना है और एक डबल गलती का कारण बनता है।

  2. malloc और आंतरिक रूप से लॉक के साथ मॉलोक क्षेत्र की रक्षा करें।आपने लॉक के साथ मॉलोक/फ्री के बीच में गलती की हो सकती है, जिससे इन फ़ंक्शन या कुछ भी उन्हें लॉक लॉक कर देगा।

  3. आप उन मानकों का उपयोग करते हैं जो मानक स्ट्रीम का उपयोग करते हैं, जो लॉक द्वारा भी संरक्षित है। यदि आप एक प्रिंटफ के बीच में गलती करते हैं तो आप एक बार फिर एक डेडलॉक करते हैं।

  4. 32 बिट प्लेटफार्मों (जैसे 2 साल पहले आपका सामान्य पीसी) पर, कर्नेल आपके स्टैक में आपके दोषपूर्ण फ़ंक्शन के बजाय एक आंतरिक ग्लिब फ़ंक्शन पर एक रिटर्न पता लगाएगा, इसलिए आपके द्वारा देखी जाने वाली जानकारी का एक सबसे महत्वपूर्ण टुकड़ा इसमें दिलचस्पी है - किस कार्यक्रम में प्रोग्राम गलती हुई थी, वास्तव में उन प्लेटफ़ॉर्म पर दूषित हो जाएगी।

तो, उदाहरण के में कोड गलत का सबसे बुरा प्रकार है - ऐसा लगता है कि यह काम कर रहा है, लेकिन यह वास्तव में उत्पादन में अप्रत्याशित तरीके से आप असफल हो जायेगी।

बीटीडब्ल्यू, इसे सही करने में रुचि रखते हैं? this बाहर देखें।

चीयर्स, गिलाद।

+3

प्रदान किया गया लिंक मर चुका है। – bltxd

+0

मैं इस क्षेत्र में बहुत ज्यादा नहीं जानता हूं। लेकिन अगर आप बच्चे की प्रक्रिया में बैकट्रैकिंग करते हैं और निष्पादित करते हैं तो आप इससे दूर हो सकते हैं, नहीं? – LiquidityC

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