दिलचस्प पोस्ट
"~ / डेस्कटॉप / test.txt: ऐसा कोई फ़ाइल या निर्देशिका नहीं" मेरा टेम्पलेट प्रारंभिक सूची क्यों नहीं स्वीकार करता है एक ही आंशिक दृश्य को नियंत्रक को कई बार डेटा कहते हैं? मैं "कंपाइलर विर्सन" आईआईएस त्रुटि कैसे ठीक करूं? क्या फ़ायरबेज 3 में टोकन के सर्वर साइड सत्यापन करना अभी भी संभव है? MATLAB में & amp और && के बीच अंतर क्या है? कार्यान्वयन-परिभाषित व्यवहार से बचाव कुशल अहस्ताक्षरित-टू-हस्ताक्षरित कास्ट क्या जावा सचमुच है ओ (1)? ग्राहक SOAP अनुरोध भेजने और प्रतिक्रिया प्राप्त करने के लिए C ++ स्ट्रिंग कन्वर्ट हेक्साडेसिमल और इसके विपरीत किसी विधि का एक विशेषता का मूल्य पढ़ें जीयूआई एमवीसी को फिर से लिखने के बाद काम नहीं कर रहा है नहीं में मौजूदा नहीं बनाम पीडीएफ ब्लॉब सामग्री प्रदर्शित नहीं कर रहा है, कोनालर 2 मैं एक UIButton subclass क्यों नहीं होना चाहिए?

सी या सी ++ में प्रिंट कॉल स्टैक

क्या सी या सी ++ में चलने वाली प्रक्रिया में कॉल स्टैक को डंप करने के लिए कोई भी तरीका हर बार एक निश्चित फ़ंक्शन कहा जाता है? मेरे मन में जो कुछ है वह ऐसा है:

