2010-07-09 13 views
9

यह मैक्रोज़ (मुझे लगता है) के बारे में एक और सैद्धांतिक सवाल है। मुझे पता है कि मैक्रोज़ स्रोत कोड लेते हैं और इसका मूल्यांकन किए बिना ऑब्जेक्ट कोड उत्पन्न करते हैं, जिससे प्रोग्रामर अधिक बहुमुखी सिंटैक्टिक संरचनाएं बनाते हैं। अगर मुझे इन दो मैक्रो सिस्टम को वर्गीकृत करना पड़ा, तो मैं कहूंगा कि "सी स्टाइल" मैक्रो और "लिस्प स्टाइल" मैक्रो था।मैक्रो-सक्षम भाषा डिबगिंग के लिए स्रोत कोड का ट्रैक कैसे रखती है?

ऐसा लगता है कि मैक्रोज़ डीबगिंग थोड़ा मुश्किल हो सकता है क्योंकि रनटाइम पर, वास्तव में चलने वाला कोड स्रोत से अलग होता है।

कैसे डिबगर preprocessed स्रोत कोड के मामले में कार्यक्रम के निष्पादन का ट्रैक रखता है? क्या कोई विशेष "डीबग मोड" है जिसे मैक्रो के बारे में अतिरिक्त डेटा कैप्चर करने के लिए सेट किया जाना चाहिए?

सी में, मैं समझ सकता हूं कि आप डिबगिंग के लिए एक संकलन समय स्विच सेट करेंगे, लेकिन लिस्पी के कुछ रूपों जैसे एक व्याख्या की गई भाषा, यह कैसे करेगी?

इस बाहर कोशिश नहीं कर लिए खेद है, तुतलाना toolchain और अधिक समय की तुलना में मैं यह पता लगाने की खर्च करने की आवश्यकता है।

उत्तर

3

मुझे नहीं लगता कि "सी शैली" और "लिस्प शैली" मैक्रोज़ में संकलित कैसे किया जाता है, इसमें एक मौलिक अंतर है। दोनों संकलक से पहले स्रोत को बदलते हैं-उचित इसे देखता है। बड़ा अंतर यह है कि सी के मैक्रोज़ सी प्रीप्रोसेसर (कमजोर माध्यमिक भाषा जो आमतौर पर सरल स्ट्रिंग प्रतिस्थापन के लिए हैं) का उपयोग करते हैं, जबकि लिस्प के मैक्रोज़ लिस्प में स्वयं लिखे जाते हैं (और इसलिए कुछ भी कर सकते हैं)।

(एक तरफ के रूप में: मैंने कुछ समय में एक गैर संकलित लिस्प को नहीं देखा है ... निश्चित रूप से सदी के अंत के बाद से नहीं। लेकिन यदि कुछ भी, व्याख्या की जा रही है तो मैक्रो डीबगिंग समस्या को आसान बना दिया जाएगा, कठिन नहीं है, क्योंकि आपके पास अधिक जानकारी है।)

मैं माइकल से सहमत हूं: मैंने मैक्रोज़ को संभालने वाले सी के लिए डीबगर नहीं देखा है। मैक्रोज़ का उपयोग करने वाला कोड कुछ भी होने से पहले बदल जाता है। "debug" mode for compiling C code आमतौर पर इसका मतलब है कि यह functions, types, variables, filenames, and such स्टोर करता है - मुझे नहीं लगता कि उनमें से कोई भी मैक्रोज़ के बारे में जानकारी संग्रहीत करता है।

  • डीबगिंग प्रोग्राम हैं जो मैक्रो का उपयोग के लिए, लिस्प बहुत ज्यादा एक ही सी यहाँ के रूप में है: अपने डिबगर संकलित कोड, नहीं मैक्रो आवेदन देखता है। आमतौर पर मैक्रो सरल रखा जाता है, और डिबग स्वतंत्र रूप से उपयोग करने से पहले, इस के लिए जरूरत से बचने के लिए, बस सी की तरह

  • मैक्रो खुद को डीबगिंग, इससे पहले कि आप जा सकते हैं और इसे कहीं का उपयोग के लिए, लिस्प सुविधाओं कि सी, जैसे, repl और macroexpand-1 (सी में वहाँ है, हालांकि में की तुलना में आसान यह करना है जाहिर है के लिए एक रास्ता एक पूरी फ़ाइल macroexpand, पूरी तरह से एक ही बार में)। आप पहले और बाद एक macroexpansion की, अपने संपादक, में सही है जब आप इसे लिखने देख सकते हैं।

मैं किसी भी समय मैं एक स्थिति भर में भाग गया याद नहीं कर सकते जहां में डिबगिंग एक मैक्रो परिभाषा ही उपयोगी हो गया होता। या तो यह मैक्रो परिभाषा में एक बग, जिसमें मामले macroexpand-1 तुरंत समस्या को अलग कर देता है, या यह है कि नीचे एक बग है, ऐसी स्थिति में सामान्य डिबगिंग सुविधाओं ठीक काम करते हैं और मुझे परवाह नहीं है कि एक macroexpansion मेरे कॉल के दो फ्रेम के बीच हुई ढेर।

