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

使用访问检查

访问检查通过监视每个读取、写入、分配和释放操作来检查程序是否正确访问内存。

程序可能会以各种方式错误读取或写入内存,这些都称为内存访问错误。例如,程序可能会引用已通过 free() 调用针对堆块释放的内存块。另外,函数可能会将指针返回给局部变量,这样,访问该指针时,便会出现错误。访问错误可能会导致程序中指针混乱,并可导致程序行为异常,包括输出错误和段违规。某些类型的内存访问错误很难跟踪。

运行时检查保存有一个跟踪程序使用的每个内存块状态的表。运行时检查会将每个内存操作与其涉及的内存块的状态进行对照,然后确定相应操作是否有效。可能的内存状态包括:

使用运行时检查来查找内存访问错误与使用编译器查找程序中的语法错误没有什么不同。在这两种情况下,都会生成错误列表,并提供与每个错误对应的错误消息,说明出错原因和程序中的出错位置。在这两种情况下,应该从错误列表的顶部开始依次向下修复程序中的错误。在链锁反应下,一个错误可导致其他错误发生。因此,链中的第一个错误是“首要原因”,修复该错误后,便可能会修复一些后续的错误。

例如,从未初始化的内存区进行读取会创建不正确的指针,这样,取消其引用时,便会导致出现其他无效的读取或写入,而这又会导致出现另一个错误。

理解内存访问错误报告

运行时检查会输出以下有关内存访问错误的信息:

错误  

信息  

type

错误类型。 

access

尝试访问的类型(读取或写入)。 

size

尝试访问的大小。 

address

尝试访问的地址。 

size

泄漏块的大小。 

detail

有关地址的更多详细信息。例如,如果地址在邻近栈中,便会提供其相对当前栈指针的位置。如果地址在堆中,便会提供最近堆块的地址、大小和相对位置。 

stack

出错时调用栈(批处理模式)。 

allocation

如果地址在堆中,便会提供最近堆块的分配跟踪。 

location

出错位置。如果有行号信息,则此信息包括行号和函数。如果无行号,运行时检查会提供函数和地址。 

以下示例显示的是一个典型的访问错误。


Read from uninitialized (rui):
Attempting to read 4 bytes at address 0xefffee50
    which is 96 bytes above the current stack pointer
Variable is ”j’
Current function is rui
   12           i = j;

内存访问错误

运行时检查会检测下列内存访问错误: