Menu Close
Red Hat Training
A Red Hat training course is available for RHEL 8
第 9 章 记录应用程序互动
应用程序的可执行代码与操作系统代码和共享库交互。记录这些交互的活动日志可让您深入了解应用程序的行为,而无需调试实际应用程序代码。或者,分析应用程序的交互有助于找出错误清单的条件。
9.1. 用于记录应用程序交互的工具
Red Hat Enterprise Linux 提供多种工具来分析应用程序的交互。
- strace
strace
工具主要启用应用程序所用系统调用(内核功能)的日志记录。-
strace
工具可提供有关调用的详细输出,因为strace
在了解底层内核代码的情况下解释参数和结果。数字被转换为对应的恒定名称,将位符合并到标志列表,指向字符数组来解引用,以提供实际字符串,等等。可能不支持较新的内核功能。 - 您可以过滤追踪的调用来减少捕获的数据的数量。
-
使用
strace
不需要任何特定的设置,除了设置日志过滤器外。 -
使用
strace
追踪应用程序代码会导致应用程序的执行显著下降。因此,strace
不适合很多生产部署。作为替代,请考虑使用ltrace
或者 SystemTap。 -
Red Hat Developer Toolset 中可用的
strace
版本也可以执行系统调用 tampering。这个功能对调试非常有用。
-
- ltrace
ltrace
工具启用将应用程序的用户空间调用记录到共享对象(动态库)中。-
ltrace
工具启用对任何库的追踪调用。 - 您可以过滤追踪的调用来减少捕获的数据的数量。
-
使用
ltrace
不需要任何特定的设置,除了设置日志过滤器外。 -
ltrace
工具是轻量级和快速的,提供了strace
的替代方案:可以追踪库中的glibc
中的对应接口,并使用ltrace
来追踪使用strace
的内核功能。 -
因为
ltrace
没有处理类似strace
的已知调用,所以它不会尝试解释传递给库功能的值。ltrace
输出只包含原始数字和指针。解释ltrace
输出需要咨询输出中库的实际接口声明。
注意在 Red Hat Enterprise Linux 8.0 中,一个已知问题会阻止
ltrace
追踪系统可执行文件。这个限制不适用于用户构建的可执行文件。-
- SystemTap
SystemTap 是一个工具平台,用于在 Linux 系统上模拟运行的进程和内核活动。SystemTap 使用自己的脚本语言来编程自定义事件处理程序。
-
与使用
strace
和ltrace
相比,脚本化日志记录意味着在初始设置阶段可以进行更多的工作。但是,脚本功能会扩展了 SystemTap 的功能,它超出了生成日志的范围。 - SystemTap 通过创建和插入内核模块来实现。SystemTap 的使用效率高,不会对系统或应用程序本身造成显著下降。
- SystemTap 附带一组使用示例。
-
与使用
- GDB
GNU Debugger(GDB)主要用于调试,而不是记录。然而,在某些特性中,即使应用程序互动是关注的主要活动,也很有用。
- 使用 GDB,可以方便地将交互事件的捕获与立即调试后续执行路径合并。
- 在被其他工具初始发现有问题的情况后,GDB 最适合对罕见或单数事件进行分析。在出现频繁事件的任何场景中使用 GDB 将会变得效率低下甚至无法使用。
9.2. 使用 strace 监控应用程序的系统调用
strace
工具启用监控应用程序执行的系统(内核)调用。
先决条件
流程
- 识别要监控的系统调用。
启动
strace
并将其附加到程序。如果您想要监控的程序没有运行,请启动
strace
并指定 程序:$ strace -fvttTyy -s 256 -e trace=call program
如果程序已在运行,找到其进程 id(pid)并把
strace
附加到它:$ ps -C program (...) $ strace -fvttTyy -s 256 -e trace=call -ppid
-
使用要显示的系统调用替换 call。您可以多次使用该
-e trace=call
选项。如果省略,strace
将显示所有系统调用类型。详情请查看 strace(1) 手册页。 -
如果您不想追踪所有 fork 进程或线程,请保留
-f
选项。
strace
工具显示应用程序的系统调用及其详情。在大多数情况下,如果没有为系统调用设置过滤,则应用程序及其库会发出大量调用,
strace
输出会立即出现。strace
工具在程序退出时退出。要在追踪程序退出前终止监控, 按 Ctrl+C。
-
如果
strace
启动程序,该程序会与strace
一起终止。 -
如果您将
strace
附加到已在运行的程序,该程序会与strace
一起终止。
-
如果
分析应用程序的系统调用列表。
- 日志中存在资源访问或可用性的问题,因为调用返回的错误。
- 传递给系统调用和调用序列模式的值可让您了解应用程序行为的原因。
- 如果应用程序崩溃,则可能需要在日志末尾获得重要信息。
- 输出会包含大量不必要的信息。但是,您可以为系统调用构建一个更加精确的过滤器,并重复这个过程。
查看输出并将其保存到文件中是很有好处的。使用 tee
命令达到此目的:
$ strace ... |& tee your_log_file.log
其它资源
strace(1) 手册页:
$ man strace
- 如何使用 strace 跟踪命令发出的系统调用? - 知识库文章
- Red Hat Developer Toolset User Guide - chapter strace
9.3. 使用 ltrace 监控应用程序的库功能
ltrace
工具允许监控应用程序对库(共享对象)中可用功能的调用。
在 Red Hat Enterprise Linux 8.0 中,一个已知问题会阻止 ltrace
追踪系统可执行文件。这个限制不适用于用户构建的可执行文件。
先决条件
流程
- 若有可能,识别相关的库和功能。
启动
ltrace
并将其附加到程序。如果您想要监控的程序没有运行,请启动
ltrace
并指定 program:$ ltrace -f -l library -e function program
如果程序已在运行,找到其进程 id(pid)并把
ltrace
附加到它:$ ps -C program (...) $ ltrace -f -l library -e function program -ppid
使用
-e
、-f
和-l
选项过滤输出:-
提供要显示为功能的 功能 名称。
-e function
选项可以多次使用。如果省略,ltrace
会显示对所有功能的调用。 -
您可以使用
-l library
选项指定整个库,而不指定功能。这个选项的行为与-e function
选项类似。 -
如果您不想追踪所有 fork 进程或线程,请保留
-f
选项。
如需更多信息,请参阅 ltrace(1)_ 手册页。
-
提供要显示为功能的 功能 名称。
ltrace
显示应用程序发出的库调用。在大多数情况下,如果没有设置过滤器,应用程序会发出大量调用,
ltrace
输出会立即显示。ltrace
程序退出时退出。要在追踪程序退出前终止监控,按 ctrl+C。
-
如果
ltrace
启动程序,该程序会与ltrace
一起终止。 -
如果您将
ltrace
附加到已在运行的程序,该程序会与ltrace
一起终止。
-
如果
分析应用程序进行的库调用列表。
- 如果应用程序崩溃,则可能需要在日志末尾获得重要信息。
- 输出会包含大量不必要的信息。但是,您可以构造一个更精确的过滤器并重复这个步骤。
查看输出并将其保存到文件中是很有好处的。使用 tee
命令达到此目的:
$ ltrace ... |& tee your_log_file.log
其它资源
ltrace(1) 手册页:
$ man ltrace
- Red Hat Developer Toolset User Guide - chapter ltrace
9.4. 使用 SystemTap 监控应用程序的系统调用
SystemTap 工具允许为内核事件注册自定义事件处理程序。与 strace
工具相比,更难以使用,但效率更高,并启用更复杂的处理逻辑。一个名为 strace.stp
的 SystemTap 脚本与 SystemTap 一起安装,并使用 SystemTap 提供 strace
功能的近似值。
流程
查找您要监控的进程 ID(pid):
$ ps -aux
使用
strace.stp
脚本运行 SystemTap:# stap /usr/share/systemtap/examples/process/strace.stp -x pid
pid 的值是进程 id。
该脚本被编译到内核模块中,然后载入该模块。这在输入命令和获取输出之间引入了一些延迟。
- 当进程执行系统调用时,调用名称及其参数会输出到终端。
-
当进程终止或按
Ctrl+C
键时,该脚本会退出。
9.5. 使用 GDB 拦截应用程序系统调用
GNU Debugger(GDB)可让您在程序执行过程中的不同情况下停止执行。要在程序执行系统调用时停止执行,请使用 GDB 捕获点。
流程
设置 catchpoint:
(gdb) catch syscall syscall-name
catch syscall
命令设置一种特殊的 breakpoint 类型,它会在程序执行系统调用时停止执行。syscall-name
选项指定调用的名称。您可以为各种系统调用指定多个捕获点。退出syscall-name
选项会导致 GDB 在任何系统调用中停止。开始执行程序。
如果程序还没有启动执行,请启动它:
(gdb) r
如果停止了程序执行,恢复它:
(gdb) c
- GDB 在执行程序执行任何指定的系统调用后停止执行。
其它资源
- 第 8.4 节 “使用 GDB 显示程序内部值”
- 第 8.3 节 “使用 GDB 通过程序代码步骤”
- 使用 GDB 进行调试 - 设置 Watchpoints
9.6. 使用 GDB 截取应用程序对信号的处理
GNU Debugger(GDB)可让您在程序执行过程中的不同情况下停止执行。要在程序收到操作系统信号时停止执行,请使用 GDB 捕获点。
流程
设置 catchpoint:
(gdb) catch signal signal-type
catch signal
命令设置一种特殊的 breakpoint 类型,它会在程序收到信号时停止执行。signal-type
选项指定信号的类型。使用特殊值'all'
来捕获所有信号。让程序运行。
如果程序还没有启动执行,请启动它:
(gdb) r
如果停止了程序执行,恢复它:
(gdb) c
- GDB 在程序接收任何指定的信号后停止执行。
其它资源