Oracle Solaris Studio 12.2 Discover 和 Uncover 用户指南

未校验的代码

有时,Discover 无法完整地校验您的程序。某些代码可能来自无法重新编译的汇编语言源文件或第三方库,因此无法校验。Discover 并不知道未校验代码正在访问和修改的内存块。例如,假定某个第三方共享库中的某个函数初始化了一个内存块,主程序(校验过的程序)稍后读取了该内存块。由于 Discover 并不知道该库已初始化内存,后续读取操作将生成未初始化内存错误 (UMR)。

为解决此类问题,Discover API 中包含了下列函数:


void __ped_memory_write(unsigned long addr, long size, unsigned long pc);
void __ped_memory_read(unsigned long addr, long size, unsigned long pc);
void __ped_memory_copy(unsigned long src, unsigned lond dst, long size, unsigned long pc);

您可以从程序调用这些 API 函数,将具体事件告知 Discover,例如,向内存区写入 (__ped_memory_write()) 或从内存区读取 (__ped_memory read())。对于这两种情况,内存区的起始地址将通过 addr 参数传递,内存区的大小通过 size 参数传递。将 pc 参数设置为 0

使用 __ped_memory_copy 函数告知 Discover 正在将内存从一个位置复制到另一个位置。源内存的起始地址将通过 src 参数传递,目标区的起始地址通过 dst 参数传递,大小通过 size 参数传递。将 pc 参数设置为 0

要使用 API,请在程序中将这些函数声明为弱函数。例如,在源代码中包含以下代码片段。


#ifdef __cplusplus
extern "C" {
#endif

extern void __ped_memory_write(unsigned long addr, long size, unsigned long pc);
extern void __ped_memory_read(unsigned long addr, long size, unsigned long pc);
extern void __ped_memory_copy(unsigned long src, unsigned long dst, long size, unsigned long pc);

#prgama weak __ped_memory_write
#pragma weak __ped_memory_read
#pragma weak __ped_memory_copy

#ifdef __cplusplus
}
#endif

API 函数是在内部 Discover 库中定义的,该库在校验时链接到程序。但是,如果未校验程序,便不会链接该库,这样,对 API 函数的所有调用都会导致应用程序挂起。因此,如果不是在 Discover 下运行程序,则必须禁用这些函数。另外,您也可以使用 API 函数的空定义创建一个动态库,并将其链接到程序。在此情况下,如果您未在 Discover 下运行程序,将使用您的库,但如果在 Discover 下运行程序,将自动调用实际的 API 函数。