GDB 多线程调试基本命令 实现简介 以及一个问题的解决
teawater@gmail.com
一直对 GDB 多线程调试接触不多,最近因为工作有了一些接触,简单作点记录吧。
先介绍一下 GDB 多线程调试的基本命令。
info threads
显示当前可调试的所有线程 , 每个线程会有一个 GDB 为其分配的 ID , 后面操作线程的时候
会用到这个 ID 。
前面有 * 的是当前调试的线程。
thread ID
切换当前调试的线程为指定 ID 的线程。
break thread_test.c:123 thread all
在所有线程中相应的行上设置断点
thread apply ID1 ID2 command
让一个或者多个线程执行 GDB 命令 command 。
thread apply all command
让所有被调试线程执行 GDB 命令 command 。
set scheduler-locking off|on|step
估计是实际使用过多线程调试的人都可以发现 , 在使用 step 或者 continue 命令调试当前被调
试线程的时候 , 其他线程也是同时执行的 , 怎么只让被调试程序执行呢?通过这个命令就可
以实现这个需求。
off 不锁定任何线程,也就是所有线程都执行,这是默认值。
on 只有当前被调试程序会执行。
step 在单步的时候 , 除了 next 过一个函数的情况 ( 熟悉情况的人可能知道 , 这其实是一个设
置断点然后 continue 的行为 ) 以外,只有当前线程会执行。
在介绍完基本的多线程调试命令后,大概介绍一下 GDB 多线程调试的实现思路。
比较主要的代码是 thread.c ,前面介绍的几个命令等都是在其中实现。
thread_list 这个表存储了当前可调试的所有线程的信息。
函数 add_thread_silent 或者 add_thread( 不同版本 GDB 不同 ) 用来向 thread_list 列表增加一个
线程的信息。
函数 delete_thread 用来向 thread_list 列表删除一个线程的信息。
上面提到的这 2 个函数会被有线程支持的 target 调用,用来增加和删除线程,不同的 OS 对
线程的实现差异很大,这么实现比较好的保证了 GDB 多线程调试支持的扩展性。