使用lldb打印变量的内容

时间:2014-06-16 16:17:53

标签: c debugging lldb

好吧,所以这听起来像是一个愚蠢的问题,但我陷入困境:在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

返回完全相同的错误消息。

我错过了什么吗?非常感谢任何帮助。

我的设置:

  • lldb:“lldb version 3.4(revision)”(package v。:“3.4~svn183914-1ubuntu1”)
  • gcc:“gcc(Ubuntu / Linaro 4.8.1-10ubuntu9)4.8.1”(包v。:“4.8.1-2ubuntu3”)
  • (我的存储库是默认情况下linux mint 16提供的存储库)

@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:最后,我发现了一些有趣的事情:

  • 使用gcc编译[-g -O0]然后使用gdb进行调试:工作
  • 使用gcc [-g -O0]进行编译,然后使用lldb进行调试:不起作用
  • 使用clang [-g -O0]进行编译,然后使用gdb进行调试:
  • 使用clang [-g -O0]进行编译,然后使用lldb:works
  • 进行调试

edit1:回复@SeanPerry edit2:区分软件版本和软件包版本

3 个答案:

答案 0 :(得分:2)

使用gcc 4.8.1lldb-3.4

时,这似乎是一个特定问题

使用gcc-4.8.2gcc-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)并查看是否有帮助。除此之外,使用指针或执行更复杂的操作,以便编译器不会删除数学并将其替换为预先计算的值。