2011-06-19 13 views
16

लिनक्स में, बैकट्रैक प्राप्त करने के लिए आप बैकट्रैक() लाइब्रेरी कॉल का उपयोग कर सकते हैं, लेकिन यह केवल वर्तमान थ्रेड का बैकट्रैक देता है। क्या किसी अन्य धागे का बैकट्रैक प्राप्त करने का कोई तरीका है, मुझे लगता है कि मुझे पता है कि यह टीआईडी ​​(या pthread_t) है और मैं इसकी गारंटी दे सकता हूं?अन्य धागे का पिछला भाग

ऐसा लगता है कि libunwind (http://www.nongnu.org/libunwind/) परियोजना मदद कर सकती है। समस्या यह है कि यह CentOS द्वारा समर्थित नहीं है, इसलिए मैं इसका उपयोग नहीं करना पसंद करता हूं।

कोई अन्य विचार? धन्यवाद।

उत्तर

7

बैकट्रैक की सहायता से सिग्नल हैंडलिंग आपके उद्देश्य को हल कर सकती है।

मेरा मतलब है कि यदि आपके पास थ्रेड का पीआईडी ​​है, तो आप उस थ्रेड के लिए सिग्नल बढ़ा सकते हैं। और हैंडलर में आप बैकट्रैक का उपयोग कर सकते हैं। चूंकि हैंडलर उस विशेष धागे में निष्पादित होगा, बैकट्रैक आपके लिए आवश्यक आउटपुट होगा।

+1

यह वही नहीं है जो मैं खोज रहा था, लेकिन यह एक अच्छा विचार है। मुझे लगता है कि मैं इसका इस्तेमाल कर सकता हूं। धन्यवाद! –

+0

@Alexander यह समाधान आपके लिए काम कर रहा है जब मॉलोक या कॉल जैसी निःशुल्क कॉल स्टैक है ..? और क्या आप सिग्नल हैंडलर से इस मामले में बैकट्रैक() को कॉल करने में सक्षम हैं? मुझे दुर्घटना हो रही है। – sandeep

+0

आखिरकार, मैंने libunwind के साथ काम करने का फैसला किया। यह समाधान मेरे परिस्थितियों के लिए बहुत जटिल है और मैंने इसे छोड़ने का फैसला किया। वैसे भी, अगर आप इसे किसी भी तरह से काम करते हैं तो कृपया यहां पोस्ट करें। –

8

मैंने इसे स्वयं here लागू किया।

प्रारंभ में, मैं here सुझाव के रूप में, यानी किसी भी तरह धागे के शीर्ष फ्रेम सूचक हो रही है और तनाव मुक्त इसे मैन्युअल रूप से (लिंक किए गए स्रोत सेब से ली गई है backtrace कार्यान्वयन, इस प्रकार एप्पल विशिष्ट हो सकता है कुछ इसी तरह लागू करने के लिए चाहता था, लेकिन विचार सामान्य है)।

हालांकि, यह सुरक्षित रखने के लिए (और उपर्युक्त स्रोत किसी भी तरह से टूटा नहीं जा सकता है), आपको अपने ढेर तक पहुंचने के दौरान थ्रेड को निलंबित करना होगा। मैंने धागे को निलंबित करने के विभिन्न तरीकों के लिए चारों ओर खोज की और this, this और this पाया। असल में, वास्तव में कोई अच्छा तरीका नहीं है। आम हैक, used by the Hotspot JAVA VM, सिग्नल का उपयोग करना और pthread_kill के माध्यम से अपने धागे पर कस्टम सिग्नल भेजना है।

तो, के रूप में मैं इस तरह की आवश्यकता होगी वैसे भी संकेत हैक, मैं यह थोड़ा आसान हो सकता है और सिर्फ बुलाया संकेत हैंडलर जो लक्ष्य सूत्र में निष्पादित किया जाता है अंदर backtrace का उपयोग करें (के रूप में भी here by sandeep सुझाव दिया)। यह मूल रूप से मेरा कार्यान्वयन कर रहा है।

आप भी पश्व-अनुरेखन मुद्रण में रुचि रखते हैं, अर्थात कुछ उपयोगी डिबगिंग जानकारी (समारोह नाम, स्रोत कोड फ़ाइल नाम, स्रोत कोड लाइन नंबर, ...) मिलता है, libbfd के आधार पर एक विस्तारित backtrace_symbols के बारे में here पढ़ें। या बस स्रोत here देखें।

+1

अल्बर्ट कहा, मेरे पास एक परिदृश्य है जहां मुझे पृष्ठभूमि धागे से मुख्य धागे का कॉल स्टैक प्राप्त करने की आवश्यकता है। पीछे विचार यह है कि अगर 2 सेकंड से अधिक यूआई थ्रेड में लटका हुआ है, तो पृष्ठभूमि थ्रेड जो प्रत्येक 200 एमआई यूआई थ्रेड पर नज़र रखता है, कॉल स्टैक एकत्र करेगा। मैं सोच रहा था कि आपका समाधान भी इस पते को संबोधित कर सकता है? अग्रिम के लिए बहुत बहुत धन्यवाद। –

+0

@ilkerAcar: हां, मेरे कार्यान्वयन में फ़ंक्शन 'int GetCallstack (ThreadId threadId, शून्य ** बफर, int आकार) 'किसी भी थ्रेड से कहा जा सकता है। बस मुख्य धागा आईडी पास करें। – Albert

+0

बीटीडब्लू।, मैं कुछ परियोजनाओं में यह भी कर रहा हूं, 'startMainLockDetector() '[यहां] (https://github.com/albertz/openlierox/blob/0.59/src/MainLoop.cpp) देखें। – Albert

0

gdb डिबगिंग बहु धागा कार्यक्रमों के लिए इन सुविधाओं को प्रदान करता है:

  • नई धागे
  • 'धागा धागा-आईडी', एक कमांड धागे
  • 'जानकारी धागे' के बीच स्विच करने के लिए स्वत: अधिसूचना, मौजूदा धागे के बारे में पूछने के लिए एक आदेश
  • 'धागा लागू [थ्रेड-आईडी-सूची] [सभी] तर्क', थ्रेड की सूची में कमांड लागू करने के लिए कमांड
  • थ्रेड-विशिष्ट ब्रेकपॉइंट्स
  • 'सेट प्रिंट थ्रेड-इवेंट', जो धागे की शुरुआत और बाहर निकलने पर संदेशों की छपाई को नियंत्रित करता है।
  • 'सेट libthread-db-search-path path', जो उपयोगकर्ता को यह निर्दिष्ट करने देता है कि डिफ़ॉल्ट विकल्प प्रोग्राम के साथ संगत नहीं है, तो libthread_db का उपयोग करने के लिए।

तो सीडीडी द्वारा 'जीडी थ्रेड-आईडी' द्वारा जीडीबी में थ्रेड की आवश्यकता है। फिर थ्रेड बैकट्रैक मुद्रित करने के लिए उस थ्रेड संदर्भ में 'बीटी' करें।

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