gdb 调试+子进程+线程
一、gdb常用指令:
gcc -g main.c //在目标文件加入源代码的信息
gdb a.out (gdb) start //开始调试
(gdb) n //一条一条执行
(gdb) step/s //执行下一条,如果函数进入函数
(gdb) backtrace/bt //查看函数调用栈帧
(gdb) info/i locals //查看当前栈帧局部变量
(gdb) frame/f //选择栈帧,再查看局部变量
(gdb) print/p //打印变量的值
(gdb) finish //运行到当前函数返回
(gdb) set var sum=0 //修改变量值
(gdb) list/l 行号或函数名 //列出源码
(gdb) display/undisplay sum //每次停下显示变量的值/取消跟踪
(gdb) break/b 行号或函数名 //设置断点
(gdb) continue/c //连续运行
(gdb) info/i breakpoints //查看已经设置的断点
(gdb) delete breakpoints 2 //删除某个断点
(gdb) disable/enable breakpoints 3 //禁用/启用某个断点
(gdb) break 9 if sum != 0 //满足条件才激活断点
(gdb) run/r //重新从程序开头连续执行
(gdb) watch input[4] //设置观察点
(gdb) info/i watchpoints //查看设置的观察点
(gdb) x/7b input //打印存储器内容,b--每个字节一组,7--7组
(gdb) disassemble //反汇编当前函数或指定函数
(gdb) si // 一条指令一条指令调试 而 s 是一行一行代码
(gdb) info registers // 显示所有寄存器的当前值
(gdb) x/20 $esp //查看内存中开始的20个数
二,调试子进程
实际上,GDB 没有对多进程程序调试提供直接支持。例如,使用GDB调试某个进程,如果该进程fork了子进程,GDB会继续调试该进程,子进程会不受干扰地运行下去。 如果你事先在子进程代码里设定了断点,子进程会收到SIGTRAP信号并终止。那么该如何调试子进程呢?其实我们可以利用GDB的特点或者其他一些辅助手 段来达到目的。此外,GDB 也在较新内核上加入一些多进程调试支持。
接下来我们详细介绍2种方法,分别是 follow-fork-mode 方法,attach 子进程方法。
在2.5.60版Linux内核及以后,GDB对使用fork/vfork创建子进程的程序提供了follow-fork-mode选项来支持多进程调试。
follow-fork-mode的用法为:
set follow-fork-mode [parent|child]
- parent: fork之后继续调试父进程,子进程不受影响。
- child: fork之后调试子进程,父进程不受影响。
- 调试子进程时,设定在子进程上的断点将会有效,而父进程上的断点此时无效;反之依然。缺省gdb是调试主进程的
因此如果需要调试子进程,在启动gdb后,可以看到在启动之后自动跳转到了子进程代码中。
(gdb) set follow-fork-mode child (gdb) start 16 pid = fork(); (gdb) [New process 6238] this is futher process 6236,wait child 6238 [Switching to process 6238] |
Attach子进程
众所周知,GDB有附着(attach)到正在运行的进程的功能,即attach <pid>命令。因此我们可以利用该命令attach到子进程然后进行调试。
例如我们要调试某个进程OwnTest,首先得到该进程的pid
host-192-10-10-8:/home/code # ps -ef|grep OwnTest root 8056 5964 0 14:06 pts/1 00:00:00 ./OwnTest root 8057 8056 0 14:06 pts/1 00:00:00 ./OwnTest root 8058 8057 0 14:06 pts/1 00:00:00 ./OwnTest root 8067 8933 0 14:06 pts/0 00:00:00 grep OwnTest 查看之后发现是三进程,通过pstree查看父子进程id情况。 host-192-10-10-8:/home/code # pstree 8056 OwnTest───OwnTest───OwnTest host-192-10-10-8:/home/code # pstree 8057 OwnTest───OwnTest |
现在就可以调试了。一个新的问题是,子进程一直在运行,attach上去后都不知道运行到哪里了。有没有办法解决呢?
一个办法是,在要调试的子进程初始代码中,比如main函数开始处,加入一段特殊代码,使子进程在某个条件成立时便循环睡眠等待,attach到进程后在该代码段后设上断点,再把成立的条件取消,使代码可以继续执行下去。
至于这段代码所采用的条件,看你的偏好了。比如我们可以检查一个指定的环境变量的值,或者检查一个特定的文件存不存在。以文件为例,其形式可以如下:
void debug_wait(char *tag_file) {while(1){if (tag_file存在)睡眠一段时间;elsebreak;} } |
三,调试线程
当程序没有启动,线程还没有执行,此时利用gdb调试多线程和调试普通程序一样,通过设置断点,运行,查看信息等等。
在多线程编程时,当我们需要调试时,有时需要控制某些线程停在断点,有些线程继续执行。有时需要控制线程的运行顺序。有时需要中断某个线程,切换到其他线程。这些都可以通过gdb实现。
先介绍一下GDB多线程调试的基本命令。 info threads thread ID thread apply ID1 ID2 command thread apply all command set scheduler-locking off|on|step 如果目标进程已经core dump了,那么 gdb -c core xxx xxx是对应的程序文件。 如果目标进程还在运行,通常此时用于调试线程死锁的情况。有两种方法 一是 gdb -p xxx xxx是该进程的进程ID 或者用gcore xxx先获取对应进程的core,他会生成一个core文件 core.xxx 进入gdb后 (gdb) info threads 可以列出所有的线程,缺省设为当前的线程前面有一个*号 比如 gdb) info thread 这是1个死锁的例子,可以看到线程9 和线程2都停在 __ksleep上。 如果想看各个线程的详细堆栈信息,比如要看9的 gdb)thread 9 把当前线程设成9,然后就可以查看相关信息 比如 gdb)bt 将列出栈的调用情况,以及对应源代码中的位置,此时谨慎察看对应代码,一般必有结果。 |
gdb 调试+子进程+线程相关推荐
- GDB 调试多进程或者多线程应用
GDB 是 linux 系统上常用的 c/c++ 调试工具, 功能十分强大. 对于较为复杂的系统, 比如多进程系统, 如何使用 GDB 调试呢? 考虑下面这个三进程系统 : 进程 ProcessChi ...
- gdb调试fork+exec创建的子进程的方法
最常见的多进程的形式如下: pid = fork(); if (pid < 0) { // fork failedprintf("fork error\n");exit(1) ...
- Linux基础 30分钟GDB调试快速突破
引言 Linus心灵鸡汤 在*nix开发中有道卡叫gdb调试,不管你怎么搞. 它依然在那丝毫不会松动.今天致敬一个 活着的传奇 Linus Torvalds Unix 始于上个世纪60年代,在70年代 ...
- 比较全面的gdb调试命令
用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序 列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行 软件的优势在于 ...
- gdb调试多进程和多线程命令 .
1. 默认设置下,在调试多进程程序时GDB只会调试主进程.但是GDB(>V7.0)支持多进程的 分别以及同时 调试,换句话说,GDB可以同时调试多个程序.只需要设置follow-fork-mod ...
- 多进程多线程GDB调试 (转)
多进程多线程GDB调试 一.线程调试指南: 1. gdb attach pid 挂载到调试进程 2. gdb$ set scheduler-locking on 只执行当前选定线程的开关 3 ...
- 用gdb调试core文件
GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成 ...
- 使用gdb调试多进程和多线程
GDB调试多进程 1. 默认设置下,在调试多进程程序时GDB只会调试主进程.但是GDB(>V7.0)支持多进程的分别以及同时调试,换句话说,GDB可以同时调试多个程序.只需要设置follow-f ...
- GDB调试多进程|多线程程序
1. 默认设置下,在调试多进程程序时GDB只会调试主进程.但是GDB(>V7.0)支持多进程的分别以及同时调试,换句话说,GDB可以同时调试多个程序.只需要设置follow-fork-mode( ...
最新文章
- 【 MATLAB 】z 变换中的卷积与解卷积
- socket传输过程
- Mozilla裁员波及Daala Codec团队
- java ndc_通过slf4j/log4j的MDC/NDC 实现日志追踪
- [ 转载 ] Java基础14--创建线程的两个方法
- 最短路径(信息学奥赛一本通-T1378)
- leetcode —— 209. 长度最小的子数组
- tomcat启动Configuration Error: deployment source ‘xxx:war exploded‘ is not valid
- 微课|玩转Python轻松过二级(1.3节):编码规范与代码优化建议2
- 1-java学习笔记
- ​四周第一次课(4月11日)lvm讲解
- 多次导入excel实现及excel导入逻辑插件清空数据
- 解决 Android App 上架 Google play后 ,签名变更,第三方sdk无法登录
- dataframe两个表合并_Spark实战第二版(涵盖Spark3.0)第三章 宏伟的角色dataframe
- ESP32s3-EYE ESP-IDF环境搭建Ubuntu18.04 Micropython环境搭建Pycharm 物联网
- OBS直播软件-简介
- 自定义控件其实很简单 五
- 2.Hadoop3.x 基础知识
- 拥有奇瑞QQ冰淇淋·桃欢喜才懂的幸福
- day11 - 每日总结及作业