百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

DTrace 和 strace 概述

moboyou 2025-04-09 13:40 19 浏览

使用这些惊人的工具,无需源代码或对环境的深入了解即可跟踪应用程序中的错误及其外部依赖项!


通常,在调试时,我们需要跳出 IDE 的舒适范围来重现或跟踪问题。在本系列中,我想介绍一些您可能会发现对这些情况有用的工具。我会尽量限制自己使用 100% 调试工具,而不是那些对开发测试有用的工具。

例如,curl或jq等工具非常有用。您可以/应该在调试时使用它们。但是您可能在构建和测试功能时使用了它们。因此,您应该已经熟悉它们,并且应该对它们的工作有所了解。我想专注于调试时最常使用的工具。从这个意义上说,SDKMan等工具在这里也没有任何意义。

我还想避免使用数据库工具等工具。它们在调试时非常有用,但同样,您也可能在开发过程中使用它们。它们也是非常特定于供应商的,因此这是一个广泛的主题,无法在此处涵盖。

我将在本系列中介绍的工具包括以下类别:

  • 系统监控工具:就像我们今天要讨论的 strace 和 DTrace 一样
  • 网络监视器:也属于上述范围,但需要属于自己的类别
  • VM/运行时监控:例如,让我们检查 JVM 的工具等。
  • 分析器和内存监视器

在第一篇文章中,我想讨论两个重量级冠军:DTrace 和 strace。如果您是 Java 开发人员或 Windows 用户,那么您很有可能从未听说过这些工具。您可能无意中使用了其中一个,因为在它们之上构建了如此多的工具,但情况可能并非如此。

这两种工具都可以让您在没有源代码的情况下调试任何东西。您可以发现问题并获得您从未想象过的理解水平。

DTrace


早在 2004 年,我在 Sun Microsystems 工作时第一次听说 DTrace。它在走廊里风靡一时,因为它是 Sun Microsystems 正在推广的一项创新。DTrace 后来被移植到 MacOS X(它起源于 Solaris)。今天,Windows 和 Linux 上也有端口。

DTrace 是一个强大的低级动态跟踪框架。但这只是另一个最高级,而且,如果您从未使用过这样的工具并且没有系统编程背景,您可能会感到有点困惑:它到底是做什么的?

它让你“看到”一切。想知道进程打开了哪些文件?

好的

想知道谁调用了内核 API 并获得调用者的堆栈跟踪?

好的

想知道一个进程为什么会死掉?

好的

想知道一个操作花费了多少 CPU 时间?

好的

您可能会认为 DTrace 是一种会彻底破坏您的 CPU 的工具……但这里有一个杀手级功能:它足够快,可以在生产环境中运行,而对性能影响最小甚至没有!

它在近二十年前推出时是革命性的,直到今天仍然如此!

运行 DTrace

在我们开始之前,先警告一句。保存您的数据!

这个工具很容易让你的机器崩溃。启用它需要禁用 MacOS 上的重要安全设施。这是一个有风险的“低级”系统服务,应该这样对待。

在 Mac 上,DTrace 与“系统完整性保护”冲突,后者是一种安全功能,可阻止进程之间的某些交互(除其他外)。在正常情况下,这会很棒。但是如果你想运行 DTrace,这将是一个问题。

解决方案是在 Intel Mac 上启动到恢复模式;Command-R这意味着在启动时按住键。在 ARM Mac 上,只需长按电源按钮。

然后,在恢复模式终端中,发出命令:csrutil disable.

重新启动后,DTrace 应按预期工作。

基本用法

如前所述,DTrace 是一个非常强大的工具。有整本关于它的书。它有自己的基于 C 语法的编程语言,您可以使用它来构建复杂的逻辑。例如,以下命令将从给定的回调中记录一些信息:

sudo DTrace -qn 'syscall::write:entry, syscall::sendto:entry /pid == $target/ { printf("(%d) %s %s", pid, probefunc, copyinstr(arg1)); }' -p [PID]br


传递给 DTrace 命令的代码片段侦听目标进程 ID 上的 sendto 回调。然后,它将信息打印到控制台,例如,(pid) text

如果这看起来有点太多而且太难开始......你是100%正确的。它是您需要时的强大工具。但是对于我们的大部分日常使用来说,它太强大了。我们想要的是了解一些基本的东西。

