Oracle® Developer Studio 12.5: dbxtool 教程

退出打印视图

更新时间: 2016 年 6 月
 
 

诊断信息转储

要查找错误,请再次运行示例程序,然后在不输入命令的情况下按回车键。

$ a.out
> display var
will display 'var'
> 
Segmentation Fault (core dumped)
$

启动包含可执行文件和信息转储文件的 dbxtool

$ dbxtool a.out core

请注意,dbxtool 命令接受的参数与 dbx 命令相同。

dbxtool 显示与以下示例类似的输出。

image:显示调试器控制台窗口和调用 strmp 的位置的 dbxtool 窗口

    请注意以下几点:

  • 在 "Debugger Console"(调试器控制台)窗口中,您将看到一条类似于以下示例的消息:

    program terminated by signal SEGV (no mapping at fault address)
    0xf8cfb790: strcmp+0x0170:      ld       [%ol], %gl
    Current function is Interp::find
  • 即使 strcmp() 函数中发生了 SEGVdbx 也会自动在第一个帧中显示包含调试信息的函数。请注意,"Call Stack"(调用堆栈)窗口中的堆栈跟踪在当前帧的图标四周有一个边框。

    image:在当前帧的图标周围具有粗边框的 “Call Stack“(调用堆栈)窗口

    请注意,"Call Stack"(调用堆栈)窗口显示参数名称和值。在该示例中,传递给 strcmp() 的第二个参数为 0x0,name 的值为 NULL。

  • 在编辑器窗口中,第 95 行上的淡紫色长条和一个三角形(而不是绿色条和箭头)表示调用 strcmp() 的位置,而不是错误的实际位置:

    image:边界中有三角形、源代码行上有淡紫色长条的编辑器窗口

    如果您没有看到参数值,请检查 .dbxrc 文件中的 dbxenv 变量 stack_verbose 是否设置为 on。您还可以在 "Call Stack"(调用堆栈)窗口中设置详细模式,方法是在该窗口中右键单击并选择 "Verbose"(详细)选项。有关 dbxenv 变量和 .dbxrc 的更多信息,请参见Oracle Developer Studio 12.5:使用 dbx 调试程序 中的 第 3 章, 定制 dbx

向函数传递错误值作为参数时,函数通常会失败。检查传递给 strcmp() 的值:

  • "Variables"(变量)窗口自动显示所有本地变量。检查 "Variables"(变量)窗口中参数的值。

    1. 单击 "Variables"(变量)选项卡。

      image:“Variables“(变量)窗口

      请注意,name 的值为 NULL。该值很可能是导致 SEGV 的原因,但我们还是来检查一下另一个参数 (*cp)->name() 的值。

    2. 在 "Variables"(变量)窗口中,展开 cp 节点,然后展开 (cp*) 节点。此处所涉及的 name 为 "quit",该名称是有效的:

      image:节点已展开的 “Variables“(变量)窗口

    如果展开 *cp 节点后未显示其他变量,请检查 .dbxrc 文件中的 dbx 环境变量 output_inherited_members 是否设置为 on。通过在窗口中右键单击并选中 "Inherited Members"(继承的成员)复选框来添加复选标记,您还可以显示继承的成员。

  • 使用气球表达式求值确认参数的值。单击进入编辑器窗口,然后将光标悬停在传递至 strcmp()name 变量上方。将显示一个提示,其中,name 的值显示为 NULL。

    image:显示气球表达式求值提示的编辑器窗口

    使用气球表达式求值时,您还可以将光标放置到一个表达式的上方,例如 (*cp)->name()。但是,对于包含函数调用的表达式,会禁用气球表达式求值,因为:

    • 您正在调试一个信息转储文件。

    • 因为在编辑器窗口中随意悬停光标,函数调用可能具有副作用。

由于 name 的值不应为 NULL,因此您需要找出是哪部分代码将该错误的值传递至 Interp::find()。要找出:

  1. 通过选择 "Debug"(调试)> "Stack"(堆栈)> "Make Caller Current"(使调用方成为当前调用方)或单击工具栏上的 "Make Caller Current"(使调用方成为当前调用方)按钮(Alt - Page Down 组合键)image: ,上移调用堆栈。

    image:将调用方标记为当前帧的 “Call Stack“(调用堆栈)窗口
  2. 在 "Call Stack"(调用堆栈)窗口中,双击与 Interp::dispatch() 相对应的帧。

    现在编辑器窗口中突出显示了相应的代码:

    image:包含陌生代码的编辑器窗口

    该代码是未知代码,除 argv[0] 的值为 NULL 外不提供任何线索。

通过动态使用断点和单步执行,调试该问题可能会更加容易。