评估gdb和lldb中的表达式

时间:2017-02-28 03:56:52

标签: gcc gdb lldb

我试图了解GDB和LLDB,以便我可以随时有效地使用它来调试我的程序。

但似乎我已经陷入困境我不知道如何打印C库函数的输出,如powstrnlen等。如果我想在那里探索输出

以下是LLDB和GDB输出。

   3    int main(int argc,char *argv[]) {
   4       int a = pow(3,2);
-> 5       printf("the value of a is %d",a);
   6       return 0;
   7    }
(lldb) print pow(3,1)
warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.
error: 'pow' has unknown return type; cast the call to its declared return type
(lldb) print strlen("abc")
warning: could not load any Objective-C class information. This will significantly reduce the quality of type information available.
error: 'strlen' has unknown return type; cast the call to its declared return type
(lldb) expr int a = strlen("abc");
error: 'strlen' has unknown return type; cast the call to its declared return type
(lldb) expr int a = strlen("abc");

GDB输出

Starting program: /Users/noobie/workspaces/myWork/pow 
[New Thread 0x1903 of process 35243]
warning: unhandled dyld version (15)

Thread 2 hit Breakpoint 1, main (argc=1, argv=0x7fff5fbffb10) at pow.c:5
5      int a = pow(3,2);
(gdb) print pow(3,2)
No symbol "pow" in current context.
(gdb) set pow(3,2)
No symbol "pow" in current context.
(gdb) set pow(3,2);
No symbol "pow" in current context.
(gdb) print pow(3,2);
No symbol "pow" in current context.
(gdb) call pow(3,2)
No symbol "pow" in current context.
(gdb) 

我使用带有-g3标志的gcc编译了程序

  

gcc -g3 pow.c -o pow

2 个答案:

答案 0 :(得分:4)

你从lldb得到的错误,例如:

error: 'strlen' has unknown return type; cast the call to its declared return type

正如它所说的那样。您需要将调用转换为正确的返回类型:

(lldb) print (size_t) strlen("abc")
(size_t) $0 = 3

strlenprintf等缺少类型信息的原因是为了节省空间,编译器只在看到函数的定义时才将函数的签名写入调试信息中,而不是在每个使用网站。由于您没有标准C库的调试信息,因此您没有此信息。

调试器在调用函数之前需要此信息的原因是,如果调用返回结构的函数,但生成代码就好像函数返回标量值一样,调用函数会破坏线程的堆栈在其上调用函数,破坏了调试会话。所以lldb没有猜到这一点。

注意,在macOS上,系统具有大多数系统库的“模块映射”,这允许lldb从模块重建类型。要在调试纯C程序时告诉lldb加载模块,请运行以下命令:

(lldb) expr -l objective-c -- @import Darwin

如果您正在调试ObjC程序,则可以不使用语言规范。运行此表达式后,lldb将加载模块映射,您可以调用标准C库中的大多数函数而不进行转换。

答案 1 :(得分:0)

如果您查看反汇编,您会看到它只包含原始结果值而不调用pow函数。 gcc知道pow是什么,并在编译期间计算它。无需与包含给定函数=>的实现的libm链接运行时没有函数,因此调试器没有任何东西可以调用。

你可以通过例如强制链接添加-lm(可以用--as-needed链接器标记覆盖。)