Oracle Solaris Studio 12.2:使用 dbx 调试程序

调试优化代码

dbx 为优化代码提供部分调试支持。支持的程度主要取决于编译程序的方式。

当分析优化代码时,可以:

如果在同时启用优化和调试的情况下(使用 -O-g 选项)编译程序,dbx 将在限定模式下操作。

关于在什么情况下哪些编译器发出哪种符号信息的详细信息通常被认为是不稳定的接口,可能随版本的变化而不同。

源代码行信息可用,但一个源代码行的代码可能会出现在优化程序的几个不同位置上,所以按源代码行在程序中单步执行会导致“当前行”在源文件中跳转,这取决于优化器如何调度代码。

当函数中的最后一个有效操作是调用另一个函数时,尾部调用优化会导致丢失栈帧。

对于 OpenMP 程序,使用 -xopenmp=noopt 选项进行编译即指示编译器不要应用任何优化。但是,为了实现 OpenMP 指令,优化器仍会处理代码,因此,使用 -xopenmp=noopt 编译的程序可能会出现所描述的一些问题。

参数与变量

通常,对于优化程序而言,参数、局部变量和全局变量的符号信息可用。结构、联合、C++ 类的类型信息,以及局部变量、全局变量和参数的类型和名称应该可用。

优化代码中有时会缺少有关参数和局部变量的位置的信息。如果 dbx 无法找到值,它会报告无法找到。有时该值可能会临时消失,因此请尝试再次单步执行和输出。

适用于基于 SPARC 的系统和基于 x86 的系统的 Oracle Solaris Studio 12.2 编译器将提供用于查找参数和局部变量的信息。较新的 GNU 编译器版本也提供此信息。

尽管在尚未发生最终寄存器至内存存储的情况下全局变量的值可能不准确,但您仍可以输出全局变量并为这些变量赋值。

内联函数

在 SPARC 平台上,dbx 允许在内联函数上设置断点。当在调用方中执行内联函数的第一条指令时,控制将会停止。可以对内联函数执行的 dbx 操作(例如 stepnextlist 命令)与非内联函数相同。

where 命令显示调用栈以及内联函数和参数(如果内联函数的位置信息可用)。

还支持对内联函数使用用于上下移动调用栈的 updown 命令。

调用方的局部变量在内联框架中不可用。

寄存器(如果显示)来自调用方的窗口。

编译器可能进行内联的函数包括 C++ 内联函数、具有 C99 内联关键字的 C 函数以及编辑器认为可以提高性能的任何其他函数。

性能分析器手册第 8 章的“函数内联”和“并行化”两部分包含有助于进行优化程序调试的信息。

编译时未使用 -g 选项的代码

虽然大多数调试支持要求使用 -g 选项编译程序,但 dbx 仍为未使用 -g 选项进行编译的代码提供以下级别的支持:

但请注意,除非用 -g 选项编译代码,否则 dbx 无法显示源代码。此限制也适用于使用 strip -x 的代码。

共享库要求使用 -g 选项以获得完全 dbx 支持

要获得完全支持,共享库也必须使用 -g 选项进行编译。如果利用没有使用 -g 选项进行编译的共享库模块来生成程序,则仍可以调试该程序。但由于未为这些库模块生成信息,所以无法获得完全 dbx 支持。

完全剥离的程序

dbx 能够调试已完全剥离的程序。这些程序包含一些可用来调试程序的信息,但只有外部可见函数可用。有些运行时检查对剥离的程序或装入对象有效:内存使用检查有效,访问检查对使用 strip -x 剥离的代码有效,但对使用 strip 剥离的代码无效。