2008-11-14 8 views
6

मैं बाहर काम कैसे स्टोर करने के लिए और फिर मेरी सी में वर्तमान ढेर मुद्रित करने के लिए कोशिश कर रहा हूँ ++ Mac OS X पर क्षुधा मुख्य समस्या सही प्रतीक वापस जाने के लिए dladdr हो रही किया जा रहा है जब मुख्य निष्पादन योग्य के अंदर एक पता दिया गया। मुझे संदेह है कि मुद्दा वास्तव में एक संकलन विकल्प है, लेकिन मुझे यकीन नहीं है।मैक ओएस एक्स पर वर्तमान स्टैक ट्रेस हो रही

मैं डार्विन/तेंदुए से पश्व-अनुरेखन कोड की कोशिश की है, लेकिन यह dladdr कॉल करता है और अपने खुद के कोड बुला dladdr रूप में एक ही समस्या है।

मूल पोस्ट:

int BackTrace(Addr *buffer, int max_frames) 
{ 
    void **frame = (void **)__builtin_frame_address(0); 
    void **bp = (void **)(*frame); 
    void *ip = frame[1]; 
    int i; 

    for (i = 0; bp && ip && i < max_frames; i++) 
    { 
     *(buffer++) = ip; 
     ip = bp[1]; 
     bp = (void**)(bp[0]); 
    } 

    return i; 
} 

ठीक काम करने लगता है कौन सा: वर्तमान में मैं इस कोड के साथ ढेर पर कब्जा कर रहा हूँ।

Dl_info dli; 
if (dladdr(Ip, &dli)) 
{ 
    ptrdiff_t  offset; 
    int c = 0; 

    if (dli.dli_fname && dli.dli_fbase) 
    { 
     offset = (ptrdiff_t)Ip - (ptrdiff_t)dli.dli_fbase; 
     c = snprintf(buf, buflen, "%s+0x%x", dli.dli_fname, offset); 
    } 
    if (dli.dli_sname && dli.dli_saddr) 
    { 
     offset = (ptrdiff_t)Ip - (ptrdiff_t)dli.dli_saddr; 
     c += snprintf(buf+c, buflen-c, "(%s+0x%x)", dli.dli_sname, offset); 
    } 

    if (c > 0) 
     snprintf(buf+c, buflen-c, " [%p]", Ip); 

कौन सा लगभग काम करता है, उदाहरण के लिए कुछ उत्पादन: सही साझा वस्तु नहीं बल्कि के लिए के लिए

/Users/matthew/Library/Frameworks/Lgi.framework/Versions/A/Lgi+0x2473d(LgiStackTrace+0x5d) [0x102c73d] 
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x2a006(tart+0x28e72) [0x2b006] 
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x2f438(tart+0x2e2a4) [0x30438] 
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x35e9c(tart+0x34d08) [0x36e9c] 
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x1296(tart+0x102) [0x2296] 
/Users/matthew/Code/Lgi/LgiRes/build/Debug/LgiRes.app/Contents/MacOS/LgiRes+0x11bd(tart+0x29) [0x21bd] 

यह विधि नाम हो रही है तो फिर इस तरह dladdr का उपयोग करने में ढेर मैं देख रहा हूँ मुद्रित करने के लिए मुख्य ऐप वे सिर्फ "टार्ट" (या "प्रारंभ करें" को पहले अक्षर से शुरू करें)।

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

वैसे भी, किसी को भी तो यह विधि के नाम सही हो जाता है बाहर इस कोड को सॉर्ट कर सकते हैं?

उत्तर

12

क्या ओएस एक्स के रिलीज आप लक्ष्यीकरण कर रहे हैं। यदि आप मैक ओएस एक्स 10.5 और उच्चतर पर चल रहे हैं तो आप केवल बैकट्रैक() और backtrace_symbols() libraray कॉल का उपयोग कर सकते हैं। उन्हें execinfo.h में परिभाषित किया गया है, और कुछ नमूना कोड के साथ manpage है।

संपादित करें:

आप टिप्पणी है कि आप टाइगर पर चलने की जरूरत है में उल्लेख किया है। आप शायद अपने ऐप में लिबिक से कार्यान्वयन भी शामिल कर सकते हैं। स्रोत ऐप्पल की ओपनसोर्स साइट से उपलब्ध है। यहां file के रिलीज का लिंक दिया गया है।

+0

मैं वर्तमान में वर्तमान और पूर्व में जारी हुए, यानी तेंदुए और बाघ को लक्ष्य कर रहा। इसके अलावा मेरे पास वर्तमान में मेरी मैकबुक पर बाघ है। तो जब तक बर्फ तेंदुए बाहर नहीं आ जाता है तब तक मेरे कोड को बाघ पर संकलित/चलाने की आवश्यकता होगी। – user33847

+0

ठीक है, उन फ़ंक्शन के लिए स्रोत कोड opensource है, इसलिए आप शायद अपने ऐप में कार्यान्वयन शामिल कर सकते हैं। मैं रिलीज जानकारी के साथ अपना जवाब संपादित कर रहा हूं। –

+0

मैंने आपके द्वारा पोस्ट किए गए कोड पर एक नज़र डाली है और अंत में यह मेरे कोड के समान ही dladdr का उपयोग करता है। जो वही गलत परिणाम देता है, मेरे निष्पादन योग्य (यानी साझा वस्तु नहीं) में कुछ भी प्रतीक "टार्ट" होता है। – user33847