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

退出打印视图

更新时间: 2016 年 6 月
 
 

单步执行程序

dbx 支持两个基本单步执行命令:nextstep,外加 step 命令的两个变体(称为 step upstep to)。 next 命令和 step 命令均可在再次停止前执行一个源代码行。

如果执行的行中包含函数调用,next 命令允许执行调用并于下一行停止(“步过”调用)。step 命令停止在被调用函数的第一行(“步入”调用)。

step up 命令会在步入函数之后,将程序返回到调用方函数。

step to 命令会尝试步入当前源代码行中的指定函数;如果未指定任何函数,则尝试步入由当前源代码行的汇编代码确定调用的最后一个函数。 可能会因为条件分支或当前源代码行内没有被调用的函数,而无法执行函数调用。在这些情况下,step to 命令将步过当前源代码行。

有关 nextstep 命令的更多信息,请参见next 命令step 命令

控制单步执行行为

要单步执行指定行数的代码,请使用 dbx 命令 nextstep,并在命令后跟要执行代码的行数 [n]

(dbx) next n

(dbx) step n

step_granularity dbxenv 变量确定 step 命令和 next 命令单步执行代码的单元。 该单元可以是 statementline

step_events 环境变量控制单步执行过程中是否启用断点。

step_abflow 环境变量控制当 dbx 检测到将发生不寻常的控制流更改时,是否停止运行。对 siglongjmp()longjmp() 的调用或异常抛出有可能导致此类型的控制流更改。

有关更多信息,请参见设置 dbxenv 变量

步入特定函数或最后一个函数

要步入从当前源代码行调用的函数,请使用 step to 命令。

(dbx) step to function 

要步入最后调用的函数:

(dbx) step to

对于以下两个示例而言,使用 step to 本身将会步入 foo

foo(bar(baz(4)));
baz()->bar()-> foo()

继续执行程序

要在程序遇到断点或某些事件后继续执行程序,请使用 cont 命令。

(dbx) cont

使用变体 cont at line-number,您可以指定除当前程序位置行以外的行来恢复程序执行。此选项允许您跳过已知引起问题的一行或多行代码,而无需重新编译。

要在指定的行继续执行程序,请键入:

(dbx) cont at 124

行号是相对于程序停止所在的文件求值的。给定的行号必须位于当前函数的作用域内。

cont at line-number command 命令和 assign 命令配合使用,可以避免执行包含某个函数调用(可能会错误地计算某一变量的值)的代码行。要快速调整错误计算的值,请使用 assign 命令为变量赋予一个正确的值。使用 cont at line-number 来跳过包含不正确地计算值之函数调用的行。

例如,假定程序停止于第 123 行。第 123 行调用函数 how_fast(),该函数将不正确地计算变量 speed。您知道 speed 变量应该取什么值,因此便为 speed 赋值。然后跳过对 how_fast() 的调用,于第 124 行处继续执行程序。

(dbx) assign speed = 180; cont at 124;

如果使用带有 when 断点命令的 cont 命令,则程序每次尝试执行第 123 行时,都会跳过对 how_fast() 的调用。

(dbx) when at 123 { assign speed = 180; cont at 124;}

调用函数

程序被停止时,可以使用 dbx call 命令调用函数,以此接受必须传递给被调用函数的参数值。

要调用过程,请键入函数名称并提供其参数。 例如:

(dbx) call change_glyph(1,3)

如果参数是可选项,则必须在参数名称后键入括号。例如:

(dbx) call type_vehicle()

您可以使用 call 命令显式调用函数;或者,通过对包含函数调用的表达式求值或使用 stop in glyph -if animate() 等条件修饰符来隐式调用函数。

您可以通过使用 print 命令或 call 命令或任何其他用于执行函数调用的命令来调用 C++ 虚拟函数,就像调用任何其他函数一样。

对 C++ 而言,dbx 可处理隐式 this 指针、缺省参数和函数重载。如有可能,C++ 重载函数将自动求解。如果存在任何二义性(例如,未使用 –g 编译函数),dbx 将显示重载名称列表。

如果定义函数的源文件已使用 –g 选项编译,或原型声明在当前作用域可见,dbx 会检查参数的个数和类型,如果存在不匹配便发出错误消息。否则,dbx 不会检查参数的个数并继续执行调用。

缺省情况下,在每个 call 命令之后,dbx 都会自动调用 fflush(stdout) 来确保 I/O 缓冲区内存储的所有信息全部被输出。 要禁用自动刷新,请将 dbxenv 变量 output_auto_flush 设置为 off

使用 call 命令时,dbx 的行为就好像您使用了 next 命令一样(从被调用的函数返回)。但是,如果程序在被调用的函数内遇到断点,dbx 将在断点处停止程序并发出消息。如果之后键入 where 命令,堆栈跟踪将显示调用源自 dbx 命令级。

如果继续执行,调用会正常返回。如果尝试中止、运行、重新运行或调试,当 dbx 试图从嵌套中恢复时,命令便会终止。然后,可以重新发出命令。另外,可以使用命令 pop –c 弹出调试器最近调用之前的所有帧。

调用安全性

通过使用 call 命令或通过输出包含调用的表达式来在要调试的进程中进行调用时,可能会导致不明显的严重中断。例如:

  • 调用可能会陷入无限循环(您可以中断该循环),或导致段故障。在许多情况下,您可以使用 pop –c 命令返回到调用方。

  • 在多线程应用程序中进行调用时,将会恢复所有线程以避免死锁,所以您可能会在进行调用的线程之外的其他线程上看到负面影响。

  • 断点条件中使用的调用可能会搞乱事件管理(请参见恢复执行)。

    dbx 进行的一些调用会安全地执行。如果遇到问题(通常是段故障)、而非通常的 Stopped with call to ...,则 dbx 将执行以下操作之一:

  • 忽略任何 stop 命令(包括那些因检测内存访问错误而使用的命令)

  • 自动发出 pop -c 命令以返回到调用方

  • 继续执行

    dbx 将在以下情况下使用安全调用:

  • display 命令输出的表达式中发生的调用。失败的调用显示为:ic0->get _data() = <call failed>

    要诊断此类故障,请尝试使用 print 命令输出表达式。

  • db_pretty_print() 函数的调用(使用 print -p 命令时除外)。

  • 事件条件表达式中使用的调用。包含失败调用的条件会计算为 false。

  • 执行 pop 命令期间为调用析构函数所做的调用。

  • 所有内部调用。