1

मुझे लिस्प मैक्रोज़ (जो मुझे संदेह है कि शायद सी मैक्रोज़ से काफी अलग है) या डिबगिंग के बारे में नहीं पता है, लेकिन कई - शायद अधिकांश - सी/सी ++ डिबगर्स सी प्रीप्रोसेसर मैक्रोज़ के स्रोत-स्तर डिबगिंग को विशेष रूप से अच्छी तरह से संभाल नहीं पाते हैं ।

आम तौर पर, C/C++ डिबगर वे मैक्रो परिभाषा में 'कदम' नहीं है। यदि एक मैक्रो एकाधिक कथन में फैलता है, तो डीबगर आमतौर पर प्रत्येक डीबगर 'चरण' ऑपरेशन के लिए उसी स्रोत रेखा (जहां मैक्रो लगाया जाता है) पर रहता है।

यह डीबगिंग मैक्रोज़ को अन्यथा होने की तुलना में थोड़ा अधिक दर्दनाक बना सकता है - फिर भी सी/सी ++ में उनसे बचने का एक अन्य कारण। यदि एक मैक्रो वास्तव में रहस्यमय तरीके से गलत व्यवहार कर रहा है, तो मैं इसे डीबग करने या मैक्रो का विस्तार करने के लिए असेंबली मोड में छोड़ दूंगा (या तो मैन्युअल रूप से या कंपाइलर स्विच का उपयोग कर)। यह बहुत दुर्लभ है कि आपको उस चरम पर जाना है; यदि आप मैक्रोज़ लिख रहे हैं जो जटिल हैं, तो आप शायद गलत दृष्टिकोण ले रहे हैं।

1

आमतौर पर सी स्रोत-स्तर डीबगिंग में लाइन ग्रैन्युलरिटी ("अगली" कमांड) या निर्देश-स्तर ग्रैन्युलरिटी ("चरण में") होती है। मैक्रो प्रोसेसर संसाधित स्रोत में विशेष निर्देश डालते हैं जो संकलक को स्रोत कोड लाइनों के लिए CPU निर्देशों के संकलित अनुक्रमों को मैप करने की अनुमति देते हैं।

लिस्प में संकलित कोड मैपिंग के लिए स्रोत कोड को ट्रैक करने के लिए मैक्रोज़ और कंपाइलर के बीच कोई सम्मेलन मौजूद नहीं है, इसलिए स्रोत कोड में सिंगल-स्टेपिंग करना हमेशा संभव नहीं होता है।

स्पष्ट विकल्प मैक्रोएक्सपेन्ड कोड में एकल चरणबद्ध करना है। कंपाइलर पहले से ही कोड का अंतिम, विस्तारित, संस्करण देखता है और मशीन कोड मैपिंग के लिए स्रोत कोड ट्रैक कर सकता है।

अन्य विकल्प इस तथ्य का उपयोग करना है कि हेरफेर के दौरान लिस्प अभिव्यक्तियों की पहचान है। यदि मैक्रो सरल है और केवल टेम्पलेट में कोड को विनाशकारी और पेस्ट कर रहा है तो विस्तारित कोड के कुछ भाव समान होंगे (ईक्यू तुलना के संबंध में) स्रोत कोड से पढ़े गए अभिव्यक्तियों के लिए। इस मामले में कंपाइलर विस्तारित कोड से स्रोत कोड में कुछ अभिव्यक्तियों को मानचित्र कर सकता है।

2

आपको वास्तव में ऐसे समर्थन में देखना चाहिए जो Racket मैक्रोज़ के साथ डीबगिंग कोड के लिए है। केन का उल्लेख है कि इस समर्थन में दो पहलू हैं। एक तरफ मैक्रोज़ डीबग करने का मुद्दा है: सामान्य लिस्प में ऐसा करने का सबसे अच्छा तरीका है मैक्रो रूपों को मैन्युअल रूप से विस्तारित करना। सीपीपी के साथ स्थिति समान है लेकिन अधिक आदिम है - आप केवल सीपीपी विस्तार के माध्यम से कोड चलाएंगे और परिणाम का निरीक्षण करेंगे। हालांकि, ये दोनों शामिल मैक्रोज़ के लिए अपर्याप्त हैं, और यह रैकेट में macro debugger रखने के लिए प्रेरणा थी - यह आपको सिंटैक्स विस्तार चरणों को एक-एक करके दिखाता है, जिसमें बाउंड आइडेंटिफायर आदि जैसी चीजों के लिए अतिरिक्त गुई-आधारित संकेत हैं।