简单用法

幸运的是,我们有一个简单的解决方案:

man -k DTrace


这会打印出一个值得阅读的工具列表,只是为了了解这个东西的广泛性。以下是该命令的几行有趣的输出:

纯文本

bitesize.d(1m)           - analyse disk I/O size by process. Uses DTrace
dapptrace(1m)            - trace user and library function usage. Uses DTrace
errinfo(1m)              - print errno for syscall fails. Uses DTrace
iotop(1m)                - display top disk I/O events by process. Uses DTrace
plockstat(1)             - front-end to DTrace to print statistics about POSIX mutexes and read/write locks


值得您花时间查看此列表以了解您在这里真正可以做什么。

例子

您正面临导致应用程序性能下降的磁盘写入问题……但是是您的应用程序有问题还是其他应用程序有问题?

赶紧运行:

sudo rwbypid.d


它将打印出对磁盘的读/写:


  PID CMD                       DIR    COUNT
  2957 wordexp-helper              W        1
  2959 wc                          W        1
  2961 grep                        W        1

... snipped for clarity ...

   637 firefox                     R     6937
   637 firefox                     W    15325
   343 sentineld                   W   100287


安全软件确实降低了性能......

您还可以使用bitesize.d来获得有关写入/分配的字节数的更具体的结果。

不过这水平相当高。如果你想要细节怎么办:文件名、进程名等?


sudo iosnoop -a


打印出几乎包括您需要的所有内容的输出:

STRTIME              DEVICE  MAJ MIN   UID   PID D      BLOCK     SIZE                     PATHNAME ARGS
2022 Jun 30 12:16:56 ??        1  17   501  1111 W  150777072     4096 ??/idb/3166453069wcaw.sqlite-wal firefox\0
2022 Jun 30 12:16:56 ??        1  17   501   661 W  150777175   487424  ??/index-dir/the-real-index Slack Helper\0
2022 Jun 30 12:16:57 ??        1  17   499   342 W  150777294     4096 ??/persistent/.dat.nosync0156.ztvXap sentineld\0


我可以看到进程 ID 以及它写入特定文件的字节数!

假设您的程序跨越进程并且您想看看发生了什么。例如,我在我构建的服务器中运行源代码构建:

sudo errinfo


这让我可以检测到从系统调用返回的错误以及最初触发它的命令:

EXEC          SYSCALL  ERR  DESC
    WindowServer workq_kernreturn   -2 
    WindowServer workq_kernreturn   -2 
   SentinelAgent workq_kernreturn   -2 
   SentinelAgent workq_kernreturn   -2 
          Signal           Helper    0 
          Google           Chrome    0 
           Brave          Browser    0 
          Google           Chrome    0


这些只是冰山一角。我建议查看Oracle的这个旧的DTrace 教程或这本书。免责声明:我没有读过这本书...

strace

有趣的是,strace 工具也起源于 90 年代的 Sun Microsystems。不过,这并不奇怪,因为源自 Sun Microsystems 的技术列表绝对令人麻木。

Strace 在使用和功能上都比 DTrace 简单得多。无论好坏。由于 DTrace 需要深度操作系统支持,因此它从未成为常见 Linux 发行版的官方功能,因此,人们在 Linux 上使用 strace 而不是 DTrace。但是,它们并不完全可以互换。

strace 的启用要归功于称为 ptrace 的内核功能。由于 ptrace 已经在 Linux 中,我们不需要添加额外的内核代码或模块。通常,DTrace 需要更深入的内核支持,以解决 Linux 上的许可问题,它位于单独的可加载模块中,但这仍然存在一些挑战。

使用 strace 类似于每次我们进行内核调用时打印一个日志条目。这会为您执行的每个命令创建非常详细的日志记录。因此,您可以了解正在运行的进程背后 的真实情况。

运行 strace

现在,strace 在 Linux 中很常用。这是该平台上我最喜欢的系统诊断工具。使用它非常方便,因为我们可以在没有特殊权限的情况下运行它。请注意,与 DTrace 不同,您应该使 strace 远离生产环境(除非代码是隔离的)。它会带来巨大的性能开销,并且会导致生产系统停机。

strace 最基本的用法只是将命令行传递给它:

strace java -classpath. PrimeMain


