Gdb के साथ मानक कंटेनर (std :: map) सामग्री का निरीक्षण


93

इस तरह से कुछ करने की आपूर्ति:

#include <map>
int main(){
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;
}

मैं gdb से प्रोग्राम चलाने वाले मैप की सामग्री का निरीक्षण करने में सक्षम होना चाहूंगा।
अगर मुझे मिलने वाले सबस्क्रिप्ट ऑपरेटर का उपयोग करने का प्रयास करें:

(gdb) p m[1]
Attempt to take address of value not located in memory.

खोज विधि का उपयोग करने से बेहतर परिणाम नहीं मिलते हैं:

(gdb) p m.find(1)
Cannot evaluate function -- may be inlined

क्या इसको मदद देने का कोई तरीका है?

जवाबों:


35

मुझे लगता है कि कम से कम ऐसा नहीं है यदि आपका स्रोत अनुकूलित है आदि। हालांकि, जीडीबी के लिए कुछ मैक्रोज़ हैं जो आपके लिए एसटीएल कंटेनरों का निरीक्षण कर सकते हैं:

http://sourceware.org/ml/gdb/2008-02/msg00064.html

हालाँकि, मैं इसका उपयोग नहीं करता, इसलिए YMMV


1
लिंक के लिए धन्यवाद; केवल एक चीज यह है कि मैक्रोज़ स्टाल लाइब्रेरीज़ संस्करण से निर्भर हैं, जिनसे मैं बचना पसंद करूँगा। +1
पाओलो टेडेस्को

यह भी थोड़ा सा निराशाजनक है कि "plist foo std :: string" जैसी आज्ञाएं वाक्यविन्यास त्रुटियां देती हैं। ऐसा प्रतीत होता है कि value_type में कोई विराम चिह्न नहीं हो सकता है।
Bklyn

2
मैंने कोशिश नहीं की है, लेकिन अगर यह GDB के बाकी हिस्सों की तरह ही काम करता है, तो एकल उद्धरणों में पंक्चर वाले नाम के साथ संलग्न होना चाहिए।
jpalecek

2
नोट: इन स्क्रिप्ट्स में std :: मैप की कार्यक्षमता 32-बिट पॉइंटर प्रकारों को मानती है। 64-बिट मशीनों के लिए, फ़ाइल में हर जगह "+ 4" को "+ 8" बदलें।
काइल सिमेक

pvector मेरे gdb (संस्करण 7.5.91.20130417-cvs-ubuntu) में परिभाषित नहीं है।
जेफ

91

इस प्रश्न के मौजूदा उत्तर बहुत पुराने हैं। हाल ही में GCC और GDB के साथ यह GDB 7.x में बिल्ट-इन पाइथन सपोर्ट के लिए जस्ट वर्क्स TM धन्यवाद और GCC के साथ आने वाले libstdc ++ सुंदर प्रिंटर।

ओपी के उदाहरण के लिए मुझे मिलता है:

(gdb) print m
$1 = std::map with 2 elements = {[1] = 2, [2] = 4}

यदि यह आपके लिए स्वचालित रूप से काम नहीं करता है तो GDB विकि के STL समर्थन पृष्ठ पर पहला बुलेट बिंदु देखें ।

आप अपने खुद के प्रकारों के लिए भी पायथन सुंदर प्रिंटर लिख सकते हैं, जीडीबी मैनुअल में सुंदर मुद्रण देखें ।


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

1
मैं GDB 7.2 और उपरोक्त कार्यों का उपयोग कर रहा हूं ... यदि आपके पास एक छोटा संग्रह है। मुझे अभी भी एसटीएल कार्यान्वयन की आंतरिक संरचनाओं का उपयोग करने के अलावा, एक 4K वेक्टर से कहना तत्व 1543 को प्रिंट करने का कोई तरीका नहीं मिला है।
पावन

5
हाँ, GDB 7.2 और icpc संकलक में मुझे त्रुटि मिलती है Could not find operator[]
पावन

11
दुर्भाग्य से यह सभी विकृतियों में "जस्ट वर्क" नहीं है। यह Ubuntu 13.10 में डिफ़ॉल्ट रूप से स्थापित नहीं है और जब आप इसे मैन्युअल रूप से स्थापित करने का प्रयास करते
nietaki

1
@ क्रेज़, फेडोरा, आरएचईएल (और आरएचईएल क्लोन)। प्रगति में एक तय है कि प्रिंटर भी डिस्ट्रोस पर काम करते हैं जहां जीडीबी पायथन 3 से जुड़ा हुआ है
जोनाथन वैकली

25

हमेशा स्पष्ट होता है: अपने स्वयं के परीक्षण-कार्य को परिभाषित करें ... इसे gdb से कॉल करें। उदाहरण के लिए:

#define SHOW(X) cout << # X " = " << (X) << endl

void testPrint( map<int,int> & m, int i )
{
  SHOW( m[i] );
  SHOW( m.find(i)->first );
}

int
main()
{
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;  // Line 15.
}

तथा:

....
Breakpoint 1 at 0x400e08: file foo.C, line 15.
(gdb) run
Starting program: /tmp/z/qD 

Breakpoint 1, main () at qD.C:15
(gdb) call testPrint( m, 2)
m[i] = 4
(*m.find(i)).first = 2
(gdb) 

16
जब तक प्रक्रिया चल रही है। कोर-डंप के लिए इतना उपयोगी नहीं है।
सीन रिले

2
यह उपयोगी सलाह है GDB सामान्य तौर पर, केवल STL के साथ नहीं। मैं हार्ड-टू-रिकवेस्ट डेटा, जैसे राइट_cuda_array_as_image () के बहुत सारे के लिए gdb हेल्पर फ़ंक्शंस की पूरी लाइब्रेरी रखता हूं। ध्यान दें कि कुछ संकलक किसी भी फ़ंक्शन को कॉल करेंगे, जिन्हें कॉल नहीं किया जाता है, इसलिए मैं अपने मुख्य "रिटर्न 0" के बाद प्रत्येक हेल्पर फ़ंक्शन के लिए कॉल करता हूं। इसके अलावा उन्हें "सी" के साथ घोषित करना उन्हें gdb से कॉल करना आसान बनाता है।
काइल सिमेक

21

stl-views.gdbसर्वश्रेष्ठ उत्तर नहीं था हुआ करता था, लेकिन अब नहीं।

यह मुख्य लाइन में एकीकृत नहीं है GDBअभी तक, लेकिन यहाँ है कि तुम क्या 'आर्चर-tromey-अजगर' का उपयोग हो जाता है शाखा :

(gdb) list
1   #include <map>
2   int main(){
3       std::map<int,int> m;
4       m[1] = 2;
5       m[2] = 4;
6       return 0;
7   }
(gdb) break 6
Breakpoint 1 at 0x8048274: file map.cc, line 6.
(gdb) run

Breakpoint 1, main () at map.cc:6
6       return 0;
(gdb) print m
$1 = std::map with 2 elements = {
  [1] = 2,
  [2] = 4
}
(gdb) quit

12

इस पृष्ठ पर डीई-रेफरेंसिंग एसटीएल कंटेनर आज़माएँ: http://www.yolinux.com/TUTORIALS/GDB-ommy.html


ये दिखते हैं धंधे!
रिचर्ड कॉर्डन

वे वास्तव में पिछले उत्तर की तरह ही मैक्रो हैं :) मुझे डर है कि कोई सरल समाधान नहीं है।
पाओलो टेडेस्को

आज्ञा क्या है? आपने हमें अप्रासंगिक सूचनाओं के प्रचुर मात्रा में ऑफ-साइट चलाने में कामयाबी हासिल की। मुझे "GDB कैसे शुरू करें" और अन्य में कोई दिलचस्पी नहीं है।
1

1

ऊपर दिए गए जवाब काम कर रहे हैं और ठीक हैं। यदि आप stl-views.gdb का उपयोग कर रहे हैं, तो यहां मानचित्र और उसके अंदर के तत्वों को देखने का उचित तरीका है। आपका नक्शा इस प्रकार है: std::map<char, int> myMap;

(gdb) pmap myMap char int

अर्थात् pmap <variable_name> <left_element_type> <right_element_type>मानचित्र में तत्वों को देखने के लिए।

उम्मीद है की वो मदद करदे।


0

Cannot evaluate function -- may be inlinedजब आप अपने प्रोग्राम को संकलित करते हैं, तो यह सुनिश्चित करके कि आप अपने कंपाइलर DWARF-2 (या 3 या 4) डीबगिंग जानकारी का उपयोग करके दूसरी समस्या ( ) के आसपास पहुँच सकते हैं । DWARF-2 में इनलाइनिंग जानकारी शामिल है, इसलिए आपको अपने std::mapकंटेनर के तत्वों तक पहुंचने के लिए आपके द्वारा बताए गए तरीकों का उपयोग करने में सक्षम होना चाहिए ।

DWARF-2 डीबग जानकारी के साथ संकलित करने के लिए, -gdwarf-2अपने कंपाइल कमांड में ध्वज जोड़ें ।


1
उम, यह जानते हुए कि जहां एक फ़ंक्शन को इनलाइन किया गया है, उस फ़ंक्शन के कॉल का मूल्यांकन करने के लिए GDB के लिए संभव नहीं है; GDB को वास्तव में फ़ंक्शन की आउट-ऑफ-लाइन प्रतिलिपि तक पहुंचने की आवश्यकता है!
सामब
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.