के पक्ष में मैक्रोज़ का उपयोग करते हुए, रैकेट हमेशा अन्य योजना और लिस्प कार्यान्वयन से अधिक उन्नत रहा है। विचार यह है कि प्रत्येक अभिव्यक्ति (एक वाक्य रचनात्मक वस्तु के रूप में) कोड प्लस अतिरिक्त डेटा है जिसमें इसका स्रोत स्थान होता है। इस तरह से जब एक रूप एक मैक्रो, विस्तारित कोड मैक्रो से आ रही सही स्रोत स्थान होगा भागों में है वह यह है कि - मैक्रो के बजाय इसके उपयोग (जहां रूपों वास्तव में मौजूद नहीं हैं) से परिभाषा से। कुछ योजनाएं और लिस्प कार्यान्वयन उपरोक्त की पहचान का उपयोग करके इस के लिए सीमित लागू होंगे, जैसा कि डिमिट्री-वीके का उल्लेख है।

+0

लेकिन मैक्रो में वापस संकलित कोड मैपिंग निम्न समस्या का समाधान नहीं करता है: जब मैक्रो घोषणात्मक इनपुट (उदाहरण के लिए, मैक्रो जो संदर्भ-मुक्त व्याकरण से पार्सर उत्पन्न करता है) के आधार पर कोड उत्पन्न करता है तो यह डिबगिंग के दौरान बहुत उपयोगी होगा इनपुट का कौन सा हिस्सा "सक्रिय" है (उदाहरण के लिए, यदि संभव हो तो व्याकरण का नियम मिलान किया जा रहा है)। इसके लिए मैक्रो लेखक को स्पष्ट रूप से यह कहना होगा कि जेनरेट कोड के कौन से हिस्से मैक्रो इनपुट के किन हिस्सों से मेल खाते हैं। रैकेट मैक्रोज़ की ऐसी क्षमता है? अन्यथा, यह डीबगिंग (आंशिक रूप से) विस्तारित कोड के बराबर है। –

+0

"अन्यथा, यह डीबगिंग (आंशिक रूप से) विस्तारित कोड के बराबर है।" मुझे नहीं लगता कि मैं इस वाक्य में गलत हूं। कृपया इसे अनदेखा करें। –

+0

dmity-vk: दाएं - रैकेट में 'वाक्यविन्यास' विशेष रूप मूल रूप से मैक्रो से कोड के टुकड़ों के साथ मैक्रो उपयोगकर्ता से कोड के टुकड़ों को जोड़ने का ख्याल रखता है, और यह सुनिश्चित कर रहा है कि परिणामी रूपों पर स्रोत स्थान है सभी रूपों में सही है। –

3

LispWorks डेवलपर्स Stepper tool का उपयोग कर सकते हैं।

LispWorks एक स्टेपर, एक पूर्ण macro expansion process के माध्यम से जहां कदम कर सकते हैं प्रदान करता है।

0

सरल जवाब है कि यह जटिल है ;-) कई अलग-अलग चीजें हैं जो एक कार्यक्रम डिबग करने के लिए सक्षम किया जा रहा करने के लिए योगदान कर रहे हैं, और भी अधिक ट्रैकिंग मैक्रो के लिए है।

सी और सी ++ में, प्रीप्रोसेसर का उपयोग मैक्रोज़ का विस्तार करने और वास्तविक स्रोत कोड में शामिल करने के लिए किया जाता है। #line निर्देशों का उपयोग करके इस विस्तारित स्रोत फ़ाइल में मूल फ़ाइल नाम और रेखा संख्याएं ट्रैक की जाती हैं।

http://msdn.microsoft.com/en-us/library/b5w2czay(VS.80).aspx

जब एक सी या सी ++ प्रोग्राम डिबगिंग सक्षम के साथ संकलित किया गया है, कोडांतरक वस्तु फ़ाइल है कि स्रोत लाइनों, प्रतीक नाम, प्रकार वर्णनकर्ता, आदि पटरियों में अतिरिक्त जानकारी के उत्पन्न करता है

http://sources.redhat.com/gdb/onlinedocs/stabs.html

ऑपरेटिंग सिस्टम में ऐसी विशेषताएं हैं जो किसी प्रक्रिया को संलग्न करने और प्रक्रिया निष्पादन को नियंत्रित करने के लिए डीबगर के लिए संभव बनाती हैं; रुकने, एकल चरणबद्ध, आदि

जब प्रोग्राम से डीबगर जुड़ा होता है, तो यह प्रक्रिया स्टैक और प्रोग्राम काउंटर को डीबगिंग जानकारी में प्रोग्राम पते के अर्थ को देखकर प्रतीकात्मक रूप में वापस भेजता है।

गतिशील भाषाओं आम तौर पर एक आभासी मशीन में निष्पादित, चाहे वह एक दुभाषिया या एक बाईटकोड वीएम है। यह वीएम है जो एक डीबगर को प्रोग्राम प्रवाह को नियंत्रित करने और प्रोग्राम स्थिति का निरीक्षण करने के लिए हुक प्रदान करता है।

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