我遇到了一个奇怪的行为,GDB将一个字符串作为参数传递给构造函数。 代码工作正常,但是当我在调试器中单步执行时,GDB似乎认为我的参数位于不同的地址。有谁知道这里发生了什么?
这是我可以创建的最简单的程序来演示问题:
--(jwcacces@neptune)--------------------------------------------(/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)编译时看到了这个问题 我还没有尝试过其他架构。
--(jwcacces@neptune)--------------------------------------------(/home/jwcacces)--
--$ g++ -O0 -g -Wall -Wextra gdb_weird.cpp -m32
--(jwcacces@neptune)--------------------------------------------(/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.
现在,调试:
--(jwcacces@neptune)--------------------------------------------(/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;
这是奇怪的,当我尝试输出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
我尝试将构造函数参数的类型更改为int,struct,指针,但我无法重现这种怪异。
另外,我尝试将调试格式设置为-ggdb。
问题:
std::string
的{{1}}成员已经过优化(可能是从库中优化出来的),这与它有什么关系吗?npos
所在的“对象”中,str
成员指向_M_p
,0xffffd748
的地址实际上位于? ---- WOAH,突破----
如果我将调试格式设置为-gstabs +,则GDB会将str
的地址设置为正确
这是否意味着gdb调试格式无法正常工作?
答案 0 :(得分:0)
在任何帖子(https://gcc.gnu.org/ml/gcc/2001-04/msg01037.html)中,调试C ++时,似乎-gstabs或-gstabs +是正确的标志。我希望这可以提供帮助。