Red Hat Training

A Red Hat training course is available for RHEL 8

3.3. 记录应用程序互动

应用程序的可执行代码与操作系统和共享库的代码交互。记录这些交互的活动日志可在不调试实际应用程序代码的情况下充分洞察应用的行为。另外,分析应用的交互可以帮助确定错误清单的条件。

3.3.1. 用于记录应用程序交互的工具

红帽企业 Linux 提供用于分析应用程序的交互的多种工具。

strace

The strace 工具主要支持记录供应用使用的系统调用(内核功能)。

  • The strace 工具可以提供有关调用的详细输出,因为 strace 知道底层内核代码来解读参数和结果。数字转换为对应的恒定名称,展开为标记列表的组合标志,指向字符数组的指针被解引用以提供实际字符串等。可能缺少对更新内核功能的支持。
  • 您可以过滤跟踪的调用来减少捕获的数据量。
  • 使用 strace 不需要任何特定设置,除了设置日志过滤器外。
  • 使用 strace 跟踪应用代码导致应用的执行出现显著下降。因此,strace 不适用于许多生产部署。作为替代方案,请考虑使用 ltrace 或 SystemTap。
  • Red Hat Developer Toolset 中提供的 strace 版本也可以执行系统调用修改。此功能对于调试非常有用。
ltrace

ltrace 工具支持将应用的用户空间调用记录到共享对象(动态库)。

  • ltrace 工具启用对任何库的追踪调用。
  • 您可以过滤跟踪的调用来减少捕获的数据量。
  • 使用 ltrace 不需要任何特定设置,除了设置日志过滤器外。
  • ltrace 工具是轻量级且快速的,它提供了 strace的 替代选择:可以使用 l trace 跟踪库中的对应接口,而不是通过 trace 跟踪内核功能
  • 因为 ltrace 不会处理一组已知的调用,如 trace, 所以它不会试图解释传递给库函数的值。ltrace 输出仅包含原始数字和指针。对 ltrace 输出的解释需要咨询输出中存在的库的实际接口声明。
注意

在 Red Hat Enterprise Linux 8 中,一个已知问题会阻止 ltrace 追踪系统可执行文件。此限制不适用于用户构建的可执行文件。

SystemTap

SystemTap 是一个检测平台,用于在 Linux 系统上探测运行中的进程和内核活动。SystemTap 使用自己的脚本语言来编程自定义事件处理程序。

  • 与使用 straceltrace 相比,编写日志意味着在初始设置阶段有更多工作。但是,该脚本功能将 SystemTap 的用处扩展至生成日志之外。
  • SystemTap 通过创建和插入内核模块来工作。SystemTap 的使用效率更高,不会自行造成系统或应用执行的显著下降。
  • SystemTap 附带了一组使用示例。
GDB

GNU Debugger(GDB)主要用于调试,而不是记录。但是,其某些功能即使在应用程序交互是关注的主要活动的情况下也使其有用。

  • 借助 GDB,可以将交互事件的捕获和后续执行路径的即时调试轻松结合在一起。
  • 在其他工具最初识别问题的情况下,GDB 最适合分析对不常见的事件或单数事件的响应。在任何有频繁事件的情况下使用 GDB 都会变得效率低下甚至不可能。

3.3.2. 使用 strace 监控应用的系统调用

The strace 工具启用监控应用执行的系统(内核)调用。

流程

  1. 确定要监控的系统调用。
  2. Start strace 并将其附加到 程序。

    • 如果您要监控的程序没有运行,请启动 追踪 并指定 程序

      $ strace -fvttTyy -s 256 -e trace=call program
    • 如果程序已在运行,请查找其进程 ID(pid) 并附加至 该程序:

      $ ps -C program
      (...)
      $ strace -fvttTyy -s 256 -e trace=call -ppid
    • call 替换为要显示的系统调用。您可以多次使用 -e trace=call 选项。如果遗漏,strace 将显示所有系统调用类型。如需更多信息,请参阅 strace(1) 手册页。
    • 如果您不想跟踪任何分叉的进程或线程,请退出 -f 选项。
  3. strace 工具显示应用程序发出的系统调用及其详细信息。

    在大多数情况下,如果未设置系统调用过滤器,应用及其库都会立即发出大量调用和 strace 输出。

  4. 当程序退出时,The strace 工具会退出。

    要在 traced 程序退出前终止监控,请按 Ctrl+C

    • If strace 启动程序,程序与 strace 一起终止。
    • 如果您 将 trace 附加到 已在运行的程序,程序会一起终止
  5. 分析应用执行的系统调用列表。

    • 当调用返回错误时,日志中会出现与资源访问或可用性相关的问题。
    • 传递给系统调用和调用序列模式的值可让您了解应用程序的原因。
    • 如果应用崩溃,重要信息或许位于日志的末尾。
    • 输出中包含大量不必要的信息。但是,您可以为感兴趣的系统调用构建更精确的过滤器,并重复该过程。
