g++4.8 对 gdb 隐藏变量
g++4.8 hides variables from gdb
最近升级到 g++ 4.8.1 后,我发现在 gdb 中调试是完全不可能的。 g++ 似乎隐藏了 gdb 中的所有变量,无论优化选项如何。在接下来的会话中,runner.cpp如下:
#include <vector>
using namespace std;
int main(void) {
vector<int> arr;
int a = 3;
int b = 2;
b = a + 3;
arr.push_back(1);
arr.push_back(2);
arr.push_back(3);
arr.push_back(4);
return 0;
}
这是结果:
Script started on Tue 14 Jul 2015 01:11:14 PM PDT
me@ministation:~/Development/clib$ g++ -g -O0 runner.cpp
me@ministation:~/Development/clib$ gdb -q ./a.out
Reading symbols from /home/me/Development/clib/a.out...done.
(gdb) break 11
Breakpoint 1 at 0x40095c: file runner.cpp, line 11.
(gdb) run
Starting program: /home/me/Development/clib/a.out
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
Breakpoint 1, main () at runner.cpp:11
11 arr.push_back(1);
(gdb) print a
= {i = {0, 1045149306}, d = 1.2904777690891933e-08} ## I have no idea what this means
(gdb) print b
= {i = {0, 1068498944}, d = 0.0625}
(gdb) print arr
No symbol "arr" in current context.
(gdb) info locals
No locals.
(gdb) next
12 arr.push_back(2);
(gdb)
13 arr.push_back(3);
(gdb) print arr
No symbol "arr" in current context.
(gdb) next
14 arr.push_back(4);
(gdb)
16 return 0;
(gdb) print arr
No symbol "arr" in current context.
(gdb) q
A debugging session is active.
Inferior 1 [process 6392] will be killed.
Quit anyway? (y or n) y
me@ministation:~/Development/clib$
Script done on Tue 14 Jul 2015 01:12:05 PM PDT
我看过一些类似的帖子,其中推荐了 -O0 标志,但它似乎在这里不起作用。使用 g++4.6 编译后完全相同的会话会产生预期的结果。关于 g++4.8 造成这种情况的原因有什么想法吗?
当谈到调试格式时,gdb 和 gcc 需要是兼容的版本(它们通常在许多版本上都很好地兼容,但有时兼容性会从一个编译器版本到另一个版本)。
我遇到了完全相同的问题。解决方案是要么在 gcc 上抛出一些标志以使用 "older style debug format" 进行编译,要么将 gdb 的版本升级到 "works" 具有较新版本 gcc 给出的调试格式的版本。
如果 gdb 真的说了 "Your debug format is X, you need debug format Y or Z for gdb to work correctly" 之类的话就好了,但我不能 100% 确定可以可靠地确定(例如,当在已修复的一代中发现错误时,并且需要在调试器中进行相应的修复,因为相同的错误出现在调试符号处理程序的 "produce" 和 "consume" 部分 - 所以旧的,有错误的版本无法读取较新的无错误格式和反之亦然)
这里的特殊问题是调试信息中 DW_AT_high_pc 标记的含义已扩展为也表示偏移量。
最初,从 0x804dd8e 到 0x804ddae 的函数被编码为
DW_AT_low_pc : 0x804dd8e
DW_AT_high_pc : 0x804ddae
现在也可以编码为
DW_AT_low_pc : 0x804dd8e
DW_AT_high_pc : 0x20
这在调试信息中节省了一点 space。
旧版本的 GDB 只识别第一个版本,并以在此范围内不能有任何变量的方式解释第二个版本。
可能的解决方案是使用 -gdwarf-2 进行编译或升级 GDB。
最近升级到 g++ 4.8.1 后,我发现在 gdb 中调试是完全不可能的。 g++ 似乎隐藏了 gdb 中的所有变量,无论优化选项如何。在接下来的会话中,runner.cpp如下:
#include <vector>
using namespace std;
int main(void) {
vector<int> arr;
int a = 3;
int b = 2;
b = a + 3;
arr.push_back(1);
arr.push_back(2);
arr.push_back(3);
arr.push_back(4);
return 0;
}
这是结果:
Script started on Tue 14 Jul 2015 01:11:14 PM PDT
me@ministation:~/Development/clib$ g++ -g -O0 runner.cpp
me@ministation:~/Development/clib$ gdb -q ./a.out
Reading symbols from /home/me/Development/clib/a.out...done.
(gdb) break 11
Breakpoint 1 at 0x40095c: file runner.cpp, line 11.
(gdb) run
Starting program: /home/me/Development/clib/a.out
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
Breakpoint 1, main () at runner.cpp:11
11 arr.push_back(1);
(gdb) print a
= {i = {0, 1045149306}, d = 1.2904777690891933e-08} ## I have no idea what this means
(gdb) print b
= {i = {0, 1068498944}, d = 0.0625}
(gdb) print arr
No symbol "arr" in current context.
(gdb) info locals
No locals.
(gdb) next
12 arr.push_back(2);
(gdb)
13 arr.push_back(3);
(gdb) print arr
No symbol "arr" in current context.
(gdb) next
14 arr.push_back(4);
(gdb)
16 return 0;
(gdb) print arr
No symbol "arr" in current context.
(gdb) q
A debugging session is active.
Inferior 1 [process 6392] will be killed.
Quit anyway? (y or n) y
me@ministation:~/Development/clib$
Script done on Tue 14 Jul 2015 01:12:05 PM PDT
我看过一些类似的帖子,其中推荐了 -O0 标志,但它似乎在这里不起作用。使用 g++4.6 编译后完全相同的会话会产生预期的结果。关于 g++4.8 造成这种情况的原因有什么想法吗?
当谈到调试格式时,gdb 和 gcc 需要是兼容的版本(它们通常在许多版本上都很好地兼容,但有时兼容性会从一个编译器版本到另一个版本)。
我遇到了完全相同的问题。解决方案是要么在 gcc 上抛出一些标志以使用 "older style debug format" 进行编译,要么将 gdb 的版本升级到 "works" 具有较新版本 gcc 给出的调试格式的版本。
如果 gdb 真的说了 "Your debug format is X, you need debug format Y or Z for gdb to work correctly" 之类的话就好了,但我不能 100% 确定可以可靠地确定(例如,当在已修复的一代中发现错误时,并且需要在调试器中进行相应的修复,因为相同的错误出现在调试符号处理程序的 "produce" 和 "consume" 部分 - 所以旧的,有错误的版本无法读取较新的无错误格式和反之亦然)
这里的特殊问题是调试信息中 DW_AT_high_pc 标记的含义已扩展为也表示偏移量。
最初,从 0x804dd8e 到 0x804ddae 的函数被编码为
DW_AT_low_pc : 0x804dd8e
DW_AT_high_pc : 0x804ddae
现在也可以编码为
DW_AT_low_pc : 0x804dd8e
DW_AT_high_pc : 0x20
这在调试信息中节省了一点 space。
旧版本的 GDB 只识别第一个版本,并以在此范围内不能有任何变量的方式解释第二个版本。
可能的解决方案是使用 -gdwarf-2 进行编译或升级 GDB。