准备好目标二进制文件后,下一步就是对其进行检测。检测会在关键位置添加代码,以便 discover 可以在二进制文件运行时跟踪内存操作。
可使用 discover 命令检测二进制文件。例如,以下命令将检测二进制文件 a.out,并使用检测过的 a.out 来覆盖输入 a.out:
discover a.out
当运行检测过的二进制文件时,discover 会监视程序对内存的使用。在运行过程中,discover 会将详细说明任何内存访问错误的报告写入一个 HTML 文件,您可以在 Web 浏览器中查看该文件。缺省文件名为 a.out.html。要请求将报告写入 ASCII 文件或 stderr,请在检测二进制文件时使用 –w 选项。
要指定您希望 discover 对二进制文件执行仅写入检测,请使用 –n 选项。
当 discover 检测二进制文件时,如果发现任何由于未注释而导致其无法检测的代码,将显示与以下内容类似的警告:
discover: (warning): a.out: 80% of code instrumented (16 out of 20 functions)
无注释代码可能来自链接到二进制文件中的汇编语言代码,或者来自使用早于正确准备二进制文件中所列版本的编译器或操作系统编译的模块。
当 discover 检测二进制文件时,会向与运行时链接程序一起工作的二进制文件中添加代码,以便在运行时装入相关的共享库时对其进行检测。检测过的库存储在高速缓存中;如果原始库自上次检测以来未发生更改,可以重新使用这些库。缺省情况下,高速缓存目录为 $HOME/SUNW_Bit_Cache。可以使用 –D 选项更改该目录。
如果检测整个程序(包括所有共享库),discover 实用程序会生成最准确的结果。 缺省情况下,discover 仅检查并报告可执行文件中的内存错误。要指定您希望 discover 跳过对可执行文件中错误的检查,请使用 –n 选项。
可以使用 –c 选项指定希望 discover 检查相关共享库和通过 dlopen() 动态打开的库中的错误。还可以使用 –c 选项避免检查特定的库中的错误。 尽管 discover 不报告该库中的任何错误,但由于其需要跟踪整个地址空间的内存状态以正确检测内存错误,因此会记录整个程序(包括共享库)中的分配和内存初始化。
discover 实用程序运行时使用链接程序审计接口(也称为 rtld-audit 或 LD_AUDIT)从 discover 的高速缓存目录自动装入检测过的共享库。在 Oracle Solaris 上,缺省情况下使用审计接口。在 Linux 上,当运行检测过的二进制文件时,需要在命令行上设置 LD_AUDIT。
对于 Oracle Linux 上的 32 位应用程序:
% LD_AUDIT=install-dir/lib/compilers/postopt/bitdl.so a.out
对于 Oracle Linux 上的 64 位应用程序:
% LD_AUDIT=install-dir/lib/compilers/postopt/amd64/bitdl.so a.out
该机制可能不会在所有运行 Oracle Enterprise Linux 5.x 的环境中起作用。如果不需要库检测并且未设置 LD_AUDIT,则 discover 在 Oracle Enterprise Linux 5.x 上没有问题。
应根据正确准备二进制文件中的说明准备程序使用的所有共享库。缺省情况下,如果运行时链接程序遇到一个未准备好的库,会发生致命错误。不过,您可以指示 discover 忽略一个或多个库。
您可能无法准备或检测某些库。 可以使用 –s、–T 或 –N 选项(请参见检测选项)或通过在 bit.rc 文件中进行指定(请参见bit.rc 初始化文件)指示 discover 忽略这些库。 可能会损失一些准确性。
如果某个库无法检测,且无法标识为可忽略,discover 将在检测时失败,或者程序将在运行时失败并出现错误消息。
缺省情况下,discover 通过在系统 bit.rc 文件中进行指定来将某些系统和编译器提供的库设置为忽略(因为没有准备这些库)。由于 discover 了解最常用库的内存特征,因此,对准确性的影响微乎其微。
可以使用 –c 选项指定某个可执行文件或库。可以通过将内存访问检查限定至某些目标文件来进一步限定目标可执行文件或目标库。
例如,如果目标库为 libx.so 并且目标可执行文件为 a.out,则可使用以下命令:
$ discover -c libx.so -o a.out.disc a.out
还可以通过添加冒号分隔的文件或目录来限制对任何目标的检查。文件可以是 ELF 文件或目录。如果指定 ELF 文件,则会检查文件中定义的所有函数。如果指定目录,则会递归使用目录中的所有文件。
$ discover -o a.out.disc a.out:t1.0:dir
$ discover -c libx.so:l1.o:12.o -o a.out.disc a.out
您可以将以下选项与 discover 命令结合使用来检测二进制文件。
将错误数据写入 binary-name.analyze/dynamic 目录以供代码分析器使用。
运行检测过的程序时会自动启动 Web 浏览器 browser(缺省情况下为 off)。
仅在报告中显示 n 个内存错误(缺省情况下显示所有错误)。
仅在报告中显示 n 个内存泄漏(缺省情况下显示 100 个)。
在报告中显示偏移(缺省情况下隐藏偏移)。
将 discover 有关二进制文件的报告以 HTML 格式写入 html-file。此文件是在您运行检测过的二进制文件时创建的。如果 html-file 是相对路径名,则会相对于您在其中运行检测过的二进制文件的工作目录放置该文件。要使文件名在您每次运行二进制文件时都是唯一的,请将字符串 %p 添加到文件名中,以指示 discover 运行时包含进程 ID。例如,选项 –H report.%p.html 生成文件名为 report.process-ID.html 的报告文件。如果在文件名中多次包含 %p,则仅将第一个实例替换为进程 ID。
如果您未指定该选项或 –w 选项,则以 HTML 格式将报告写入 output-file.html,其中 output-file 是检测过的二进制文件的基名。该文件位于您运行检测过的二进制文件时所在的工作目录中。
您可以同时指定此选项和 –w 选项,同时以文本和 HTML 格式写入报告。
在报告中显示改编名称(缺省为显示取消改编名称)。
将检测过的二进制文件写入 file。缺省情况下,检测过的二进制文件会覆盖输入二进制文件。
仅在报告中显示 n 个堆栈帧(缺省情况下显示 8 个)。
将 discover 有关二进制文件的报告写入 text-file。该文件是在您运行检测过的二进制文件时创建的。如果 text-file 是相对路径名,则会相对于您在其中运行检测过的二进制文件的工作目录放置该文件。要使文件名在您每次运行二进制文件时都是唯一的,请将字符串 %p 添加到文件名中,以指示 discover 运行时包含进程 ID。例如,选项 –w report.%p.txt 生成文件名为 report.process-ID.txt 的报告文件。如果在文件名中多次包含 %p,则仅将第一个实例替换为进程 ID。指定 –w - 将在 stderr 中输出。
如果您未指定该选项或 –H 选项,则以 HTML 格式将报告写入 output-file.html,其中 output-file 是检测过的二进制文件的基名。该文件位于您运行检测过的二进制文件时所在的工作目录中。
您可以同时指定此选项和 –H 选项,同时以文本和 HTML 格式写入报告。
打开/关闭分配/释放堆栈跟踪(堆栈深度为 8 时缺省值为 on)。仅当针对硬件辅助检查进行检测时,才可以使用 –i adi 选项指定此标志。要获得更好的运行时性能,可以使用此选项关闭分配/释放堆栈跟踪收集。仅当安装了 Oracle Solaris Studio 12.4 4/15 平台特定增强 (Platform Specific Enhancement, PSE) 时,才能使用此选项。
检查所有库中、指定的 library 中或指定的 file 中列出且由新行分隔的库中的错误。缺省设置为不检查库中的错误。可以通过添加冒号分隔的文件或目录来限制对库进行检查的范围。有关更多信息,请参见检查库或可执行文件的部分。
指定如果您已使用 discover 检测的二进制文件在运行时派生,您希望发生什么情况。缺省情况下,discover 继续从父进程和子进程收集内存访问错误数据。如果您希望 discover 仅跟随父进程,则指定 –F parent。如果您希望 Discover 仅跟随子进程,则指定 –F child。
确定 discover 的检测类型(缺省值为 memcheck)。
如果指定了 datarace,则使用线程分析器针对数据争用检测进行检测。如果使用此选项,仅在运行时执行数据争用检测,而不执行其他任何内存检查。必须使用 collect 命令运行检测过的二进制文件,以生成可以在性能分析器中查看的实验。有关更多信息,请参见Oracle Solaris Studio 12.4:线程分析器用户指南 。 如果指定了 memcheck,则会针对内存错误检查进行检测。 如果指定了 adi,则会使用 SPARC M7 处理器的 ADI 功能针对硬件辅助检查进行检测。只有在 SPARC M7 处理器上运行的 Oracle Solaris 11.3 中,才能使用此功能。仅当安装了 Oracle Solaris Studio 12.4 4/15 平台特定增强 (Platform Specific Enhancement, PSE) 时,才能使用 –i adi 选项。
不读取 bit.rc 初始化文件(请参见bit.rc 初始化文件)。
在轻量模式下运行 discover。使用该选项可更快地执行程序,不必专门准备程序,但检测到的错误数会受到限制。
不检查可执行文件中的错误。
不检测与前缀 library 匹配的任何相关共享库。如果库名称的前几个字符与 library 匹配,则忽略该库。如果 library 以斜杠 (/) 开头,则在库的完整绝对路径名上执行匹配。否则,根据库的基本名称进行匹配。
打开或关闭精确 ADI 模式。缺省值为 on。仅当针对硬件辅助检查进行检测时,才可以使用 –i adi 选项指定此标志。要获得更好的运行时性能,可以使用此选项关闭精确 ADI 模式。仅当安装了 Oracle Solaris Studio 12.4 4/15 平台特定增强 (Platform Specific Enhancement, PSE) 时,才能使用此选项。
如果尝试检测不可检测的二进制文件,将会发出警告,但不标记错误。
仅检测命名的二进制文件。在运行时不检测任何相关的共享库。
将 cache-directory 用作用于存储高速缓存的已检测二进制文件的根目录。缺省情况下,高速缓存目录为 $HOME/SUNW_Bit_Cache。
强制重新检测高速缓存中找到的所有库。
discover 实用程序通过在启动时读取一系列 bit.rc 文件来初始化其状态。系统文件 Oracle-Solaris-Studio-installation-directory/prod/lib/bit.rc 提供某些变量的缺省值。discover 实用程序首先读取该文件,接着读取 $HOME/.bit.rc(如果存在),然后读取 current-directory/.bit.rc(如果存在)。
bit.rc 文件包含用于设置、附加或删除某些变量值的命令。当 discover 读取 set 命令时,会放弃变量以前的值(如果有)。当读取 append 命令时,会将参数附加到变量的现有值(该参数置于冒号分隔符后面)。当读取 remove 命令时,将从变量的现有值中删除参数及其冒号分隔符。
bit.rc 文件中设置的变量包括检测时要忽略的库列表,以及计算库中无注释(未准备)代码百分比时要忽略的函数或函数前缀的列表。
有关更多信息,请参阅系统 bit.rc 文件头中的注释。