跳过导航链接 | |
退出打印视图 | |
Oracle Solaris Studio 12.3:使用 dbx 调试程序 Oracle Solaris Studio 12.3 Information Library (简体中文) |
运行时检查具有以下限制。
访问检查需要装入对象的某些符号信息。当装入对象被完全剥离时,运行时检查可能无法捕获所有的错误。从未初始化的内存错误进行读取可能会出错,因而会被抑制。可以使用 unsuppress rui 命令覆盖抑制。要保留装入对象的符合表,请在剥离装入对象时使用 -x 选项。
运行时检查无法捕获所有数组越界错误。如果没有调试信息,针对静态内存和堆栈内存的边界检查不可用。
运行时检查为访问检查检测内存访问指令。这些指令由 SIGSEGV 处理程序在运行时处理。由于运行时检查需要其自己的 SIGSEGV 处理程序和信号备用堆栈,所以尝试安装 SIGSEGV 处理程序或 SIGALTSTACK 处理程序会导致发生 EINVAL 错误或忽略该尝试。
SIGSEGV 处理程序的调用不能被嵌套。如果嵌套,则会导致 terminating signal 11 SEGSEGV 错误。如果收到此错误,请使用 rtc skippatch 命令跳过受影响函数的检测过程。
如果 8 MB 的所有现有代码中没有足够的补丁区域,则可能会引发两个问题
缓慢
如果启用了访问检查,dbx 会用分支到一个补丁区域的分支指令来替换每一个装入和存储指令。此分支指令寻址范围为 8 MB。如果被调试程序用完了替换的特定装入或存储指令的所有 8 MB 地址空间,将没有空间来存放补丁区域。在这种情况下,dbx 会调用陷阱处理程序而不是使用分支。将控制权移交给陷阱处理程序的过程非常缓慢(最多会慢 10 倍),但不受 8 MB 限制。
V8+ 模式中的输出寄存器覆盖问题
如果同时符合以下两个条件,则陷阱处理程序限制会影响访问检查:
被调试的进程使用陷阱进行检测。
进程使用 V8+ 指令集。
出现问题的原因是,V8+ 体系结构中输出寄存器和输入寄存器的大小不相同。输出寄存器的长度为 64 位,而输入寄存器仅为 32 位。当调用陷阱处理程序时,输出寄存器被复制到输入寄存器,而较高的 32 位会丢失。因此,如果被调试的进程使用输出寄存器的高 32 位,则启用访问检查时该进程可能会以不正确的方式运行。
缺省情况下,创建基于 SPARC 的 32 位二进制文件时,编译器使用 V8+ 体系结构,但您可以使用 -xarch 选项来通知编译器使用 V8 体系结构。遗憾的是,重新编译应用程序不会影响系统运行时库。
dbx 会自动跳过以下函数和库(已知使用陷阱进行检测时不能正常工作)的检测过程:
server/libjvm.so
client/libjvm.so
`libfsu_isa.so`__f_cvt_real
`libfsu_isa.so`__f90_slw_c4
但是,跳过检测过程可能会导致不正确的 RTC 错误报告。
如果上述任一条件适用于您的程序,并且在启用访问检查时程序的行为方式开始有所不同,则可能是陷阱处理程序限制影响到您的程序。要变通克服这些限制,您可以执行以下操作:
使用 rtc skippatch 命令(请参见rtc skippatch 命令)跳过使用上面所列函数和库的程序代码的检测过程。通常,很难跟踪某个特定函数的问题,所以您可能需要跳过整个装入对象的检测过程。rtc showmap 命令可显示按地址排序的检测类型图。
尝试使用 64 位 SPARC-V9 而不使用 32 位 SPARC-V8
如果可能,重新编译 V9 体系结构的程序,在该体系结构中,所有的寄存器长度为 64 位。
尝试添加补丁区域目标文件。
可以使用 rtc_patch_area shell 脚本创建特殊的 .o 文件,这些文件可以链接到大型可执行文件或共享库的中间,从而可以提供更多补丁空间。请参见 rtc_patch_area(1) 手册页。
如果 dbx 达到 8 MB 限制,它会告知哪个装入对象过大(主程序还是共享库),并会输出该装入对象所需的补丁空间总量。
为了得到最佳结果,应在可执行文件或共享库中均匀分布这些特殊的补丁目标文件,并应使用缺省大小 (8 MB) 或更小的大小。另外,添加的补丁空间不要超过 dbx 指出的所需大小的 10-20%。例如,如果 dbx 指出需要 31 MB 用于 a.out,请添加使用 rtc_patch_area 脚本创建的四个目标文件,每个大小均为 8 MB,然后在可执行文件中大致平均地分布这些文件。
如果 dbx 在可执行文件中找到显式补丁区域,则会打印这些补丁区域跨越的地址范围,这有助于将它们正确地置于链接行上。
尝试将较大的装入对象分解为较小的装入对象。
将可执行文件或大型库中的目标文件分解成较小的多组目标文件。然后将它们链接成较小的部分。如果大型文件是可执行文件,则将其分解成较小的可执行文件和一系列共享库。如果大型文件是共享库,则将其重新安排成一组较小的库。
dbx 可利用这一技术在不同的共享对象间为补丁代码寻找空间。
尝试添加“填充”.so 文件。
只有当要连接已启动的进程时,才需要采用此解决方案。
运行时链接程序可能会将各库非常紧密地放置在一起,造成无法在库之间的间隙中创建补丁空间。如果 dbx 在启用了运行时检查的情况下启动可执行文件,它会要求运行时链接程序在共享库之间留出额外的间隙;但如果连接的进程不是由 dbx 在启用了运行时检查的情况下启动的进程,这些库之间可能会非常靠近。
如果运行时库之间太近,(且如果无法使用 dbx 启动程序),则可以尝试使用 rtc_patch_area 脚本创建一个共享库,然后将其链接到其他共享库之间的程序中。有关更多详细信息,请参见 rtc_patch_area(1) 手册页。