本文已参与「新人创作礼」活动,一起开启掘金创作之路。 如果要查看基本的gdb命令可以参考上篇
GDB多进程调试
进程的简单描述(唯一标识PID)
当进程不能为系统和用户做出任何贡献了,他就可以发挥最后一点余热,调用任何一个exec,让自己以新的面貌重生;或者,更普遍的情况是,如果一个进程想执行另一个程序,它就可以fork出一个新进程,然后调用任何一个exec,这样看起来就好像通过执行应用程序而产生了一个新进程一样
exec函数族的函数执行成功后不会返回,因为调用进程的实体,包括代码段,数据段和堆栈等都已经被新的内容取代,只留下进程ID等一些表面上的信息仍保持原样,只有调用失败了,它们才会返回一个-1,从原程序的调用点接着往下执行。
1.查看gdb跟随的进程(是父进程还是子进程)
show follow-fork-mode
2.设置gdb跟随的进程
set follow-fork-mode parent | child
3.查看分离进程的开关
show detach-on-fork
4.关闭分离进程的开关
set detach-on-fork off
5.查看当前运行进程的inferior<Num>
info inferiors
6.切换到另一个进程
inferior <Num>
7.根据inferior<Num>复制一个进程/添加一个进程(按照执行路径)
add-inferior [-copies n] [-exec executable]
8.根据PID查找进程
shell ps -ef | grep <PID>
ps -ef (查找当前进程)
| (输入到管道)
grep pid (根据pid过滤)
9.将程序挂载到具体进程上
attach <PID>
10.查看exec的模式
show follow-exec-mode
11.设置exec的模式
set follow-exec-mode new|same
- 设置same:当发生exec的时候,在执行exec的inferior上控制子进程。
- 设置new:新建一个inferior给执行起来的子进程。而父进程的inferior仍然保留,当前保留的inferior的程序状态是没有执行。
GDB多线程调试
线程的唯一标识TID
* GDB默认进入主线程,子线程阻塞在pthread_create()
多线程程序的编译(需要加pthread库)
gcc -g thread.c -o thread -lpthread
1.查看线程阻塞开关
show schedule-locking
2.设置线程模式
set schedule-locking on | off | step
off:不锁定任何线程,默认值
on:只有当前线程执行,锁定其他线程
step:在step时,只有当前线程运行,锁定其他线程
3. 查看线程信息
info threads
4.切换调试线程(GDB分配的ID)
thread <ID>
5.其他设置
- 只能在~/.gdbinit里设置,不能在gdb运行时设置 set non-stop on/off (当调式一个线程时,其他线程是否运行)
set target-async on/off (同步-gdb在输出提示符之前等待程序报告一些线程已经终止的信息;异步-直接返回)
Linux程序发布流程(本质就是分离符号表)
* 确定程序是否存在符号表
readelf -s test
* 生成符号表
objcopy --only-keep-debug test test.symbol
* 生成发布程序
objcopy --strip-debug test test-release
使用符号表进行程序debug
1.进入gdb
gdb file
2.载入符号表
file ./file.symbol
(或者)直接载入符号表进入GDB
gdb --symbol=file.symbol --exec=file-release