评估 gdb 和 lldb 中的表达式
Evaluate an expression in gdb and lldb
我正在尝试了解 GDB 和 LLDB,以便我可以随时有效地使用它来调试我的程序。
但我似乎被卡住了,我不确定如何打印 C 库函数的输出,如 pow
、strnlen
等。如果我想探索那里的输出。
以下为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
如果您查看反汇编,您会发现它只包含未调用 pow
函数的原始结果值。 gcc 知道 pow
是什么,并在编译期间计算它。不需要 link 和 libm
包含给定函数的实现 => 运行时不存在任何函数,因此调试器没有任何可调用的东西。
您可以通过例如强制 link添加 -lm
(不过可以用 --as-needed
linker 标志覆盖)。
您从 lldb 得到的错误,例如:
error: 'strlen' has unknown return type; cast the call to its declared return type
正如其名。您需要将调用转换为正确的 return 类型:
(lldb) print (size_t) strlen("abc")
(size_t) [=11=] = 3
strlen
和printf
等缺少类型信息的原因是为了保存space,编译器只在调试时将函数的签名写入调试信息看到功能的定义,而不是在每个使用站点。由于您没有标准 C 库的调试信息,因此您没有此信息。
调试器在调用函数之前需要此信息的原因是,如果您调用一个 return 结构的函数,但生成代码就像函数 returned 一个标量值一样,调用该函数将破坏调用该函数的线程的堆栈,从而破坏您的调试会话。所以 lldb 不会猜测这个。
注意,在 macOS 上,系统为大多数系统库提供了 "module maps",这允许 lldb 从模块中重建类型。要告诉 lldb 在调试纯 C 程序时加载模块,运行 这个命令:
(lldb) expr -l objective-c -- @import Darwin
如果您正在调试 ObjC 程序,则可以省略语言规范。在这个表达式 运行s 之后,lldb 将加载模块映射,您可以调用标准 C 库中的大部分函数而无需强制转换。
我正在尝试了解 GDB 和 LLDB,以便我可以随时有效地使用它来调试我的程序。
但我似乎被卡住了,我不确定如何打印 C 库函数的输出,如 pow
、strnlen
等。如果我想探索那里的输出。
以下为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
如果您查看反汇编,您会发现它只包含未调用 pow
函数的原始结果值。 gcc 知道 pow
是什么,并在编译期间计算它。不需要 link 和 libm
包含给定函数的实现 => 运行时不存在任何函数,因此调试器没有任何可调用的东西。
您可以通过例如强制 link添加 -lm
(不过可以用 --as-needed
linker 标志覆盖)。
您从 lldb 得到的错误,例如:
error: 'strlen' has unknown return type; cast the call to its declared return type
正如其名。您需要将调用转换为正确的 return 类型:
(lldb) print (size_t) strlen("abc")
(size_t) [=11=] = 3
strlen
和printf
等缺少类型信息的原因是为了保存space,编译器只在调试时将函数的签名写入调试信息看到功能的定义,而不是在每个使用站点。由于您没有标准 C 库的调试信息,因此您没有此信息。
调试器在调用函数之前需要此信息的原因是,如果您调用一个 return 结构的函数,但生成代码就像函数 returned 一个标量值一样,调用该函数将破坏调用该函数的线程的堆栈,从而破坏您的调试会话。所以 lldb 不会猜测这个。
注意,在 macOS 上,系统为大多数系统库提供了 "module maps",这允许 lldb 从模块中重建类型。要告诉 lldb 在调试纯 C 程序时加载模块,运行 这个命令:
(lldb) expr -l objective-c -- @import Darwin
如果您正在调试 ObjC 程序,则可以省略语言规范。在这个表达式 运行s 之后,lldb 将加载模块映射,您可以调用标准 C 库中的大部分函数而无需强制转换。