Oracle® Developer Studio 12.5:使用 dbx 调试程序

退出打印视图

更新时间: 2016 年 6 月
 
 

设置断点

    dbx 中,可以使用下列三个命令设置断点:

  • stop-程序执行到使用 stop 命令创建的断点处时将停止。 直到发出其他调试命令(如 contstepnext)后,程序才会恢复执行。

  • when-程序执行到使用 when 命令创建的断点处时将停止,且 dbx 执行一个或多个调试命令,然后程序继续执行(除非执行的命令之一是 stop)。

  • trace-跟踪可显示程序中事件的相关信息,如变量值变化。 尽管跟踪的行为与断点的行为不同,但跟踪和断点的事件处理程序相似。程序执行到使用 trace 命令创建的断点处时将停止,此时会发送事件特定的 trace 信息行,然后程序继续执行。

stopwhentrace 命令都将事件规范(说明断点所基于的事件)当作参数。设置事件规范详细讨论了事件规范。

要设置计算机级断点,请使用 stopiwhenitracei 命令。有关更多信息,请参见在计算机指令级调试


注 -  调试使用 Java 代码和 C JNI(Java Native Interface,Java 本地接口)代码或 C++ JNI 代码混合编写的应用程序时,可能需要在尚未装入的代码中设置断点。有关在此类代码中设置断点的信息,请参见在本地 (JNI) 代码中设置断点

在源代码行设置断点

可以使用 stop at 命令在行号处设置断点,其中 n 是源代码行号,filename 是可选的程序文件名限定符。

(dbx) stop at filename:n

例如:

(dbx) stop at main.cc:3

如果指定的行不是可执行的源代码行,dbx 会在下一个可执行源代码行处设置断点。如果没有可执行源代码行,dbx 会发出错误。

可以使用 file 命令设置当前文件并使用 list 命令列出要在其中停止的函数来确定要停止在那里的行。然后使用 stop at 命令在源代码行设置断点,如以下示例所示。

(dbx) file t.c
(dbx) list main
10    main(int argc, char *argv[])
11    {
12        char *msg = "hello world\n";
13        printit(msg);
14    }
(dbx) stop at 13

有关指定 at 位置事件的更多信息,请参见at 事件规范

在函数中设置断点

可以使用 stop in 命令在函数中设置断点。

(dbx) stop in function

In Function 断点用于在过程或函数中第一个源代码行的开头处暂停程序执行。

    dbx 应当能够确定您正在引用哪个函数,但下列情况除外:

  • 只通过名称来引用一个重载的函数。

  • 引用以 ` 开头的函数。

  • 按函数的链接程序名称(在 C++ 中为改编名称)引用函数。在这种情况下,如果您在名称前添加 # 前缀,则 dbx 将接受该名称。有关更多信息,请参见链接程序名

假设有下面一组声明:

int foo(double);
int foo(int);
int bar();
class x {
   int bar();
};

要在非成员函数处停止,以下命令将在全局 foo(int) 处设置断点:

stop in foo(int)

要在成员函数中设置断点:

stop in x::bar()

在以下命令中,dbx 无法确定所指是全局函数 foo(int) 还是全局函数 foo(double),因而会显示重载菜单以便确认。

stop in foo

如果键入:

stop in `bar

dbx 便无法确定所指是全局函数 bar() 还是成员函数 bar(),因而会显示重载菜单。


注 -  如果成员名称是唯一的(如 unique_member),则使用 stop in unique_member 便已足够。如果成员名称不具有唯一性,则可以使用 stop in 命令并响应重载菜单,以指定您所指的成员。

有关指定 in-function 事件的更多信息,请参见in 事件规范

在 C++ 程序中设置多个断点

可以检查与对不同类成员的调用、对给定类任何成员的调用或对重载的顶级函数的调用有关的问题。可以将关键字 inmemberinclassinfunctioninobjectstopwhentrace 命令一起使用,在 C++ 代码中设置多个断点。

在不同类的成员函数中设置断点

要在特定成员函数的每个类特定变体(成员函数名相同,类不同)中设置断点,请使用 stop inmember

例如,如果在几个不同的类中定义了函数 draw,要在每个函数中设置断点,请键入:

(dbx) stop inmember draw

有关指定 inmemberinmethod 事件的更多信息,请参见inmember 事件规范

在类的所有成员函数中设置断点

要在特定类的所有成员函数中设置断点,请使用 stop inclass 命令。

缺省情况下,断点只插入类中定义的类成员函数中,而不会插入可能从基类继承的类成员函数中。如果还要在从基类继承的函数中插入断点,请指定 -recurse 选项。

以下命令可在类 shape 中定义的所有成员函数中设置断点:

(dbx) stop inclass shape

以下命令可在类中定义的所有成员函数中以及从该类继承的函数中设置断点:

(dbx) stop inclass shape -recurse

有关指定 inclass 事件的更多信息,请参见inclass 事件规范stop 命令

由于 stop inclass 和其他断点选择可能会插入大量断点,因此应确保将 dbxenv 变量 step_events 设置为 on 以加快 stepnext 命令的执行速度。有关更多信息,请参见效率考虑事项

