में पैरामीटर के लिए गलत पता रिपोर्ट करता है, मुझे एक कन्स्ट्रक्टर के पैरामीटर के रूप में एक स्ट्रिंग पास करने वाले जीडीबी के साथ एक अजीब व्यवहार का अनुभव हो रहा है। कोड ठीक काम करता है, लेकिन जब मैं डीबगर में जाता हूं, तो जीडीबी लगता है कि मेरा पैरामीटर एक अलग पते पर है तो यह है। क्या किसी को पता है कि यहाँ क्या हो रहा है?जीडीबी सी ++ ऑब्जेक्ट के कन्स्ट्रक्टर
जानकारी डिबगिंग साथ--([email protected])--------------------------------------------(/home/jwcacces)--
--$ nl gdb_weird.cpp
1 #include <iostream>
2 #include <string>
3
4 class C
5 {
6 public:
7 C(std::string str)
8 {
9 std::string* str_ptr = &str;
10 std::cout << "Address of str: " << &str << std::endl;
11 std::cout << "Address in str_ptr: " << str_ptr << std::endl;
12 std::cout << "Value of str: " << str << std::endl;
13 };
14 };
15
16 int main(int, char*[])
17 {
18 std::string s("Hello, World!");
19 C c(s);
20 return 0;
21 }
संकलित, कोई अनुकूलन:
यहाँ सबसे सरल कार्यक्रम मुझे लगता है कि समस्या को दर्शाता है बना सकते हैं है।
नोट, x86, x64, और mingw (x86) के लिए संकलित होने पर मुझे यह समस्या दिखाई देती है।
मैंने अन्य आर्किटेक्चर की कोशिश नहीं की है।
--([email protected])--------------------------------------------(/home/jwcacces)--
--$ g++ -O0 -g -Wall -Wextra gdb_weird.cpp -m32
--([email protected])--------------------------------------------(/home/jwcacces)--
--$ g++ --version
g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
अब, डिबग:
--([email protected])--------------------------------------------(/home/jwcacces)--
--$ gdb a.out
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/jwcacces/a.out...done.
(gdb) br main
Breakpoint 1 at 0x80488ce: file gdb_weird.cpp, line 18.
(gdb) run
Starting program: /home/jwcacces/a.out
Breakpoint 1, main() at gdb_weird.cpp:18
18 std::string s("Hello, World!");
(gdb) next
19 C c(s);
(gdb) step
C::C (this=0xffffd74f, str=...) at gdb_weird.cpp:9
9 std::string* str_ptr = &str;
यहाँ weirdness है, जब मैं उत्पादन str
करने की कोशिश, मैं कचरा मिलती है:
(gdb) output str
{
static npos = <optimized out>,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>},
<No data fields>},
_M_p = 0xffffd748 "\024\260\004\b\364\177\354\367\360\211\004\b\364\177\354", <incomplete sequence \367>
}
}
तो, क्या GDB str
का पता लगता है करता है है?
(gdb) output &str
(std::string *) 0xffffd734
और कार्यक्रम क्या सोचते str
का पता है करता है?
(gdb) next
10 std::cout << "Address of str: " << &str << std::endl;
(gdb) next
Address of str: 0xffffd748
11 std::cout << "Address in str_ptr: " << str_ptr << std::endl;
(gdb) next
Address in str_ptr: 0xffffd748
12 std::cout << "Value of str: " << str << std::endl;
यह वास्तव में अजीब बात है, इस कार्यक्रम सोचता str
0xffffd748
पर है, लेकिन gdb, 0xffffd734
में अपनी सोचता है और जब आप उत्पादन स्ट्रिंग उद्देश्य यह है कि 0xffffd748
पर होगा इसे सही ढंग से काम करता है।
(gdb) output *(std::string*)0xffffd748
{
static npos = <optimized out>,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>},
<No data fields>
},
_M_p = 0x804b014 "Hello, World!"
}
}
और कार्यक्रम में ही पैरामीटर का उपयोग कर कोई समस्या नहीं एच एस:
(gdb) next
Value of str: Hello, World!
13 };
(gdb) continue
Continuing.
[Inferior 1 (process 19463) exited normally]
(gdb) quit
मैं एक पूर्णांक, एक struct, एक सूचक को निर्माता पैरामीटर के प्रकार को बदलने की कोशिश की है, लेकिन मैं पुन: पेश नहीं कर सकते अजीबता
इसके अलावा, मैंने डिबगिंग प्रारूप को -ggdb पर सेट करने का प्रयास किया है।
सवाल:
- यहाँ क्या हो रहा है?
- जीडीबी क्यों कहता है कि
std::string
काnpos
सदस्य ऑप्टिमाइज़ किया गया है (लाइब्रेरी से ऑप्टिमाइज़ किया गया हो सकता है), और क्या इसका इसके साथ कुछ लेना देना है? - क्या यह एक संयोग है कि "ऑब्जेक्ट" में जहां जीडीबी
str
सोचता है,_M_p
सदस्य अंक0xffffd748
पर है, जो पताstr
वास्तव में स्थित है? - इस व्यवहार के साथ अन्य परिस्थितियों में क्या होता है?
---- ओह, निर्णायक ----
अगर मैं -gstabs + करने के लिए डिबगिंग प्रारूप निर्धारित करते हैं, GDB str
सही का पता हो जाता है।
क्या इसका मतलब यह है कि जीडीबी डीबगिंग प्रारूप सही ढंग से काम नहीं करता है?
मेरे लिए क्या चिपक जाता है यह है कि आपका "सही" सूचक 0xffffd748 आपके पहले प्रिंट स्टेटमेंट से "अवैध" स्ट्रिंग के '_M_p' सदस्य के रूप में भी दिखाई देता है। तो शायद gdb एक पॉइंटर-टू-और पॉइंटर-टू-पॉइंटर-टू-बीच के बीच उलझन में है? बीटीडब्लू मैं बस इतना कहता हूं कि "यही कारण है कि आपको स्ट्रिंग्स को कॉन्स्ट-रेफ्स के रूप में पास करना चाहिए" उचित उत्तर नहीं है: पी – araqnid
स्ट्रिंग नियमित पैरामीटर (मान द्वारा योग्यता प्राप्त पास) के रूप में ठीक से गुजरती है, यह सिर्फ जीडीबी है जिसमें समस्या है इसके साथ। और हाँ, _M_p पॉइंटर वास्तव में मेरे लिए अजीब है। –
यह std :: स्ट्रिंग के साथ फ़ंक्शन तर्क होने के साथ कुछ करना चाहिए - यदि आप सी :: सी() के अंदर किसी अन्य std :: स्ट्रिंग चर को स्ट्रेट करते हैं और फिर उस दूसरे चर को gdb में जांचें तो यह ठीक दिखता है, यहां तक कि ठीक है हालांकि समारोह तर्क gdb के लिए जंक प्रतीत होता है। –