注意

益处是查看输出并将其保存到文件中。使用 tee 命令实现这一点:

$ strace ... |& tee your_log_file.log

其他资源

3.3.3. 使用 ltrace 监控应用程序的库功能调用

ltrace 工具支持监控应用程序对库中可用功能(共享对象)的调用。

注意

在 Red Hat Enterprise Linux 8 中,一个已知问题会阻止 ltrace 追踪系统可执行文件。此限制不适用于用户构建的可执行文件。

流程

  1. 识别感兴趣的库和功能(如果可能)。
  2. 启动 ltrace 并将其附加到 程序。

    • 如果您要监控的程序没有运行,请启动 ltrace 并指定 程序

      $ ltrace -f -l library -e function program
    • 如果程序已在运行,请查找其进程 ID(pid)并附加 ltrace 到其中:

      $ ps -C program
      (...)
      $ ltrace -f -l library -e function program -ppid
    • 使用 -e-f-l 选项过滤输出:

      • 提供要显示为 function 的函数名称。e 函数 选项可多次使用。如果遗漏,ltrace 会显示对所有功能的调用。
      • 您可以使用 -l 选项指定整个库,而不是指定函数。这个选项的行为与 -e 函数 选项类似。
      • 如果您不想跟踪任何分叉的进程或线程,请退出 -f 选项。

      如需更多信息,请参阅 ltrace(1)_ 手册页。

  3. ltrace 显示应用发出的库调用。

    在大多数情况下,如果未设置过滤器,应用会立即发出大量调用和 ltrace 输出。

  4. 当程序 退出时,ltrace 会退出。

    要在 traced 程序退出前终止监控,请按 enter ctrl+C

    • 如果 ltrace 启动了程序,程序会一起使用 ltrace 终止。
    • 如果您将 ltrace 附加到已在运行的程序,程序会一起终止 ltrace
  5. 分析应用执行的库调用列表。

    • 如果应用崩溃,重要信息或许位于日志的末尾。
    • 输出中包含大量不必要的信息。但是,您可以构建一个更精确的过滤器并重复该过程。
注意

益处是查看输出并将其保存到文件中。使用 tee 命令实现这一点:

$ ltrace ... |& tee your_log_file.log

其他资源

  • ltrace(1) 手册页:

    $ man ltrace
  • Red Hat Developer Toolset 用户指南 - 第 ltrace

3.3.4. 使用 SystemTap 监控应用的系统调用

SystemTap 工具启用为内核事件注册自定义事件处理程序。与 strace 工具相比,它更难使用,但更有效,并支持更复杂的处理逻辑。SystemTap 脚本名为 trace.stp, 与 SystemTap 一同安装,并且使用 SystemTap 提供对 strace 功能的估测。

流程

  1. 查找您要监控的进程的进程 ID(pid):

    $ ps -aux
  2. 使用 the strace.stp 脚本运行 SystemTap:

    # stap /usr/share/systemtap/examples/process/strace.stp -x pid

    pid 的值是进程 ID。

    脚本编译到内核模块,然后载入该模块。这在输入命令和获取输出之间引入了一些延迟。

  3. 当进程执行系统调用时,调用名称及其参数将打印到终端。
  4. 当进程终止或按 Ctrl+C 时,脚本将退出。

3.3.5. 使用 GDB 截获应用程序系统调用

GNU Debugger(GDB)可让您在程序执行过程中出现的各种情况下停止执行。要在程序执行系统调用时停止执行,请使用 GDB 捕获点

流程

  1. 设置捕获点:

    (gdb) catch syscall syscall-name

    捕获系统调用的命令 设置一种特殊的断点类型,在程序执行系统调用时停止执行。

    syscall-name 选项指定调用的名称。您可以为各种系统调用指定多个捕获点。退出 syscall-name 选项会导致 GDB 在任何系统调用时停止。

  2. 开始执行 程序。

    • 如果程序还没有开始执行,请启动它:

      (gdb) r
    • 如果程序执行被停止,恢复它:

      (gdb) c
  3. GDB 在程序执行任何指定系统调用后停止执行。

3.3.6. 使用 GDB 截获应用程序处理信号

GNU Debugger(GDB)可让您在程序执行过程中的不同情况下停止执行。要在程序收到操作系统信号时停止执行,请使用 GDB 捕获点

流程

  1. 设置捕获点:

    (gdb) catch signal signal-type

    命令 捕获信号 会设置一种特殊的断点类型,它会在程序收到信号时暂停执行。signal-type 选项指定信号的类型。使用特殊值 'all' 来 捕获所有信号。

  2. 让程序运行。

    • 如果程序还没有开始执行,请启动它:

      (gdb) r
    • 如果程序执行被停止,恢复它:

      (gdb) c
  3. GDB 在程序收到任何指定信号后停止执行。