Я испытываю странное поведение, когда 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, структуру, указатель, но я не могу воспроизвести странность.
Кроме того, я попытался установить формат отладки на -ggdb.
Вопросы:
npos
std :: string
оптимизирован (возможно, оптимизирован вне библиотеки) ), и имеет ли это какое-либо отношение к этому? str
, член _M_p
указывает на 0xffffd748
, адрес, по которому на самом деле находится str
? ---- WOAH, Прорыв --- -
Если я установил формат отладки на -gstabs +, GDB правильно получит адрес str
.
Означает ли это, что формат отладки gdb работает некорректно?