多线程编程指南

调试多线程程序

下面论述的内容介绍了一些可能在多线程程序中导致错误的特征。

多线程程序中常见的疏忽性问题

以下列表指出了在多线程程序中可能导致错误的一些经常被疏忽的问题。

多线程程序(特别是那些包含错误的程序)经常在两次连续运行中的行为方式不同,即使输入相同也是如此。此行为是由线程调度顺序的差异所导致的。

一般情况下,多线程错误是统计得出的,不具有确定性。通常,与基于断点的调试相比,跟踪是用于查找执行顺序问题的一种更有效的方法。

使用 TNF 实用程序跟踪和调试

请使用 TNF 实用程序跟踪、调试和收集应用程序和库中的性能分析信息。TNF 实用程序将内核以及多个用户进程和线程中的跟踪信息整合在一起。TNF 实用程序对于多线程代码特别有用。TNF 实用程序包括在 Solaris 软件中,是该软件的一部分。

使用 TNF 实用程序,可以轻松跟踪和调试多线程程序。有关使用 prex(1)tnfdump(1) 的详细信息,请参见 TNF 手册页。

使用 truss

有关跟踪系统调用、信号和用户级别函数调用的信息,请参见 truss(1) 手册页。

使用 mdb

有关 mdb 的信息,请参见《Solaris Modular Debugger Guide》。

可以使用下面的 mdb 命令来访问多线程程序的 LWP。

$l

如果目标为用户进程,则将列显有代表性的线程的 LWP ID。

$L

如果目标为用户进程,则将列显目标中每个 LWP 的 LWP ID。

pid::attach

附加到编号为 pid 的进程。

::release

释放以前附加的进程或核心转储文件。随后可以由 prun(1) 继续处理进程,或者可通过应用 MDB 或其他调试器来恢复进程。

address ::context

上下文切换到指定进程。

这些用于设置条件断点的命令通常很有用。

[ addr ] ::bp [+/-dDestT] [-c cmd] [-n count] sym ...

在指定的位置设置断点。

addr ::delete [id | all]

删除包含给定 ID 编号的事件说明符。

使用 dbx

使用 dbx 实用程序,可以调试和执行使用 C++、ANSI C 和 FORTRAN 编写的源代码程序。dbx 与调试器接受同样的命令,但使用标准的终端 (TTY) 接口。dbx 和调试器都支持调试多线程程序。有关如何启动 dbx 的说明,请参见 dbx(1) 手册页。有关 dbx 的概述,请参见《Debugging a Program With dbx》。调试器功能在 dbx 的调试器 GUI 的联机帮助中介绍。

表 7–2 中列出的所有 dbx 选项均可支持多线程应用程序。

表 7–2 MT 程序的 dbx 选项

选项 

操作 

cont at line [-sig signo id]

在包含信号 signoline 中继续执行操作。id(如果存在)指定哪个线程或 LWP 继续操作。缺省值为 all

lwp

显示当前的 LWP。切换到给定 LWP [lwpid]。  

lwps

列出当前进程中所有的 LWP。  

next ... tid

单步执行给定线程。跳过函数调用时,所有的 LWP 都会在该函数调用期间隐式恢复。不能单步执行非活动线程。  

next ... lid

单步执行给定 LWP。跳过函数时不会隐式恢复所有 LWP。所含的给定线程处于活动状态的 LWP。跳过函数时不会隐式恢复所有 LWP。  

step... tid

单步执行给定线程。跳过函数调用时,所有的 LWP 都会在该函数调用期间隐式恢复。不能单步执行非活动线程。  

step... lid

单步执行给定 LWP。跳过函数时不会隐式恢复所有 LWP。  

stepi... lid

给定的 LWP。  

stepi... tid

所含的给定线程处于活动状态的 LWP。  

thread

显示当前线程。切换到线程 tid。在下面所有的变体中,可选的 tid 表示当前线程。

thread -info [ tid ]

列显有关给定线程的所有已知信息。  

thread -blocks [ tid ]

列显阻塞其他线程的给定线程持有的所有锁定。  

thread -suspend [ tid ]

使给定线程进入暂停状态。  

thread -resume [ tid ]

取消暂停给定线程。  

thread -hide [ tid ]

隐藏给定线程或当前线程。该线程不会出现在通用的 threads 列表中。

thread -unhide [ tid ]

取消隐藏给定线程或当前线程。

thread -unhide all

取消隐藏所有线程。

threads

列显所有已知线程的列表。  

threads -all

列显通常不会列显的线程(僵线程)。  

threads -mode all|filter

控制在缺省情况下,threads 是列显所有线程,还是过滤线程。

threads -mode auto|manual

实现线程列表的自动更新。  

threads -mode

回显当前模式。线程或 LWP ID 可以按照以前的任何形式来追溯指定实体。