2012-01-24 16 views
6

में पैरामीटर के लिए गलत पता रिपोर्ट करता है, मुझे एक कन्स्ट्रक्टर के पैरामीटर के रूप में एक स्ट्रिंग पास करने वाले जीडीबी के साथ एक अजीब व्यवहार का अनुभव हो रहा है। कोड ठीक काम करता है, लेकिन जब मैं डीबगर में जाता हूं, तो जीडीबी लगता है कि मेरा पैरामीटर एक अलग पते पर है तो यह है। क्या किसी को पता है कि यहाँ क्या हो रहा है?जीडीबी सी ++ ऑब्जेक्ट के कन्स्ट्रक्टर

जानकारी डिबगिंग साथ
--([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; 

यह वास्तव में अजीब बात है, इस कार्यक्रम सोचता str0xffffd748 पर है, लेकिन 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 सही का पता हो जाता है।
क्या इसका मतलब यह है कि जीडीबी डीबगिंग प्रारूप सही ढंग से काम नहीं करता है?

+0

मेरे लिए क्या चिपक जाता है यह है कि आपका "सही" सूचक 0xffffd748 आपके पहले प्रिंट स्टेटमेंट से "अवैध" स्ट्रिंग के '_M_p' सदस्य के रूप में भी दिखाई देता है। तो शायद gdb एक पॉइंटर-टू-और पॉइंटर-टू-पॉइंटर-टू-बीच के बीच उलझन में है? बीटीडब्लू मैं बस इतना कहता हूं कि "यही कारण है कि आपको स्ट्रिंग्स को कॉन्स्ट-रेफ्स के रूप में पास करना चाहिए" उचित उत्तर नहीं है: पी – araqnid

+0

स्ट्रिंग नियमित पैरामीटर (मान द्वारा योग्यता प्राप्त पास) के रूप में ठीक से गुजरती है, यह सिर्फ जीडीबी है जिसमें समस्या है इसके साथ। और हाँ, _M_p पॉइंटर वास्तव में मेरे लिए अजीब है। –

+0

यह std :: स्ट्रिंग के साथ फ़ंक्शन तर्क होने के साथ कुछ करना चाहिए - यदि आप सी :: सी() के अंदर किसी अन्य std :: स्ट्रिंग चर को स्ट्रेट करते हैं और फिर उस दूसरे चर को gdb में जांचें तो यह ठीक दिखता है, यहां तक ​​कि ठीक है हालांकि समारोह तर्क gdb के लिए जंक प्रतीत होता है। –

उत्तर

0

किसी भी पोस्ट से (https://gcc.gnu.org/ml/gcc/2001-04/msg01037.html) ऐसा लगता है कि -स्टाब्स या -स्टाब्स + सी ++ डीबग करते समय सही झंडे हैं। मुझे उम्मीद है कि यह मदद कर सकता है।