在gdb中调试C程序时,我在for循环中有一个断点。我无法打印“i”的值(我得到:在当前上下文中没有符号“i”)。我可以打印所有其他变量的值。这是正常的吗?
这是循环:
for (i=0; i < datasize; i++){
if ( feature_mask[i] > 0 ){
k = feature_mask[i] - 1;
if (neighbors[k][nmax-1] != 0){
neighbors[k][nmax-1] = bvalue;
feature_mask[i] = -feature_mask[i];
}
}
}
答案 0 :(得分:22)
我最近遇到过这个问题。我编译了GCC 5.1,然后用它来编译C ++ 11代码库。而且,虽然我可以在gdb中单步执行程序的代码,但我无法打印任何变量的值,我在每个变量中不断获得“当前上下文中的”无符号“xyz”错误。
我使用的是gdb 7.4,但当时的最新版本是7.9。我下载了最新版本的gdb并编译了它(使用GCC 5.1),当使用gdb 7.9时,我能够再次成功检查变量值。
我猜GCC 5.1的调试信息与gdb 7.4不兼容。
答案 1 :(得分:21)
由于您只在循环中使用feature_mask[i]
,因此可能已经对已编译的代码进行了优化。
在调用编译器时是否指定了优化级别?如果您使用的是gcc,则只需省略任何-O
选项,然后重试。
答案 2 :(得分:4)
确保在没有优化的情况下编译程序,并启用调试信息。环路计数器很可能最终进入寄存器。
答案 3 :(得分:3)
您可以尝试将我声明为volatile
。这将阻止一些编译器优化(并希望在调试器中看到i
)。
答案 4 :(得分:2)
检查优化选项。 GCC可以用指向feature_mask
的指针替换变量。
答案 5 :(得分:0)
如果其他任何人在您的项目中使用Google的Bazel build system,我想补充一点,如果您无法从gdb
打印任何变量,可能是因为您需要正确添加-ggdb
和-O0
( update:use 在{{1}上使用-Og
instead of -O0
-O0
})使用-Og
选项的C构建标志,使用--copt=
选项的INSTEAD OF。就我而言,尽管它们既可以构建也可以运行,但只有--per_file_copt=
技术允许我充分使用gdb和print变量,而--copt=
技术也允许我使用gdb但不允许我使用打印变量。
注意:在下面的示例中,如果不需要同时运行单元测试,只需将--per_file_copt=
替换为test
。
UDPATE:事实证明,在进行调试时,您应该更喜欢参见此处:{{3} }。build
而不是-Og
,所以我将相应地更新这些示例。
因此,请执行以下操作:
-O0
对此:
time bazel test --copt=-ggdb --copt=-O0 \
//my/build/folder1/... //my/build/folder2/...
...以便能够在gdb中打印变量。
同样,上述技术的 两者都可以很好地构建和运行,并且都允许我运行和使用gdb,但实际上只有第一个允许我使用time bazel test --per_file_copt=//my/build/folder1/...,//my/build/folder2/...@-ggdb,-O0 \
//my/build/folder1/... //my/build/folder2/...
完全。
最后,如果上面的第一个命令仍然不起作用,请尝试添加gdb
Bazel标志What's the difference between a compiler's `-O0` option and `-Og` option?,以防止Bazel剥离调试信息。现在该命令将如下所示:
--strip=never
time bazel test --copt=-ggdb --copt=-O0 --strip=never \
//my/build/folder1/... //my/build/folder2/...
:
--copt=
:
--per_file_copt
:
--strip=never
胜过-Og
-O0
胜过-O0
:https://docs.bazel.build/versions/master/user-manual.html#flag--strip