JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris Studio 12.3:使用 dbx 调试程序     Oracle Solaris Studio 12.3 Information Library (简体中文)
search filter icon
search icon

文档信息

前言

1.  dbx 入门

2.  启动 dbx

3.  定制 dbx

4.  查看和导航到代码

5.  控制程序执行

6.  设置断点和跟踪

7.  使用调用堆栈

8.  求值和显示数据

9.  使用运行时检查

10.  修复并继续

11.  调试多线程应用程序

了解多线程调试

线程信息

查看另一线程的上下文

查看线程列表

恢复执行

了解线程创建活动

理解 LWP 信息

12.  调试子进程

13.  调试 OpenMP 程序

14.  处理信号

15.  使用 dbx 调试 C++

16.  使用 dbx 调试 Fortran

17.  使用 dbx 调试 Java 应用程序

18.  在机器指令级调试

19.  将 dbx 与 Korn Shell 配合使用

20.  调试共享库

A.  修改程序状态

B.  事件管理

C.  宏

D.  命令参考

索引

了解多线程调试

检测到多线程程序时,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)

本机代码的每行信息由以下内容组成:

Java 代码的每行信息由以下内容组成:

表 11-1 线程和 LWP 状态

线程和 LWP 状态
说明
挂起
线程已被显式挂起。
可运行
线程可运行,并正等待作为计算资源的 LWP。
僵停
分离的线程退出 (thr_exit()) 后,在通过使用 thr_join() 重新链接之前,将一直处于僵停状态。THR_DETACHED 是在线程创建时 (thr_create()) 指定的标志。退出的非分离线程在被获得前将一直处于僵停状态。
syncobj 上休眠
线程在给定同步对象上被阻塞。视 libthreadlibthread_db 所提供的支持级别,syncobj 可能会如十六进制地址一般简单,也可能会包含更多的信息内容。
活动
线程在某 LWP 中处于活动状态,但 dbx 无法访问该 LWP。
未知
dbx 无法确定状态。
lwpstate
绑定或活动线程状态具有与之关联的 LWP 的状态。
运行
LWP 正在运行,但因响应另一 LWP 而同步停止。
syscall num
LWP 进入给定系统调用 # 时停止。
syscall 返回 num
LWP 退出给定系统调用 # 时停止。
作业控制
LWP 因作业控制而停止。
LWP 挂起
LWP 在内核中被阻塞。
单步递阶
LWP 刚刚完成一步。
断点
LWP 刚刚遇到断点。
fault num
LWP 招致给定错误 #。
signal name
LWP 招致给定信号。
进程同步
此 LWP 所属进程刚刚开始执行。
LWP 停止
LWP 正在退出。

查看另一线程的上下文

要将查看上下文切换到另一线程,请使用 thread 命令。语法如下:

thread [-blocks] [-blockedby] [-info] [-hide] [-unhide] [-suspend] [-resume] thread_id

要显示当前线程,请键入:

thread

要切换到线程 thread_id,请键入:

thread thread_id

有关 thread 命令的更多信息,请参见thread 命令

查看线程列表

要查看线程列表,请使用 threads 命令。语法为:

threads [-all] [-mode [all|filter] [auto|manual]]

要打印所有已知线程,请键入:

threads

要打印通常不输出的线程(僵停),请键入: 

threads -all

有关线程列表的说明,请参见线程信息

有关 threads 命令的更多信息,请参见threads 命令

恢复执行

可以使用 cont 命令来恢复程序执行。因为线程目前使用同步断点,所以所有线程都会恢复执行。

不过,您可以使用带有 -resumeone 选项的 call 命令恢复单个线程(请参见call 命令)。

在调试多线程应用程序(其中许多线程会调用函数 lookup())时,请考虑以下两种情况:

调用 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() 进行求值。

此方法在诸如以下的情况下会无能为力: