当前位置:   article > 正文

GDB调试的基本使用、GDB调试多进程_gdb启动程序

gdb启动程序

1. 编译时加选项-g,生成具有调试信息的程序

gcc -g test.c -o test

2. 启动GDB

(1)启动GDB:

gdb test

(2)设置运行时参数:(主函数中可接收运行时参数)

  1. set args // 设置运行时参数,如set args 10 20 30
  2. show args // 查看设置的运行时参数

(3)启动程序

  1. run // 执行程序,若有断点,则停在第一个断点处;简写为r
  2. start // 程序向下执行一行
  3. continue // 执行到第一个断点处

3. 显示源码

  1. list 或 l // 显示当前行后面的源代码(默认总共显示10行)
  2. list- // 显示当前行前面的源代码(默认总共显示10行)
  3. list n // 显示第n行前后的源代码
  4. list func // 显示func函数的源代码
  5. set listsize n // 设置一次显示n行
  6. show listsize // 查看一次显示行数

4. 断点操作

(1)简单断点:使用b或break命令

  1. b n // 在第n行设置断点
  2. b func // 在func函数入口处设置断点
  3. info b // 显示所有断点,可简写为 i b

(2)多文件断点,假设程序有add.cpp和test.cpp两个文件

  1. b add.cpp:n // 在add.cpp源文件第n行设置断点
  2. b add.cpp:func // 在add.cpp源文件func函数入口处设置断点
  3. b Animal::func // 在Animal类的func函数入口处设置断点
  4. b Animal::doSth(int, double) // 有函数重载时,必须指定函数形参的情况
  5. b MyNamespace::Animal::func // 在NyNamespace的Animal类的func函数入口处设置断点

(3)条件断点:为断点设置条件

  1. b test.c:8 if Value == 5
  2. // test.c第8行,Value为5时就停止
  3. // 若为循环,不能停在for语句,要停在循环体中

 (4)维护断点

  1. delete 10-12 // 删除编号为10、11、12的断点,delete可以简写为d
  2. disable n //禁用编号为n的断点
  3. enable n //启用编号为n的断点

5. 调试程序

  1. run // 执行程序,若有断点,则停在第一个断点处,简写为r
  2. next // 单步跟踪。函数调用当做一条语句直接执行,简写为n
  3. step // 单步跟踪。函数调用则进入函数体内,简写为s
  4. finish // 退出进入的函数
  5. until // 在循环体内单步跟踪时,执行完循环体并退出,简写为c
  6. continue // 继续执行程序,停在下一个断点处
  7. quit // 退出gdb,简写为q

6. 查看数据

查看运行时变量、字符串、表达式等的值:

print a  // 查看a的值,print可简写为p

7. 自动查看

自己设置需要查看的值,程序停住或单步跟踪时,会自动显示需要查看的值:

  1. display i // 设置自动显示i的值
  2. info display // 查看所有被设置为display的变量
  3. undisplay n // 不显示编号为n的display设置
  4. delete display n // 删除编号为n的display设置
  5. disable display n // 禁用编号为n的display设置
  6. enable display n // 启用编号为n的display设置

8. 查看修改变量的类型、值

  1. ptype i // 查看变量i的类型
  2. p i // 查看变量i的值
  3. set var i = 100 // 设置变量i的值为100

 9. GDB调试多进程

 有如下的多进程程序,需要使用GDB分别调试父子进程:

  1. #include<stdio.h>
  2. #include<unistd.h>
  3. #include<sys/types.h>
  4. #include<sys/wait.h>
  5. #include<stdlib.h>
  6. int main(int argc, const char* argv[]) {
  7. pid_t pid = -1;
  8. int status = 0;
  9. int ret = -1;
  10. pid = fork();
  11. if (-1 == pid) {
  12. perror("fork");
  13. return 1;
  14. }
  15. if (pid > 0) {
  16. // 父进程
  17. printf("父进程说太强了");
  18. printf("父进程笑尿了");
  19. printf("父进程哈哈哈哈哈");
  20. } else {
  21. // 子进程
  22. printf("子进程说太强了");
  23. printf("子进程笑尿了");
  24. printf("子进程哈哈哈哈哈");
  25. exit(0);
  26. }
  27. ret = wait(&status); // 父进程等待回收子进程资源
  28. if(-1 == ret) {
  29. perror("wait");
  30. return 1;
  31. }
  32. return 0;
  33. }

GDB调试默认跟踪父进程,如下:

如何跟踪子进程呢?

在fork函数调用之前设置跟踪子进程:

set follow-fork-mode child

然后就会跟踪子进程,如下:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/742344
推荐阅读
相关标签
  

闽ICP备14008679号