在非成员函数中设置多个断点

要在具有重载名称(名称相同、参数的类型或数量不同)的非成员函数中设置多个断点,请使用 stop infunction 命令。

例如,如果 C++ 程序定义了两个名为 sort() 的函数版本(一个传递 int 类型参数,另一个传递 float 类型参数),以下命令将会在这两个函数中设置断点:

(dbx) stop infunction sort 

有关指定 infunction 事件的更多信息,请参见infunction 事件规范

在对象中设置断点

可以设置 In Object 断点来检查应用于特定对象实例的操作。

使用 In Object 断点在对特定对象实例调用任何方法时停止程序执行。例如,以下代码仅在调用 f1->printit() 时导致停止:

Foo *f1 = new Foo();
Foo *f2 = new Foo();
 f1->printit();
 f2->printit();

(dbx) stop inobject f1

f1 中存储的地址将标识您在其中放置断点的对象。这表示只能在 f1 中的对象实例化之后创建此断点。

缺省情况下,In Object 断点会在对象的类(包括继承的类)的所有非静态成员函数中暂停程序执行。要将断点局限于对象类,请指定 -norecurse 选项。

要在对象 foo 的基类中定义的所有非静态成员函数中以及在对象 foo 的继承类中定义的所有非静态成员函数中设置断点:

(dbx) stop inobject &foo

要在对象 foo 的类中定义的所有非静态成员函数中设置断点,但不在对象 foo 的继承类中定义的所有非静态成员函数中设置断点:

(dbx) stop inobject &foo -norecurse

有关指定 inobject 事件的更多信息,请参见inobject 事件规范stop 命令

设置数据更改断点(监视点)

您可以使用数据更改断点(也称为“监视点”)在 dbx 中注明更改变量或表达式值的时间。

访问地址时停止执行

使用 stop access 命令可在已访问内存地址时停止执行:

(dbx) stop access mode address-expression [, byte-size-expression]

mode 指定内存访问模式。有效的模式选项包括:

r

已读取指定地址处的内存。

w

已写入内存。

x

已执行内存。

mode 还可以包含以下任一项:

a

访问后停止进程(缺省值)。

b

访问前停止进程。

在这两种情况下,程序计数器都将指向访问指令。“之前”和“之后”都具有副作用。

address-expression 是求值结果为地址的任何表达式。如果提供符号表达式,则会自动推导出要监视的区域大小。可以通过指定 byte-size-expression 覆盖它。也可以使用非符号、无类型地址表达式,在这种情况下,必须提供大小。

在以下示例中,该命令将在读取了内存地址 0x4762 之后在任意四个字节后停止执行。

(dbx) stop access r 0x4762, 4

在以下示例中,将在写入变量速度前停止执行:

(dbx) stop access wb &speed

    使用 stop access 命令时请记住下列要点:

  • 写入变量时(即使值不变),会发生事件。

  • 缺省情况下,在执行了写入变量的指令后会发生事件。可以通过将模式指定为 b 来指示要在执行指令前发生事件。

有关指定 access 事件的更多信息,请参见access 事件规范stop 命令

变量更改时停止执行

如果指定变量的值已更改,请使用 stop change 命令停止程序执行:

(dbx) stop change variable

    使用 stop change 命令时请记住下列要点:

  • dbx 会将程序停止在引起指定变量值更改的行后面的那一行。

  • 如果 variable 是函数的局部变量,则第一次进入函数并分配 variable 的存储空间时,便认为该变量已更改。对于参数也是如此。

  • 该命令无法与多线程应用程序配合使用。

有关指定 change 事件的更多信息,请参见change 事件规范stop 命令

dbx 实现的 stop change 操作是自动单步执行且每一步都检查值。如果库未使用 -g 选项进行编译,则单步执行会跳过库调用。因此,如果控制按以下方式流动,dbx 便不会跟踪嵌套的 user_routine2,因为跟踪会跳过库调用和对 user_routine2 的嵌套调用。

   user_routine calls
      library_routine, which calls
        user_routine2, which changes variable

variable 值的更改是在从库调用返回后便已发生,而不是在 user_routine2 中发生的。

dbx 无法为块局部变量({} 中嵌套的变量)中的更改设置断点。如果尝试在块局部嵌套变量中设置断点或跟踪,dbx 会发出错误,说明无法执行此操作。


注 -  与使用 change 事件相比,使用 access 事件监视数据更改的速度更快。access 事件不是自动单步执行程序,而是使用速度更快的硬件或 OS 服务。

条件停止执行

如果条件语句的求值结果为 true,请使用 stop cond 命令停止程序执行:

(dbx) stop cond condition

条件发生时,程序便停止执行。

    使用 stop cond 命令时请记住下列要点:

  • dbx 会将程序停止在使条件的求值结果为 true 的行后面的那一行。

  • 该命令无法与多线程应用程序配合使用。

有关指定条件事件的更多信息,请参见cond 事件规范stop 命令