使用 dbx 调试程序来显示和处理源文件

此部分描述了使用 dbx 调试程序来显示和处理源文件的过程。

可使用 dbx 调试程序仔细搜索并显示程序的部分源文件。

搜索时不需要当前源列表。 dbx 调试程序跟踪当前文件、当前过程以及当前行。 如果核心文件存在,那么最初将当前行和当前文件设为包含在其结束进程的源代码语句的行和文件。 仅当进程停止在某个为进行调试而编译的位置时,才是这种情况。

更改源目录路径

在缺省情况下,dbx 调试程序在以下目录中搜索正在调试的程序的源文件:

  • 编译源文件时该源文件所在的目录。 只有编译器设置了对象中的源路径时才能搜索目录。
  • 当前目录。
  • 程序当前所在的目录。

您可以使用 德布克斯 调用行上的 -我 选项或在 德布克斯 程序中发出 使用 子命令来更改要搜索的目录列表。 例如,如果在编译时将源文件移动到一个新位置,那么您也许想要使用这些命令之一指定旧位置、新位置以及一些临时位置。

显示当前文件

list 子命令允许您列出源行。

美元符号 $ 和 at 符号 @ 代表SourceLineExpression,可用于liststoptrace子命令。 $ 符号代表下一个将要运行的行。 @ 符号代表下一个将要列示的行。

move 子命令更改要列示的下一个行号。

更改当前文件或过程

使用 funcfile 子命令来更改当前文件,当前过程, 以及 dbx 程序中的当前行,而不必运行程序的任何部分。

仔细搜索当前文件以获取与正则表达式匹配的文本。 如果找到匹配项,那么将当前行设为包含匹配文本的行。 搜索子命令的语法为:

/ RegularExpression [/]
在当前源文件中 向前搜索 给定表达式。
? RegularExpression [?]
在当前源文件中 向后搜索 给定表达式。

如果重复不带自变量的搜索,那么 dbx 命令将再次搜索先前的正则表达式。 搜索回绕文件的结尾或开头。

还可以使用 edit 子命令为源文件调用外部文本编辑器。 在启动 dbx 程序前,可通过将 EDITOR 环境变量设为期望编辑器来覆盖缺省编辑器 (vi)。

dbx 程序在编辑会话完成时重新开始控制进程。

调试涉及多个线程的程序

涉及多个用户线程的程序调用子例程 pthread_create。 当进程调用此子例程时,操作系统在进程内创建执行的新线程。 调试多线程程序时,有必要处理各个线程而不是进程。 dbx 程序仅适用于用户线程: 在 dbx 文档中,单词 thread 通常单独用于表示 用户线程dbx 程序为正在调试的进程中的每个线程分配唯一的线程号,并且还支持正在运行的线程和当前线程的概念:

运行线程
负责通过运行到断点来停止程序的用户线程。 单步执行程序的子命令处理正在运行的线程。
当前线程
正在检查的用户线程。 显示信息的子命令处理当前线程的上下文。

在缺省情况下,正在运行的线程与当前线程相同。 可使用 thread 子命令选择不同的当前线程。 当 thread 子命令显示线程时,当前线程行前面有 >。 如果正在运行的线程与当前线程不同,那么其行以 *开头。

调试涉及多个进程的程序

涉及多个进程的程序调用 forkexec 子例程。 派生程序时,操作系统将创建另一个进程,该进程具有与原始进程相同的映像。 原始进程称为父进程,被创建的进程称为子进程。

当进程执行 exec 子例程时,一个新的程序将接管原始进程。 在一般情况下,调试程序仅调试父进程。 但是,当您发出 multproc 子命令时, dbx 程序可以跟随执行并调试新进程。 multproc 子命令启用多进程调试。

当启用多进程调试且发生派生时,父进程和子进程均会停止。 对于新版本的 dbx 程序,打开独立虚拟终端 Xwindow 以控制子进程的运行:

(dbx) multproc on
(dbx) multproc
multi-process debugging is enabled
(dbx) run

发生派生时,执行停止在父进程中,并且 dbx 程序将显示该程序的状态:

application forked, child pid = 422, process stopped, awaiting input
stopped due to fork with multiprocessing enabled in fork at 0x1000025a (fork+0xe)
(dbx)

然后打开了另一个虚拟终端 Xwindow 以调试子进程:

debugging child, pid=422, process stopped, awaiting input
stopped due to fork with multiprocessing enabled in fork at 0x10000250
10000250 (fork+0x4) )80010010    1       r0,0x10(r1)
(dbx)

此时,正在运行两种截然不同的调试会话。 子进程的调试会话保留了父进程的断点,但仅可重新运行父进程。

当程序以多进程调试方式执行 exec 子例程时,程序覆盖它自身,并且原始符号信息作废。 当 exec 子例程运行时所有断点都会被删除;新程序将被停止并标识从而使调试有意义。 dbx 程序将其自身连接到新程序映像、使子例程确定新程序的名称,报告名称,然后提示输入。 提示符与以下内容类似:

(dbx) multproc
Multi-process debugging is enabled
(dbx) run
Attaching to program from exec . . . 
Determining program name . . . 
Successfully attached to /home/user/execprog . . . 
Reading symbolic information . . . 
(dbx)

如果多线程程序派生,那么新子进程将只含有一个线程。 此进程应该调用 exec 子例程。 否则,将保留原始符号信息,并且与线程相关的子命令(如 thread)将显示已作废的父进程的对象。 如果调用了 exec 子例程,那么重新初始化原始符号信息,并且与线程相关的子命令显示新子进程中的对象。

可通过使用 multproc 子命令的 child 标记在不打开新 Xwindow 的情况下跟踪派生的子进程。 创建派生进程时,dbx 跟踪子进程。 multproc 子命令的 parent 标记在派生程序时导致 dbx 停止,但而后跟踪该父进程。 child 标记和 parent 标记都跟踪 execed 进程。 当 Xwindows 未在运行时,这些标记对于调试程序是非常有用的。