gdb调试任意函数

使用gdb调试时,有的函数只在某些路径上会执行到,而触发这些路径执行的条件构造起来比较麻烦,比如某个server在接收到READ请求时,会调用do_read进行响应,这时如果我们想调试do_read函数,就必须在客户端构造一个READ请求来触发。

int do_read(const ReadRequest& req); 

假设我们知道do_read调用时参数ReadRequest的具体内容,能否直接使用gdb显式的调试do_read,且看下面这个例子。

main函数里没有显式调用get_capacity函数,如果我们想要调试这个函数,最直观的一种方式,当然是将get_capacity加到main里,让其出现在调用路径中即可调试。

gdb的jump可以让程序跳转到任意位置执行,实验了一下,结果是跳转到get_capacity里开始执行时,出现Segmentation fault,因为参数Box的空间没有分配。在了解参数传递顺序及栈布局的情况下,可通过一些出栈、入栈操作,在jump到get_capacity前将参数先准备好,这样get_capacity调用时,就不会有问题,但这样做太过复杂。

struct Box {
  int length;
  int width;
  int height;
};

int get_capacity(const struct Box& box)
{
  int capacity = box.length * box.width * box.height;
  printf("box capacity: %d\n", capacity);
  return capacity;
} 


int main()
{
  printf("main called no functions\n");
  return 0;
} 

gdb的call可以在调试时显式调用函数,需要先把参数准备好。如下所示,在main里设置断点,然后分配出一个box的内存,并对box进行赋值,最后将其最为参数传递给get_capacity函数,get_capacity函数被正确的调用,通过在get_capacity设置断点即可对它进行调试。

(gdb) set $box = (Box*)malloc(sizeof(Box))
(gdb) set $box->length = 3
(gdb) set $box->width = 4
(gdb) set $box->height = 5
(gdb) call get_capacity(*$box)
box capacity: 60
$1 = 60 

针对上面这种方式,存在两个疑问,求达人解惑。

直接使用box对象而不是指针时,传递时有问题,如下:

(gdb) set $box = *(Box*)malloc(sizeof(Box))
(gdb) call get_capacity($box)
Attempt to take address of value not located in memory. 

不能直接使用new来构造对象,对于复杂的类(尤其是拥有虚函数的情况),上面的方式没办法工作。

(gdb) set $box = new Box()
A syntax error in expression, near `new Box()'.


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用GDB调试程序的基本流程如下: 1. 编译程序时需要加上-g选项,以便在程序中添加调试信息。 2. 启动GDB调试器,可以通过以下命令启动: ``` $ gdb <executable> ``` 其中,`<executable>`是要调试的可执行文件。 3. 设置断点,可以使用以下命令在代码中设置断点: ``` (gdb) break <line> ``` 其中,`<line>`是要设置断点的行号或函数名。 4. 运行程序,可以使用以下命令运行程序: ``` (gdb) run <args> ``` 其中,`<args>`是程序的命令行参数。 5. 当程序运行到断点处时,GDB会停止程序的执行,并等待用户输入命令。 6. 在程序停止时,可以使用以下命令查看程序的状态: ``` (gdb) info <args> ``` 其中,`<args>`可以是以下任意一个选项: - `info locals`:查看本地变量。 - `info breakpoints`:查看已设置的断点。 - `info threads`:查看正在运行的线程。 7. 恢复程序的执行,可以使用以下命令: ``` (gdb) continue ``` 8. 在程序执行过程中,可以使用以下命令单步执行程序: ``` (gdb) step ``` 或者使用以下命令跳过函数调用: ``` (gdb) next ``` 9. 在程序执行过程中,可以使用以下命令查看变量的值: ``` (gdb) print <var> ``` 其中,`<var>`是要查看的变量名。 10. 在调试完成后,可以使用以下命令退出GDB: ``` (gdb) quit ``` 这只是GDB调试的基本流程,GDB还有许多其他的命令和选项,可以根据需要自行学习。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值