gdb 笔记(12)— 调试技巧(print 打印结果显示完整、为函数添加断点失效、多线程下禁止线程切换、调试多进程程序)

1. print 打印结果显示完整

当使用 print 命令打印一个字符串或者字符数组时,如果该字符串太长,print 命令默认显示不全的,我们可以通过在 GDB 中输入

set print element 0 

命令设置一下,这样再次使用 print 命令就能完整地显示该变量的所有字符串了。

2. 为函数添加断点失效

有时候一个函数明明存在,并且我们的程序也存在调试符号,使用

break functionName

添加断点时 GDB 却提示:

Make breakpoint pending on future shared library load? y/n

即使输入 y 命令,添加的断点可能也不会被正确地触发,此时需要改变添加断点的方式,使用该函数所在的代码文件和行号添加断点就能达到效果。

3. 多线程下禁止线程切换

假设现在有 5 个线程,除了主线程,工作线程都是下面这样的一个函数:

void thread_proc(void* arg)
{
    //代码行1
    //代码行2
    //代码行3
    //代码行4
    //代码行5
    //代码行6
    //代码行7
    //代码行8
    //代码行9
    //代码行10
    //代码行11
    //代码行12
    //代码行13
    //代码行14
    //代码行15
}

为了能说清楚这个问题,我们把四个工作线程分别叫做 A、B、C、D。

假设 GDB 当前正在处于线程 A 的代码行 3 处,此时输入 next 命令,我们期望的是调试器跳到代码行 4 处;或者使用 u 代码行10,那么我们期望输入 u 命令后调试器可以跳转到代码行 10 处。

但是在实际情况下,GDB 可能会跳转到代码行 1 或者代码行 2 处,甚至代码行 13、代码行 14 这样的地方也是有可能的,这不是调试器 bug,这是多线程程序的特点,当我们从代码行 4 处让程序 continue 时,线程 A 虽然会继续往下执行,但是如果此时系统的线程调度将 CPU 时间片切换到线程 B、C 或者 D 呢?那么程序最终停下来的时候,处于代码行 1 或者代码行 2 或者其他地方就不奇怪了,而此时打印相关的变量值,可能就不是我们需要的线程 A 的相关值。

为了解决调试多线程程序时出现的这种问题,GDB 提供了一个在调试时将程序执行流锁定在当前调试线程的命令:

set scheduler-locking on

当然也可以关闭这一选项,使用

set scheduler-locking off

4. 使用 GDB 调试多进程程序

这里说的多进程程序指的是一个进程使用 Linux 系统调用 fork() 函数产生的子进程,没有相互关联的进程就是普通的 GDB 调试,不必刻意讨论。

在实际的应用中,如有这样一类程序,如 Nginx,对于客户端的连接是采用多进程模型,当 Nginx 接受客户端连接后,创建一个新的进程来处理这一路连接上的信息来往,新产生的进程与原进程互为父子关系,那么如何用 GDB 调试这样的父子进程呢?一般有两种方法:

  • GDB 先调试父进程,等子进程 fork 出来后,使用 gdb attach 到子进程上去,当然这需要重新开启一个 session 窗口用于调试,gdb attach 的用法在前面已经介绍过了;
  • GDB 调试器提供了一个选项叫 follow-fork,可以使用 show follow-fork mode 查看当前值,也可以通过 set follow-fork mode 来设置是当一个进程 fork 出新的子进程时,GDB 是继续调试父进程还是子进程(取值是 child),默认是父进程( 取值是 parent)。
(gdb) show follow-fork mode     
Debugger response to a program call of fork or vfork is "parent".
(gdb) set follow-fork child
(gdb) show follow-fork mode
Debugger response to a program call of fork or vfork is "child".
(gdb) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wohu007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值