View on GitHub

开源开发工具技术博客

编译器/工具链、模拟器、虚拟机、Linux内核、调试和性能分析工具

最近GDB社区在讨论给GDB中增加ITSET的功能,这是很重要的功能,会GDB的功能,特别是多线程/多进程方面,有一个巨大的进步 (截止到2012年5月6日,ITSET功能还没有进入到GDB的 CVS)。

ITSET是什么?

ITSET是 Inferior(在GDB中,一个被调试程序的进程可以认为是一个Inferior/Thread SET 的简称。ITSET的概念本身很简单,就是一个Inferior/Thread的集合,然后有了这样的集合以后,调试器的_操作范围_都局限于用户设定的ITSET中。我后边会介绍 调试器的操作范围的具体含义,其实也很容易理解。ITSET在别的场合,也有不同但是类似的名字,比如,ptset (process/thread set) 或者  ptc set (process/thread/core set)。在HPDF (High Performance Debugging Forum) spec 中,叫做ptset。TotalView 中的实现也叫做ptset。每个实现的细节语法和功能和 HPDF spec 有一些出入,但是大体上都一样的。

调试的操作范围,其实,就是一个命令对被调试程序的影响范围。假如调试器正在调试两个进程,p1 和 p2。每个进程又有三个进程,t11, t12,t13 和 t21,t22,t23。如果你是一个调试器的设计者,当实现如下命令的时候,你就需要考虑命令的操作范围了,

break foo 假如两个进程都有foo这个符号,那么断点是插入到两个进程里边呢,还是仅仅插入到当前进程里边?也就是说,这个命令的操作范围是当前进程呢还是所有进程。当然,还可以有更加细致的控制范围,比如,现在有100个进程,我想断点只插入到若干几个进程中。

break bar 假如只有一个进程有这个符号,理所当然这个断点就只插入到那一个进程中。当进程中的一个线程触发断点的时候,应该有哪些线程受到影响呢?这里又有一个范围的问题,需要设计者考虑。p1进程中的t11触发了线程,调试器应该让那几个线程停止下来?调试器的设计者,有如下几个选择

只停止t11。因为就是它触发了断点,其它线程和进程继续运行

停止p1中的所有线程。因为它的一个线程触发了断点

停止p1和p2中的所有线程。这样虽然有些不可思议,但是的确是一种选择

其实还有很多别的选择,这里就不罗列了。在以前的调试器设计中,往往都是选定一种控制范围。

continue 运行这个命令,就是resume已经停止了的线程或者进程继续执行。这里也有不同的范围考虑。如果当前进程p1中,t11 和 t12 已经停止,进程p2 的t21 停止。当前线程是t11。如果运行continue命令,调试器作者可以选择,要么仅仅resume t11,或者resume p1中的所有stopped的线程,或者resume所有停止的线程。

上边的这些例子,就是想说,面对多进程多线程的挑战的时候,调试器需要能够灵活的控制每个命令的范围,而描述这个范围的就是ITSET,但是,如何能够是调试器能够按照ITSET的内容,来准确的控制线程和进程,就是调试器自己的事情了,这也就是现在GDB要做的事情。

ITSET是什么样子的?

如上边介绍,ITSET就是一个线程 进程 核 的集合,所以语法和现有的数学集合很像。”-” 是范围,比如 “t1-4″ 线程1到4,”,” 是或操作 “.” 是与操作等等。这里不详细介绍ITSET的语法,因为每个实现对ITSET都有一些微小的修改。我下来会给一些例子,让大家感受一下ITSET,

i1.t1-4 inferior 1中的thread 1到4

i1.t1,i2.t2 inferior 1中的thread 1 或者 inferior 2 中的thread 2

running.c0 所有在core 0上处于running 状态的线程

有了这样的语法,我们就能轻松灵活的控制命令的范围了。

用ITSET控制命令范围

在将来的GDB实现中,可能是用 itfocus 命令来控制某个命令的作用范围的。

itfocus ITSET command

比如,可以这样控制命令的范围 (下边的例子中的命令还不存在于GDB中)

itfocus i1.t1-2 trace foo在函数foo上设置tracepoint,但是只有对inferior 1中的 t1和t2 有效。也就是说,这个tracepoint是 thread specific的。

itfocus t1-2 p/x var打印变量var在线程 t1 和 t2 的value的value。如果var是一个局部变量,线程t1和t2若在不同的stack上,var的value是不一样的。

itfocus stopped.~t1-2 stepi让除了t1 t2 的所有处于stopped状态的线程单步执行一条指令。

这样的例子会有很多,大家应该能够从这样的例子里边,感受到ITSET对调试器的提高。

结束语
本文介绍了可能在GDB出现的新功能ITSET,以及ITSET的简单语法,初步体现了ITSET的灵活和强大。有了ITSET的GDB,将会对线程 进程的控制和命令 有更加细粒度,使用起来更加灵活。但是,这样的灵活性本身并没有解决多线程程序的复杂,相反,这样的灵活性,可能是用户更加的困惑。总之,ITSET只是一个手段, 还是需要用户来自己解决自己的问题。当程序的线程数目和处理器的core的数目继续增长,纵然有ITSET,用户也是无能为力。所以,更加智能的分析,才是用户更需要的。