gdb调试总结

1.常用命令

    1. watch命令监视一个变量或者一段内存,当这个变量或者内存发生变化时,gdb就中断。—> (watch point)
    • int i; watch i;
    • char *p; watch p 与 watch *p;
    • 监视一个数组或内存区间 char buf[128]; watch buf; 对buf的128个数据进行了监视。
  • 2 display,每次 gdb 中断,都会自动输出这些被监视变量或内存的值。
    1. dir 发生调试源文件出现目录发生变化,使用dir进行目录的重定向。

2.使用gdb调试多线程程序

1. 调试多线程程序的方法

    1. info thread 查看线程的数量
  • 2.thread 2 跳转对应的线程
    1. bt 在对应的线程下查看对应的栈信息,可以在源码中找到对应的代码,进行分析。
    1. f 站函数编号 跳转对应的栈信息,进行相应的调试
    1. 对应的函数添加 断点 b func(),然后进行 r 重新运行。

2.在调试时控制线程切换

    1. set scheduler-locking on/step/off 将程序执行流锁定在当前调试线程中, 有三个值可选 on, step, off。 与 on相比 step 选项的值为单步调试提供了更加精细化的控制。当且仅当使用 nextstep 命令做单步调试会锁定当前线程,如果使用 until,finish,return 等线程内的调试命令,则其他线程还是会有机会运行的。

3.使用gdb调试多进程程序–以调试Nginx为例

方法一 gdb attach 进程号

以nginx 这块

//获取
 wget http://nginx.org/download/nginx-1.18.0.tar.gz
 // 解压
 tar zxvf nginx-1.18.0.tar.gz
 cd nginx-1.18.0/
 // 配置
 ./configure --prefix=/usr/local/nginx
 //编译
 make CFLAGS="-g -O0" 
 // 安装
 make install
 cd /usr/local/nginx/sbin/ 
 // 运行
 sudo ./nginx -c /usr/local/nginx/conf/nginx.conf 
 //查看端口以及进程号

在这里插入图片描述

  • root用户为主的是主进程,以 nobody 为用户的是子进程,当客户端请求数量达到一定的限度或继续 fork 新的子进程。

开启调试
附加主进程 sudo gdb attach 3490076

    1. bt 查看调用栈信息
    1. frame 1 切换栈的信息
    1. 基本的命令一样的
      附加子进程,重启一个shell 窗口 sudo gdb attach 3490077
    1. bt 查看子进程的调用栈信息, 同时切换栈的信息 f 1
    1. b 804 添加断点 然后继续运行 c
    1. 客户端进行连接 http://192.168.3.1 进行访问,804的断点就会中断,这样调试Nginx的问题。

方法二 set follow-fork mode mode的取值 parentchild

    1. show follow-fork mode 查看当前值
    1. cd /usr/local/nginx/sbin/ && ./nginx -s stop 停止 nginx。
    1. //src/os/unix/ngx_daemon.c:13 行,为了不让此逻辑调用,关闭后台运行,在 nginx的配置文件中添加一行 daemon off;就行。
    1. gdb nginx && set args -c /usr/local/nginx/conf/nginx.conf && r 或者在 run 之前 set follow-fork child 这样就会出现在子进程

4.gdb实用调试技巧

    1. print 命令输出的字符串或字符数组完整显示
    • set print element 0
    1. 让被调试的程序接受信号
    • 1> signal SIGINT 主动发送信号 SIGINT 或者其他信号
    • 2> handle SIGINT nostop print 告诉SIGINT时不要停止,并把该信号传递给目标调试程序。
  • 3.函数明明存在,添加断点无效 Make breakpoint pending on future shared library load? y/n
    • 改变添加策略 ,使用函数所在的文件和行号进行添加断点。
  • 4,断点:普通断点、条件断点、数据断点。
      1. 数据断点,watch 监视的内存值或者变量发生变化触发的断点。
    • 2.条件断点,触发一定的条件才会触发,
      • <1>.i达到一定的值然后进行开始断点监控。 break [lineNo] if [condition], lineNo 是程序触发断点后需要停止的位置,condition是断点触发的条件。这里可以写成 break 11 if i== 5000,此时 11 就是需要监控的位置。
      • <2>. 首先设置一个普通断点 b 11, 然后获取断点编号 info b ,然后设置"condition 断点编号 断点触发条件",实例就是 condition 1 i ==5000

5.自定义gdb调试命令

    1. 在 root用户下,就在 /root目录, 在 home用户下就在/home目录下,定义一个 .gdbinit文件即可,不存在可以新建一个。然后在文件里面写上 gdb 命令
      Apache Web Server 源码为例,源码目录里面有一个 .gdbinit 文件
# gdb macros which may be useful for folks using gdb to debug
# apache. Delete it if it bothers you
define dump_table
	set $t = (apr_table_entry_t *) ((apr_array_header_t *)$arg0)->elts
	set $n = ((apr_array_header_t *)$arg0)-> nelts
	set $i = 0
	while $i < $n
	if $t[$i].val == (void *)0L
		printf "[%u] '%s'=>NULL\n", $i, $t[$i].key
	else
		printf "[%u] '%s'='$s' [%p]\n", $i, $t[$i].key, $t[$i].val, $t[$i].val
	end
	set $i = $i + 1
	end
end

# 省略部分代码
# Set sane defaults for common signals:
handle SIGPIPE noprint pass nostop
handle SIGUSR1 print pass nostop
  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值