首页 文章

使用lldb打印变量的内容

提问于
浏览
3

好吧,所以这听起来像是一个愚蠢的问题,但我被困住了:我在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 )"(包v . :"3.4~svn183914-1ubuntu1")

  • gcc:"gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1"(包装版:"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进行调试:有效

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

3 回答

  • 1

    使用 gcc 4.8.1lldb-3.4 时,这似乎是一个特定的问题

    使用 gcc-4.8.2gcc-4.7.3 工作正常 .

  • 0

    调查行为的最佳方法是're seeing is to look at the debug info. On a Mac OS X system, you'在 .dSYM 包或 .o 文件上运行dwarfdump(如果您没有创建dSYM) . 调试信息具有从编译器到调试器的关于在何处查找变量的指令 .

    在实时进程中,使用lldb,您可以让lldb显示所有局部变量的存储位置(以DWARF位置表达式语言表示),其中包含 image lookup -v -a $pc (或简称 im loo -va $pc ) .

    如果有's a program where gdb can' t打印变量并且lldb在同一个pc地址不能,那听起来好像它可能是一个lldb bug . 调试信息是最终的事实(就调试器而言)关于存储变量的位置以及它们的长度"live" . 在优化的代码中,它们可能适用于函数的非常短的部分 .

    从黑客的角度来看,真正的真相来源是阅读汇编代码 . 通常情况下,在优化过程中,编译器不会跟踪变量的位置 - 它可能会说某个变量在给定的pc地址不可用,但如果你仔细阅读了程序集,你可能会发现仍然保存在堆栈上的最后一个值的副本等 .

  • 2

    这段代码非常简单我敢打赌llvm完全删除了这些变量 . 尝试编译并禁用优化(-O0)并查看是否有帮助 . 除此之外,使用指针或做一些更复杂的事情,因此编译器不会删除数学并用预先计算的值替换它 .

相关问题