strace 的输出很长,我们来看几行:

execve("/home/ec2-user/jdk1.8.0_45/bin/java", ["java", "-classpath.", "PrimeMain"], 0x7fffd689ec20 /* 23 vars */) = 0
brk(NULL)                               = 0xb85000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0294272000
readlink("/proc/self/exe", "/home/ec2-user/jdk1.8.0_45/bin/j"..., 4096) = 35
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/jli/tls/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/jli/tls/x86_64", 0x7fff37af09a0) = -1 ENOENT (No such file or directory)
open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/jli/tls/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/jli/tls", 0x7fff37af09a0) = -1 ENOENT (No such file or directory)


这些行中的每一行都是一个 Linux 系统调用。我们可以用谷歌搜索他们每个人,以了解发生了什么。这是一个简单的例子:

open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/jli/tls/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)br


Java 尝试使用系统打开调用pthread从目录中加载库以加载文件。tls系统调用的退出码是-1,表示文件不存在。在正常情况下,我们应该从这个 API 中取回一个文件描述符值。查看目录,似乎tls缺少目录。我猜这是因为缺少 JCE 安装。这可能没问题,但在某些情况下可能很有趣。

显然,有时输出量是压倒性的。我们通常只想查看“打开了哪个文件”和“我们的网络调用发生了什么”之类的内容。我们可以通过仅查看使用-e参数的特定系统调用来轻松实现这一点。

strace -e open java -classpath . PrimeMain


只会显示打开的系统调用:

open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/jli/tls/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/jli/tls/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/jli/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/jli/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/tls/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/tls/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/jli/libjli.so", O_RDONLY|O_CLOEXEC) = 3
open("/home/ec2-user/jdk1.8.0_45/bin/../lib/amd64/jli/libdl.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)


您可以学习和使用许多系统调用来跟踪许多行为,例如:连接、写入等。这只是您可以使用 strace 执行的操作的冰山一角。Julia Evans 在 strace 上写了一些最详尽、最有趣的帖子。如果您想了解更多关于它的信息,可能没有比这更好的地方了(还可以查看她的其他资料……惊人的资源!)。

strace 和 Java

正如您之前看到的,strace 与 JVM 配合得很好。由于 strace 早于 Java 并且是一个非常低级的工具,因此它不了解 JVM。JVM 与大多数其他平台一样工作,并调用可用于调试其行为的系统调用。但是,由于它对某些问题的独特处理方法,某些方面可能不会像 strace 那样可见。

一个很好的例子是分配。系统工具使用 malloc,它映射到内核分配逻辑,但 Java 采用不同的路线。它管理自己的内存以提高效率并简化垃圾收集逻辑。因此,内存分配的某些方面将从 strace 输出中隐藏。这可能是因祸得福,因为有时输出可能是压倒性的。

在撰写本文时,线程与 strace 配合得很好。但未来可能并非如此,因为Loom 项目可能会改变 Java 线程和系统线程之间的一对一映射。这可能会使 strace 输出更难在重线程应用程序中查明。

最后

有各种形式的“*trace”实用程序的字母汤,它们不断地相互借鉴想法。跟上所有这些噪音是一项重大挑战。有太多很棒的工具需要介绍,不过我想在以后的文章中讨论 btrace。它与 DTrace 非常相似,但也非常特定于 JVM,因此可能值得另外发表一篇文章。

我今天讨论的工具采用不同的方法来解决类似的问题:我们如何理解二进制应用程序“真正”做了什么?安全研究人员和黑客使用这些工具来了解您的程序。他们不需要代码,也不需要反汇编来查看您实际在做什么。

您还可以使用这些工具来了解您的操作的影响。我们经常调用 API 并让事情到此结束。但魔鬼在细节中,而这些细节可能会带来沉重的代价。作为一名 Java 开发人员,我很少考虑信号传递、进程管理或其他此类低级主要内容。但我确实会花时间研究这些东西,因为它们最终会影响我的应用程序的稳定性和性能。



相关推荐

电子EI会议!投稿进度查

今天为大家推荐一个高性价比的电子类EI会议——IEEE电子与通信工程国际会议(ICECE2024)会议号:IEEE#62199截稿时间:2024年3月25日召开时间与地点:2024年8月15...

最“稳重”的滤波算法-中位值滤波算法的思想原理及C代码实现

在信号处理和图像处理领域,滤波算法是一类用于去除噪声、平滑信号或提取特定特征的关键技术。中位值滤波算法是一种常用的非线性滤波方法,它通过取一组数据的中位值来有效减小噪声,保留信号的有用特征,所以是最稳...

实际工程项目中是怎么用卡尔曼滤波的?

就是直接使用呀!个人认为,卡尔曼滤波有三个个关键点,一个是测量,一个是预测,一个是加权测量:通过传感器,获取传感器数据即可!预测:基于模型来进行数据预测;那么问题来了,如何建模?有难有易。加权:主要就...

我拿导弹公式算桃花,结果把自己炸成了烟花

第一章:学术圈混成“顶流”,全靠学生们把我写成段子最近总有人问我:“老师,您研究导弹飞行轨迹二十年,咋还顺带研究起月老红绳的抛物线了?”我扶了扶眼镜,深沉答道:“同志,导弹和爱情的本质都是动力学问题—...

如何更好地理解神经网络的正向传播?我们需要从「矩阵乘法」入手

图:pixabay原文来源:medium作者:MattRoss「机器人圈」编译:嗯~阿童木呀、多啦A亮介绍我为什么要写这篇文章呢?主要是因为我在构建神经网络的过程中遇到了一个令人沮丧的bug,最终迫...

电力系统EI会议·权威期刊推荐!

高录用率EI会议推荐:ICPSG2025(会议号:CFP25J66-PWR)截稿时间:2025年3月15日召开时间与地点:2025年8月18-20日·新加坡论文集上线:会后3个月内提交至S...

EI论文写作全流程指南

推荐期刊《AppliedEnergy》是新能源领域权威EI/SCI双检索期刊,专注能源创新技术应用。刊号:ISSN0306-2619|CN11-2107/TK影响因子:11.2(最新数...

JMSE投稿遇坑 实验结果被推翻

期刊基础信息刊号:ISSN2077-1312全称:JournalofMarineScienceandEngineering影响因子:3.7(最新JCR数据)分区:中科院3区JCRQ2(...

斩获国际特等奖!兰理工数学建模团队为百年校庆献礼

近日,2019年美国大学生数学建模竞赛(MCM-ICM)成绩正式公布。兰州理工大学数学建模团队再创佳绩,分别获得国际特等奖(OutstandingWinner)1项、一等奖(Meritorious...

省气象台开展人员大培训岗位大练兵学习活动

5月9日,省气象台组织开展首次基于Matlab编程语言的数值模式解释应用培训,为促进研究性业务发展,积极开展“人员大培训、岗位大练兵”学习活动起到了积极作用。此次培训基于实际业务需求,着眼高原天气特色...

嵌入式软件培训

培训效果:通过系统性的培训学习,理论与实践相结合,可以胜任相关方向的开发工作。承诺:七大块专业培训,可以任意选择其中感兴趣的内容进行针对性地学习,每期培训2个月,当期没学会,可免费学习一期。本培训内容...

轧机支承辊用重载中低速圆柱滚子轴承滚子修形探讨

摘 要:探讨了轧机支承辊用重载中低速圆柱滚子轴承滚子修形的理论和方法,确定关键自变量。使用Romax软件在特定载荷工况条件下对轴承进行数值模拟分析,确定关键量的取值范围。关键词:轧机;圆柱滚子轴承;滚...

数学建模EI刊,如何避雷?

---权威EI会议推荐会议名称:国际应用数学与工程建模大会(ICAMEM)截稿时间:2025年4月20日召开时间/地点:2025年8月15日-17日·新加坡论文集上线:会后2个月内由Sp...

制造工艺误差,三维共轭齿面怎样影响,双圆弧驱动的性能?

文/扶苏秘史编辑/扶苏秘史在现代工程领域,高效、精确的传动系统对于机械装置的性能和可靠性至关重要,谐波传动作为一种创新的机械传动方式,以其独特的特性在精密机械领域引起了广泛关注。在谐波传动的进一步优化...

测绘EI会议——超详细解析

【推荐会议】会议名称:国际测绘与地理信息工程大会(ICGGE)会议编号:71035截稿时间:2025年3月20日召开时间/地点:2025年8月15-17日·德国慕尼黑论文集上线:会后2个...