void foo() { print_stack_trace(); // foo's body return } 

जहां print_stack_trace पर्ल में caller समान काम करता है

या इस तरह का कुछ:

 int main (void) { // will print out debug info every time foo() is called register_stack_trace_function(foo); // etc... } 

जहां register_stack_trace_function कुछ प्रकार के आंतरिक ब्रेकपॉइंट को डालता है जिससे स्टैक ट्रेस प्रिंट हो सकता है जब भी foo को कॉल किया जाता है।

क्या कुछ ऐसा कुछ मानक सी लाइब्रेरी में मौजूद है?

मैं जीसीसी के प्रयोग से लिनक्स पर काम कर रहा हूं।


पृष्ठभूमि

मेरे पास एक टेस्ट रन है जो कुछ कमांडलाइन स्विचेस के आधार पर अलग ढंग से व्यवहार करता है जिससे इस व्यवहार को प्रभावित नहीं करना चाहिए मेरे कोड में छद्म-यादृच्छिक संख्या जनरेटर है जो मुझे लगता है कि इन स्विचों के आधार पर अलग-अलग बुलाया जा रहा है मैं स्विच के प्रत्येक सेट के साथ टेस्ट चलाने में सक्षम होना चाहता हूं और यह देखने के लिए कि क्या यादृच्छिक संख्या जनरेटर को प्रत्येक एक के लिए अलग कहा जाता है

वेब के समाधान से एकत्रित समाधान "सी या सी ++ में प्रिंट कॉल स्टैक"

लिनक्स-केवल समाधान के लिए आप बैकटास (3) का उपयोग कर सकते हैं जो बस void * की एक सरणी देता है void * (वास्तव में इनमें से प्रत्येक बिंदु इसी स्टैक फ़्रेम से रिटर्न पते पर) इसका उपयोग करने के लिए कुछ का अनुवाद करने के लिए, बैकट्र्रेस_संबॉल्स (3)

बैकटास (3) में नोट्स अनुभाग पर ध्यान दें:

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

ऐसा करने के लिए कोई मानकीकृत तरीका नहीं है विंडो के लिए कार्यक्षमता डीबीजी सहायता पुस्तकालय में दी गई है

क्या सी या सी ++ में चलने वाली प्रक्रिया में कॉल स्टैक को डंप करने के लिए कोई भी तरीका हर बार एक निश्चित फ़ंक्शन कहा जाता है?

विशिष्ट फ़ंक्शन में आप रिटर्न स्टेटमेंट के बजाय मैक्रो फ़ंक्शन का उपयोग कर सकते हैं।

उदाहरण के लिए, वापसी का उपयोग करने के बजाय,

 int foo(...) { if (error happened) return -1; ... do something ... return 0 } 

आप मैक्रो फ़ंक्शन का उपयोग कर सकते हैं।

 #include "c-callstack.h" int foo(...) { if (error happened) NL_RETURN(-1); ... do something ... NL_RETURN(0); } 

फ़ंक्शन में कोई भी त्रुटि होने पर, आपको नीचे दिखाए गए अनुसार जावा-शैली कॉल स्टैक दिखाई देगा।

 Error(code:-1) at : so_topless_ranking_server (sample.c:23) Error(code:-1) at : nanolat_database (sample.c:31) Error(code:-1) at : nanolat_message_queue (sample.c:39) Error(code:-1) at : main (sample.c:47) 

पूर्ण स्रोत कोड यहां उपलब्ध है।

https://github.com/Nanolat पर सी-कॉलस्टैक

आप इसके लिए पोपी उपयोग कर सकते हैं। यह आमतौर पर दुर्घटना के दौरान स्टैक ट्रेस को इकट्ठा करने के लिए उपयोग किया जाता है, लेकिन यह एक रनिंग प्रोग्राम के लिए भी इसे आउटपुट कर सकता है।

अब यह अच्छा हिस्सा है: यह स्टैक पर प्रत्येक फ़ंक्शन के लिए वास्तविक पैरामीटर मानों का उत्पादन कर सकता है, यहां तक ​​कि स्थानीय चर, लूप काउंटर आदि।

आप अपनी कार्यक्षमता को लागू कर सकते हैं:

वैश्विक (स्ट्रिंग) स्टैक का उपयोग करें और प्रत्येक फ़ंक्शन की शुरुआत में फ़ंक्शन नाम और ऐसे स्टैक पर ऐसे अन्य मान (जैसे पैरामीटर) को पुश करें; समारोह के बाहर निकलने पर इसे फिर से पॉप।

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

यह बहुत काम की तरह लग सकता है लेकिन काफी उपयोगी है

बेशक अगले सवाल यह है कि क्या यह पर्याप्त होगा?

स्टैक-निशान का मुख्य नुकसान यह है कि क्यों आपके पास सटीक कार्य किया जा रहा है जिसे आपके पास कुछ और नहीं है, जैसे कि इसके तर्कों के मान, जो डीबगिंग के लिए बहुत उपयोगी है।

अगर आपके पास जीसीसी और जीडीबी तक पहुंच है, तो मैं एक विशिष्ट स्थिति की जांच करने के लिए assert सुझाव देता हूं, और मेमरी डंप का निर्माण नहीं करता है अगर यह पूरा नहीं हुआ है। बेशक इसका मतलब है कि प्रक्रिया बंद हो जाएगी, लेकिन आपके पास केवल एक स्टैक-ट्रेस की बजाए एक पूर्ण रिपोर्ट होगी

यदि आप कम जोखिमहीन तरीके के लिए चाहते हैं, तो आप लॉगिंग का उपयोग कर सकते हैं। वहाँ बहुत कुशल प्रवेश सुविधाएं हैं, जैसे पैंथाइओस उदाहरण के लिए। जो एक बार फिर से आपको क्या हो रहा है की एक अधिक सटीक छवि दे सकता है।

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

क्या सी या सी ++ में चलने वाली प्रक्रिया में कॉल स्टैक को डंप करने के लिए कोई भी तरीका हर बार एक निश्चित फ़ंक्शन कहा जाता है?

कोई नहीं है, हालांकि प्लेटफॉर्म पर निर्भर समाधान मौजूद हो सकते हैं।