Oracle® Developer Studio 12.5:使用 dbx 调试程序

退出打印视图

更新时间: 2016 年 6 月
 
 

运行时检查限制

本节介绍了运行时检查的限制。

使用更多的符号和调试信息提高性能

访问检查需要装入对象的某些符号信息。当装入对象被完全剥离时,运行时检查可能无法捕获所有的错误。从未初始化的 (rui) 内存错误进行读取可能会出错,因而会被抑制。可以使用 unsuppress rui 命令覆盖抑制。要保留装入对象的符合表,请在剥离装入对象时使用 –x 选项。

运行时检查无法捕获所有数组越界错误。如果没有调试信息,针对静态内存和堆栈内存的边界检查不可用。

SIGSEGVSIGALTSTACK 信号在 x86 平台上受限制

运行时检查为访问检查检测内存访问指令。这些指令由 SIGSEGV 处理程序在运行时处理。由于运行时检查需要其自己的 SIGSEGV 处理程序和信号备用堆栈,所以尝试安装 SIGSEGV 处理程序或 SIGALTSTACK 处理程序会导致发生 EINVAL 错误或忽略该尝试。

SIGSEGV 处理程序的调用不能被嵌套。如果嵌套,则会导致 terminating signal 11 SEGSEGV 错误。如果收到此错误,请使用 rtc skippatch 命令跳过受影响函数的检测过程。

当 8 MB 的所有现有代码中具有足够的修补程序区时性能将提高(仅限 SPARC 平台)。

    如果 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 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) 手册页。