gcc 计算GDB和LLDB中的表达式

lymgl2op  于 2023-08-06  发布在  其他
关注(0)|答案(2)|浏览(173)

我正试图理解GDB和LLDB,以便我可以在任何时候有效地使用它来调试我的程序。
但我似乎被卡住了:我不知道如何打印像powstrnlen等C库函数的输出。如果我想探索他们的输出。
以下是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)


我已经编译了程序使用
gcc -g3 pow. c-o pow

pu3pd22g

pu3pd22g1#

您从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上,系统为大多数系统库提供了“模块Map”,允许lldb从模块中重建类型。要告诉lldb在调试纯C程序时加载模块,请运行以下命令:

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


如果你正在调试一个ObjC程序,你可以不考虑语言规范。在这个表达式运行之后,lldb将加载模块Map,您可以调用标准C库中的大多数函数而无需强制转换。

alen0pnh

alen0pnh2#

如果你看一下反汇编,你会发现它只包含原始的结果值,没有调用pow函数。gcc知道pow是什么,并在编译期间计算它。不需要与libm链接,它包含给定函数的实现=>运行时没有函数,因此调试器没有任何东西可调用。
您可以通过以下方式强制链接:添加-lm(但可以用--as-needed链接器标志覆盖)。

相关问题