GDB的使用

GDB的使用

常用gdb调试命令及用法

命令名称命令缩写命令说明
runr运行一个程序
continuec让暂停的程序继续运行
breakb添加断点
tbreaktb添加临时断点
backtracebt查看当前线程的调用堆栈
framef切换到当前调用线程指定的堆栈
infoinfo查看断点、线程等信息
enableenable启用某个断点
disabledisable禁用某个断点
deletedel删除断点
listl显示代码
printp显示变量值,如:p + 变量名,表示显示变量的值。也可以加上函数:p + 函数,也可以加上表达式
ptypeptype查看变量的类型
threadthread切换到指定的线程
nextn运行到下一行
steps执行当前行语句,如果该语句为函数调用,则进入函数执行其中的第一条语句
注意:如果函数是库函数或者第三方提供的函数,用s也进不去,因为没有源代码,如果是自定义的函数,只要有源码就可以进去
untilu运行到指定的行,停下来
finishfi结束当前调用函数,到上一层函数调用处
returnreturn结束当前调用函数并返回指定的值,到上一层函数调用处
jumpj将当前程序的执行流跳转到指定的行或地址
disassembledis查看汇编代码
set args设置主程序的参数
设置方法:
(gdb)set args +参数1 + 参数2
set var设置变量的值,假设程序有两个变量:如int i;char arr[20];
set var i = 10; 把i的值设置为10;
set var arr = “string”; 把arr的值设置为”string“,注意不是strcpy
show args查看设置的命令行参数
watchwatch监视某个变量或内存地址的值是否发生了变化
displaydisplay监视的变量或者内存地址,在程序中断后自动输出监控的变量或者内存地址
dirdir重定向源码文件的位置

注意

调试程序时需要加上-g选项,还建议关闭编译器程序的优化选项,编译器程序的优化一般有5个级别,即O0-O4,其中O0表示不优化,从O1-O4,优化级别越来越高。推荐使用O0。

启动gdb调试的方法

使用gdb调试一个程序一般有三种方法:

  1. 直接调试目标程序: gdb + filename

  2. attach到进程:gdb + attach + pid

    • 当一个程序已经启动,但是又想调试该程序,那么需要gdb attch + 需要调试的进程id。在使用attach到目标进程后,调试器会停下来,此时直接使用continue命令让程序继续跑即可。
    • 若想调试完程序后结束此次调试,且不对当前进程有任何影响,可以在gdb的命令界面输入detach命令程序与调试器分离。
  3. 调试core文件–定位进程奔溃问题:gdb + filename corename

    • linux系统默认情况下是不会开启程序奔溃时产生core文件这一功能,可以使用ulimit -c 来查看系统是否开启这一功能。如果发现core file size是0的话,表示关闭生成core文件的选项,可以通过ulimit + 选项名 + 设置值 来修改。可以改成最大允许生成的大小,如1024,表示生成最大core文件大小为1024KB;也可以改成无限大,如ulimit -c unlimited

    • 注意:当关闭会话后,这个值还会变成0。如想希望这个选项永久生效,有两种方式可以设置:

      1. 在/etc/security/limits.conf中增加一行:

        #<domain>   <type>   <item>    <value>
        *            soft     core     unlimited
        
      2. ulimit -c unlimited加到/etc/profile文件中,放到最后一行即可。修改成功后执行source /etc/profile 可以让配置立即生效。当然这只作用到root用户,如果想仅仅作用某一用户的话,可以把ulimit -c unlimited加入到该用户对应的 ~/.bashrc或者 ~/.bash_profile文件中

      3. 生成的core文件默认命名方式是core.pid。位置在崩溃程序所在的目录。

    • 假如,当有多个程序同时崩溃,无法从core文件的名字来对应是哪个服务,该如何解决呢?

      1. 方式一:在程序启动是记录pid

      2. 方式二:自定义core文件的名称和目录

        • /proc/sys/kernel/core_uses_pid可以控制在产生的core文件的名字中是否添加pid作为扩展,如果添加则文件内容为1,否则为0

        • /proc/sys/kernel/core_pattern可以设置格式化的core文件保存位置或文件名。修改方式如下:

          echo "/corefile/core-%e-%p-%t" > /proc/sys/kernel/core_pattern
          
          参数名称参数含义
          %p添加pid到core文件名中
          %u添加当前uid到core文件名中
          %g添加当前gid到core文件名中
          %s添加导致产生core的信号到core文件中
          %t添加core文件的生成时间(UNIX)到core文件中
          %h添加主机名到core文件名中
          %e添加程序名到core文件名中

gdb调试多线程方法

  1. 使用gdb将程序跑起来后,使用ctrl + c将程序中断,使用info threads 命令查看当前进程有多少线程。

  2. 可以使用thread + 线程编号切换到对应的线程,使用bt查看线程的调用堆栈

  3. 有时在多线程情况下,只希望调试某一个线程,而不是切换到其他线程,可以使用锁定当前调试线程的选项scheduler-locking这个选项有三个值,分别是on(锁定)、step(锁定)、off(释放锁定)。使用方式如下

    set scheduler-locking on/step/off
    
    • on和step区别:设置为on时,当前线程执行next、step、until、finish、return命令时,其它线程不会执行。而step当且仅当使用next、step命令会锁定当前线程,使用until、finish、return等线程内的调试命令(非单步调试命令),其它线程是有机会运行的。

gdb调试多进程方法

  1. 方法一:现在shell窗口中使用gdb调试父进程,当子进程被fork出来后,在重新开一个shell窗口使用gdbattach 命令将gdb attach到子进程上。

  2. 方式二:gdb调试器提供了一个follow-fork选项,通过set follow-fork mode设置一个进程fork出新的子进程使,gdb是继续调试父进程还是调试子进程。

    1. 调试父进程:set follow-fork-mode parent(缺省)
    2. 调试子进程:set follow-fork-mode child
    3. 设置调试模式:set detach-on-fork [on|off]
       1. 缺省是on;表示调试当前进程的时候,其它的进程继续运行
       2. off:调试当前进程的时候,其它的进程被gdb挂起
    4. 查看调试的进程:info inferiors
    5. 切换当前调试的进程:inferior + 进程ID
    6. 注意:想要切换进程调试需要把调试模式设置为off
    

本文参考《c++服务器开发精髓》

如果本文对你有帮助,记得一键三连哦,一键三连笑哈哈,代码能力顶呱呱!

本人能力有限,如有错误,望不吝指正;原创不易,欢迎转载,转载请注明出处!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值