跳过导航链接 | |
退出打印视图 | |
Oracle Solaris Studio 12.3:使用 dbx 调试程序 Oracle Solaris Studio 12.3 Information Library (简体中文) |
检测到多线程程序时,dbx 会尝试装入 libthread_db.so,它是一个专门用于进行线程调试的系统库,位于 /usr/lib 目录下。
dbx 是同步式的;当某个线程或轻量进程 (lightweight process, LWP) 停止时,所有其他线程和 LWP 也会相应停止。我们有时将这种行为称作 "stop the world" 模型。
注 - 有关多线程编程和 LWP 的信息,请参见 Solaris《多线程编程指南》。
dbx 中提供有以下线程信息:
(dbx) threads t@1 a l@1 ?() running in main() t@2 ?() asleep on 0xef751450 in_swtch() t@3 b l@2 ?() running in sigwait() t@4 consumer() asleep on 0x22bb0 in _lwp_sema_wait() *>t@5 b l@4 consumer() breakpoint in Queue_dequeue() t@6 b l@5 producer() running in _thread_start() (dbx)
本机代码的每行信息由以下内容组成:
*(星号)表示该线程内发生了需要用户处理的事件。该事件通常是断点。
如果不是星号,而是 "o",则表示发生的是 dbx 内部事件。
>(箭头)表示为当前线程。
线程 id t@number 指特定线程。number 是 thr_create 传回的 thread_t 值。
b l@number 或 a l@number 表示线程绑定到指定的 LWP 或在其上处于活动状态(即操作系统可实际运行该线程)。
传递给 thr_create 的线程的“启动函数”。?() 表示启动函数未知。
线程状态(请参见表 11-1 中有关线程状态的描述。)
线程当前执行的函数。
Java 代码的每行信息由以下内容组成:
t@number, dbx 样式的线程 ID
线程状态(请参见表 11-1 中有关线程状态的描述。)
加单引号的线程名
说明线程优先级的数字
表 11-1 线程和 LWP 状态
|
要将查看上下文切换到另一线程,请使用 thread 命令。语法如下:
thread [-blocks] [-blockedby] [-info] [-hide] [-unhide] [-suspend] [-resume] thread_id
thread
thread thread_id
有关 thread 命令的更多信息,请参见thread 命令。
threads [-all] [-mode [all|filter] [auto|manual]]
threads
threads -all
有关线程列表的说明,请参见线程信息。
有关 threads 命令的更多信息,请参见threads 命令。
可以使用 cont 命令来恢复程序执行。因为线程目前使用同步断点,所以所有线程都会恢复执行。
不过,您可以使用带有 -resumeone 选项的 call 命令恢复单个线程(请参见call 命令)。
在调试多线程应用程序(其中许多线程会调用函数 lookup())时,请考虑以下两种情况:
您设置条件断点:
stop in lookup -if strcmp(name, "troublesome") == 0
当 t@1 在对 lookup() 的调用处停止时,dbx 尝试对条件求值并调用 strcmp()。
您设置断点:
stop in lookup
当 t@1 在对 lookup() 的调用处停止时,发出以下命令:
call strcmp(name, "troublesome")
调用 strcmp() 时,dbx 将会恢复调用期间内的所有线程,这与使用 next 命令进行单步执行时 dbx 所执行的操作类似。之所以这样做的原因是,如果 strcmp() 尝试抓取另一个线程拥有的锁,则仅恢复 t@1 可能会导致死锁。
在这种情况下恢复所有线程的缺点是,dbx 无法处理另一个线程(例如 t@2),从而会在调用 strcmp() 时在 lookup() 处遇到断点。它会发出类似以下之一的警告:
event infinite loop causes missed events in following handlers:
Event reentrancy first event BPT(VID 6, TID 6, PC echo+0x8) second event BPT(VID 10, TID 10, PC echo+0x8) the following handlers will miss events:
在这些情况下,如果可以确定条件表达式中调用的函数不会抓取互斥锁,则可使用 -resumeone 事件修饰符强制 dbx 只恢复 t@1:
stop in lookup -resumeone -if strcmp(name, "troublesome") == 0
只恢复在 lookup() 中遇到断点的线程,以便对 strcmp() 进行求值。
此方法在诸如以下的情况下会无能为力:
由于条件以递归方式调用 lookup(),lookup() 上的第二个断点发生在同一个线程中
运行条件的线程放弃控制权、休眠或以某种方式将控制权交给另一个线程