最近升级到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
$1 = {i = {0, 1045149306}, d = 1.2904777690891933e-08} ## I have no idea what this means
(gdb) print b
$2 = {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导致此问题的任何想法吗?
答案 0 :(得分:1)
这里的特殊问题是调试信息中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
在调试信息中节省了一些空间。
旧版本的GDB只识别第一个版本,并以不能包含此范围内任何变量的方式解释第二个版本。
可能的解决方案是使用-gdwarf-2进行编译或升级GDB。
答案 1 :(得分:0)
gdb和gcc在调试格式方面需要兼容版本(并且它们在许多版本中通常兼容性很好,但SOMETIMES兼容性从一个版本的编译器到另一个版本都被破坏了)。
我遇到了完全相同的问题。解决方案是在gcc上抛出一些标志,用#34;旧式调试格式&#34;进行编译,或者将gdb的版本升级为&#34;工作的#34;使用较新版本的gcc。
给出的调试格式如果gdb实际上说的是&#34;你的调试格式是X,你需要调试格式Y或Z才能使gdb正常工作&#34;这将是NICE,但我不是100%肯定可以可靠地确定(例如,在修复的代中发现错误,并且需要调试器中的相应修复,因为同样的错误出现在&#34;产生&#34;和#34;消耗& #34;调试符号处理程序的一部分 - 所以一个较旧的,错误的版本无法读取较新的unbuggy格式,反之亦然)