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
### GDB调试基础 GDB 是 GNU 调试器 (GNU Debugger),用于调试 C 和 C++ 程序。它允许开发者分析崩溃原因并逐步跟踪程序运行过程中的状态变化。 #### 编译带有调试信息的程序 为了能够使用 GDB 进行有效的调试,必须在编译阶段加入 `-g` 参数以包含调试符号表。这可以通过 GCC 或其他支持此选项的编译器完成[^2]。例如: ```bash gcc -g -std=c99 -o bug bug.c ``` 上述命令会生成名为 `bug` 的可执行文件,并附带完整的调试信息。 #### 启动 GDB 并加载目标程序 通过指定目标二进制文件作为参数来启动 GDB。如果成功读取到符号信息,则会在终端显示类似于 “Reading symbols from...done.” 的消息[^1]。以下是具体操作方式: ```bash gdb demo1 ``` 此时进入交互模式,在这里可以输入各种指令控制被调试的应用进程行为。 #### 基本GDB命令概览 - **run**: 开始或重新开始程序执行。可以选择提供命令行参数给待测应用。 ```bash run arg1 arg2 ... ``` - **breakpoint 设置断点**: 可以按函数名或者源码行号设置停止点以便更细致地观察变量值的变化情况。 ```bash break main # 在main函数入口处设停靠位 break filename.c:line_number # 定义特定位置上的暂停标记 ``` - **step/next 单步执行**: step 会深入调用子功能内部;而 next 则仅跨越当前语句而不展开其细节。 ```bash step # 步入下一个逻辑单元(可能跳转至另一方法) next # 继续直到下一条顶层表达式被执行完毕 ``` - **print 查看变量值**: 动态获取内存中存储的数据实例。 ```bash print variable_name # 输出某个已声明对象的内容 ``` - **continue 恢复流程直至下一断点到达前继续正常运转** ```bash continue # 让应用程序按照常规顺序前进,除非遇到新的障碍物才会再次中断下来等待进一步指示 ``` - **quit 结束会话退出工具界面返回shell环境当中去** ```bash quit # 关闭整个工作区离开debugger回到操作系统提示符之下 ``` 以上只是部分常用特性介绍而已,实际上还有许多高级技巧可供探索学习。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值