दिलचस्प पोस्ट
प्रोटोटाइप के साथ एक घटना ट्रिगर करें Async-await on .net 4 का उपयोग करना एकाधिक पंक्तियों को एक अल्पविराम-पृथक मान jQuery के AJAX सफलता कॉलबैक फ़ंक्शन परिभाषा मैं जेवीएम द्वारा उपयोग किए जाने वाले प्रॉक्सी कैसे सेट करूं? क्यों malloc मेरे कंप्यूटर पर स्मृति का उपयोग नहीं कर रहा है? सीएसएस – क्यों प्रतिशत ऊंचाई काम नहीं करता है? मौजूदा कस्टम थीम के साथ XML में एक गतिविधि के लिए शीर्षक बार को कैसे छुपाया जाए ग्रहण: एक स्थानीय संपत्ति के माध्यम से एक पुस्तकालय में स्रोत / javadoc संलग्न करें मैं Visual Studio 2015 दुर्घटना का निदान कैसे कर सकता हूं? मैं एक ऐसी तालिका के लिए एसक्यूएल कैसे लिख सकता हूँ जो MySQL में संरक्षित कीवर्ड के समान नाम को साझा करता है? बूटस्ट्रैप 3 – अक्षमबार पतन अक्षम करें क्लोन / गहरी प्रतिलिपि करने के लिए सबसे अच्छा तरीका क्या है। नेट जेनेरिक शब्दकोश <string, T>? एक ही नाम के साथ बहु-विरासत कार्य क्यों करते हैं लेकिन अलग-अलग हस्ताक्षर को अतिभारित कार्यों के रूप में नहीं माना जाता? क्रोम एक्सटेंशन के ब्राउज़र एक्शन, पृष्ठभूमि स्क्रिप्ट, और कंटेंट स्क्रिप्ट के बीच संचार के संदर्भ और तरीके?

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

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

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 और आपको कुछ कोड के साथ अपना कोड संकलित करना होगा।

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

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