Sun Studio 12:使用 dbx 调试程序

调试优化代码

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

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

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

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

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

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

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

优化代码中经常缺少有关参数和局部变量的位置的信息。如果编译器生成 Dwarf 位置列表,则 dbx 将使用该信息输出局部变量和参数的值。如果在优化函数的第一个指令处停止,则 dbx 可输出参数的值,因为这些值将位于符合 ABI 标准的寄存器或栈位置中。要查看局部变量的值,可能还需要设置 dbx 环境变量 optim_local_vars

调试信息中的一个简单位置描述了一个寄存器或栈位置。位置列表描述了变量在代码中不同点的不同位置,使得位置列表能够更好地描述优化代码。

从 Sun Studio 12 发行版开始,Sun Studio 编译器将不生成位置列表,但会针对某些优化代码生成简单位置。更新版本的 GNU 编译器使用位置列表描述帧指针,并描述某些参数和局部变量。编译器记录该信息的方式可能会随发行版不同而异。

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

Sun Studio 11 性能分析器》手册第 8 章介绍了有关编译器优化的信息,这些信息在调试优化程序时可能很有用。

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

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

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

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

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

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

完全剥离的程序

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