《gdb调试之实用技巧篇》

1. 获取进程的内核转储文件(core dump文件)

        gdb可以用来调试进程发生错误时产生的coredump文件,那么coredump文件是怎么产生,以及生成在哪里呢?为什么很多时候我们找不到coredump文件呢?这主要有两个原因:

  • 内核转储功能没有开启
  • 内核转储文件的生成路径问题

启用内核转储

       首先使用ulimit -a查看内核转储功能是否被关闭,如果core_file_size被设置为0则表示该功能被关闭。这时可以用ulimit -c命令设置core_file_size为非0值来开启的该功能。


设置内核转储路径和文件名

       内核转储文件生成路径和文件名取决于内核参数kernel.core_patternkernel.core_uses_pid。我们也可以通过这两个内核参数来查询和设置内核转储的路径和文件名。具体的设置方式有两种,如下图所示:


       内核参数core_pattern,指定的实际上是内核转储文件的全路径名(包括路径和文件名)。例如/var/core/core表示在/var/core/路径下生成名为core的内核转储文件。如果只设置了文件名,例如上图中core_pattern=core的情况,则表示在可执行文件所在目录生成文件名为core的内核转储文件。

       内核参数core_uses_pid表示是否在生成的内核转储文件后添加进程号后缀,1表示添加,0表示不添加。实际上,我们也可以将core_uses_pid设置为0,而直接在core_pattern里通过格式符来设置,具体的格式符较多,建议自行查阅。

       需要说明的是,这种方式只是临时生效,当计算机重启之后则会恢复/etc/sysctl.conf中的设置或系统默认设置。因此如果希望每次重启计算机都能够生效,则可以通过修改/etc/sysctl.conf文件实现。例如在文件中增加如下两行设置:

kernel.core_pattern=/var/core/core.%p

kernel.core_uses_pid=0

2. gdb内部命令使用技巧

       在基础篇里曾列出了gdb的常用内部命令,实际使用时候还是有很多技巧的。这里针对部分常用内部命令做进一步的说明:

程序启动

        gdb可执行文件

        gdb –args可执行文件 arguments

        gdb可执行文件 coredump文件

        gdb –c coredump文件可执行文件

        gdb可执行文件进程pid

       上面列出了多种启动方式,大致还是分为3类,调试可执行文件,coredump文件和正在运行的进程。

断点设置

       断点的设置:

        break/b 函数名/行号/文件名:行号/文件名:函数名/+偏移量/-偏移量/*地址

       条件断点的设置:

        break 断点 if条件

        condition 断点编号条件

运行程序

       调试可执行文件时才有可能需要指定参数,参数即可以在启动gdb时指定,也可以在开始调试时指定:

        run/r 参数

显示栈帧

        backtrace/bt [ [full] N/-N]

       说明:指定full时除了显示栈帧,还会显示局部变量。N-N分别表示开头和最后N个栈帧。

显示寄存器以及内存

       显示寄存器:inforeg

       显示内存:x/格式地址

       说明:显示寄存器时,可以看到一个eip寄存器,那就是程序指针。x命令可用格式为i,表示以汇编语言显示。那么我要显示从程序指针指向地址开始的10条指令就可以用一下命令:

         x/10i $eip

显示变量

        p/格式变量

       说明:这里的重点在格式符,x,d,u,o,t,a,c,f,s分别表示十六进制,十进制,无符号十进制,八进制,二进制,地址,字符,浮点小数,字符串。

修改变量

        set  variable  变量=

运行控制

        next/n N:单步执行N步,不进入函数调用

        step/s N:单步执行N步,进入函数调用

        continue/c N:继续执行,N次遇到断点不停止,相当于连续执行Ncontinue

        finish/fin:运行到当前函数的结束

删除/禁用/启用断点

        clear 函数名/行号/文件名:行号/文件名:函数名

        delete [breakpoints]断点编号

        disable [breakpoints] [断点编号]

        enable [breakpoints] [once/delete] [断点编号]

      说明:disableenable命令,不指定断点编号是会对所有断点起作用,once表示只启用一次,delete表示启用一次后删除该断点

设置断点命令

        commands 断点编号

             命令

             ……

        end

       说明:这个功能非常适合在设置的断点处打印变量的值或者查看栈帧。

监视点

        watch 表达式:表达式发生变化时,暂停运行

        rwatch 表达式:表达式被访问时,暂停运行

        awatch 表达式:表达式发生变化或者被访问时,暂停运行

生成内核转储文件

       在gdb调试过程中,可以使用generate-core-file子命令生成内核转储文件。我们也可以直接使用gcore命令对正在运行的进程直接生成内核转储文件:

        gcore PID

3. 调试正在运行的进程

       除了在启动gdb时直接指定进程号,我们还可以在启动gdb之后,使用内部命令attach进行进程绑定。这非常适用于已经出现问题无法正常结束的进程。调试结束是可以使用detach命令释放进程。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值