好吧,所以这听起来像是一个愚蠢的问题,但我陷入困境:在lldb调试会话期间我无法读取变量的值(使用gdb可以正常工作)。
我找到了其他人遇到过与我相同的错误消息的帖子,但区别在于我甚至无法弄清楚如何打印出最简单形式的变量值。
为了更好地表达我的问题,我将在这里考虑一个非常简单的例子。我们有一个文件“main.c”,其中包含以下代码:
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int a = 1;
int b = 2;
int c = 0;
c = a + b;
c = c*b;
printf("c = %d\n", c);
return 0;
}
我使用以下方法编译它:
user@machine ~ $ gcc -g main.c
一个名为的二进制文件 “的a.out” 生成
然后ivoque lldb:
user@machine ~ $ lldb-3.4 ./a.out
我想在第9行停下来并读取c的值。因此,我首先添加一个断点:
(lldb) breakpoint set -f main.c -l 9
然后我运行代码:
(lldb) run
到目前为止,每件事都按预期进行。现在是棘手的部分:我想读取变量c的值。因此,我写道:
(lldb) print c
lldb回报我:
error: use of undeclared identifier 'c'
error: 1 errors parsing expression
当然:
(lldb) expression c
返回完全相同的错误消息。
我错过了什么吗?非常感谢任何帮助。
我的设置:
@Sean Perry回答后的更多信息:
1:似乎附加选项-O0不会改变调试器的行为。
2:我还尝试使用以下虚拟代码而不是之前的代码
#include <stdlib.h>
#include <stdio.h>
int main(void) {
long a = 1;
long b = 2;
long c = 0;
c = a + b;
c += (long) &c;
printf("c = %ld\n", c);
return 0;
}
我不确定@Sean Perry的意思是“使用指针”,但我认为它必须阻止代码优化,因为变量c的地址(或多或少)随机地改变二进制文件的每次运行。
3:最后,我发现了一些有趣的事情:
edit1:回复@SeanPerry edit2:区分软件版本和软件包版本
答案 0 :(得分:2)
使用gcc 4.8.1
和lldb-3.4
使用gcc-4.8.2
和gcc-4.7.3
可以正常使用。
答案 1 :(得分:1)
调查您所看到的行为的最佳方法是查看调试信息。在Mac OS X系统上,如果您没有创建dSYM,则在.dSYM
包或.o
文件上运行dwarfdump。调试信息包含从编译器到调试器的有关在何处查找变量的指令。
在实时流程中,使用lldb,您可以让lldb显示存储所有局部变量的位置(以DWARF位置表达式语言表示)image lookup -v -a $pc
(或简称为im loo -va $pc
)。
如果有一个程序,其中gdb无法打印变量而lldb 在同一个pc地址不能,那听起来好像它可能是一个lldb错误。调试信息是关于变量存储位置和“实时”存储时间的最终事实(就调试器而言)。在优化的代码中,它们可能适用于函数的非常短的部分。
从黑客的角度来看,真正的真相来源是阅读汇编代码。通常情况下,在优化过程中,编译器不会跟踪变量的位置 - 它可能说变量在给定的pc地址不可用,但是如果你读取了汇编足够紧密,您可能会找到仍保存在堆栈上的最后一个值的副本&amp;这样
答案 2 :(得分:0)
这段代码非常简单我敢打赌llvm完全删除了变量。尝试编译并禁用优化(-O0)并查看是否有帮助。除此之外,使用指针或执行更复杂的操作,以便编译器不会删除数学并将其替换为预先计算的值。