Oracle Solaris Studio 12.2 Discover 和 Uncover 用户指南

使用 Discover 时的限制

仅校验有注释的代码

Discover 只能校验按照必须正确准备二进制文件中的说明准备的代码。无注释代码可能来自链接到二进制文件中的汇编语言代码,或者来自使用早于该部分中所列版本的编译器或操作系统编译的模块。

在准备时,特别要排除包含 asm 语句或 .il 模板的汇编语言模块和函数。

计算机指令可能不同于源代码

Discover 处理计算机代码。该工具可检测到装入和存储等计算机指令中的错误,并将这些错误与源代码相关联。某些源代码语句没有关联的计算机指令,因此,看上去 Discover 没有检测到明显的用户错误。例如,请看以下 C 语言代码片段:

  int *p = (int *)malloc(sizeof(int));
  int i;

  i = *p;  /* compiler may not generate code for this statement */
  printf("Hello World!\n");

  return;

由于内存未初始化,读取 p 所指向的地址处存储的值就是一个潜在的用户错误。但是,优化编译器可以检测到未使用变量 i,因此,不会生成让语句读取内存并将其分配到 i 的代码。在此情况下,Discover 不会报告使用了未初始化内存 (UMR)。

编译器选项影响生成的代码

编译器生成的代码不一定始终如您所愿。由于编译器生成的代码因所使用的编译器选项(包括 -On 优化选项)的不同而异,因此,Discover 报告的错误也可能有所不同。例如,在 -O1 优化级别上生成的代码中报告的错误可能不会出现于在 -O4 优化级别上生成的代码中。

系统库可能会影响报告的错误

系统库是随操作系统一起预装的,无法重新编译以进行校验。Discover 为标准 C 库 (libc.so) 中的公用函数提供支持;也就是说,Discover 知道这些函数访问或修改的内存。但是,如果应用程序使用了其他系统库,可能会在 Discover 报告中出现误报。如果出现误报,可以从代码调用 Discover API 来消除误报。

自定义内存管理可能会影响数据的准确性

Discover 可以跟踪标准编程语言机制(例如 malloc()calloc()free()operator new()operator delete())分配的堆内存。

如果应用程序使用在标准函数顶层工作的自定义内存管理系统(例如,使用 malloc() 实现的池分配管理),则 Discover 仍会运行,但不能保证正确报告泄漏或对已释放内存的访问。

Discover 不支持下列内存分配器:

不支持 sigaltstack(2)() 函数。

无法检测到静态和自动数组的超出边界错误

由于检测数组边界所用的算法问题,Discover 无法检测到静态和自动(本地)数组的超出边界访问错误。只能检测动态分配数组的错误。