DTrace 和 strace 概述
moboyou 2025-04-09 13:40 41 浏览
使用这些惊人的工具,无需源代码或对环境的深入了解即可跟踪应用程序中的错误及其外部依赖项!
通常,在调试时,我们需要跳出 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 开发人员,我很少考虑信号传递、进程管理或其他此类低级主要内容。但我确实会花时间研究这些东西,因为它们最终会影响我的应用程序的稳定性和性能。
- 上一篇:Oracle监听日志分析
- 下一篇:MySQL常用函数详解,内含示例
相关推荐
- python新手学习常见数据类型——数字
-
Python支持三种不同的数值类型:整型(int)、浮点型(float)、复数(complex)创建数字:a=1b=2.7c=8+4j删除数字:a=1b=2.7c=8+4...
- 只用一个套路公式,给 Excel 中一列人员设置随机出场顺序
-
很多同学会觉得Excel单个案例讲解有些碎片化,初学者未必能完全理解和掌握。不少同学都希望有一套完整的图文教学,从最基础的概念开始,一步步由简入繁、从入门到精通,系统化地讲解Excel的各个知...
- Excel神技 TIME函数:3秒搞定时间拼接!职场人必学的效率秘籍
-
你是否经常需要在Excel中手动输入时间,或者从不同单元格拼接时、分、秒?今天我要揭秘一个超实用的Excel函数——TIME函数,它能让你3秒内生成标准时间格式,彻底告别繁琐操作!一、TIME函数基础...
- 销售算错数被批?97 Excel 数字函数救场,3 步搞定复杂计算
-
销售部小张被老板当着全部门骂。上季度销售额汇总,他把38652.78算成36852.78,差了1800块。财务对账时发现,整个部门的提成表都得重算。"连个数都算不对,还做什么销售?&...
- 如何使用Minitab 1分钟生成所需要的SPC数据
-
打开Minitab,“计算”-“随机数据”-“正太”,因为不好截图,使用的是拍照记录的方式.再要生产的行数中,填写125,可以按照要求,有些客户要求的是100个数据,就可以填写100...
- 验证码,除了 12306,我还没有服过谁
-
为了防止暴力注册或爬虫爬取等机器请求,需要验证操作者是人还是机器,便有了验证码这个设计。本文作者主要介绍了如何使用Axure来设计一个动态的图形验证码,一起来学习一下吧。在软件设计中,为了防止暴力...
- 零基础也能学会的9个Excel函数,小白进阶必备
-
今天给大家分享一些常用的函数公式,可以有效地解决Excel中办公所需,0基础也可以轻松学会。建议收藏,在需要的时候可以直接套用函数。1、计算排名根据总和,计算学生成绩排名。函数公式=RANK(E2,$...
- [office] excel表格数值如何设置_excel表格怎样设置数值
-
excel表格数值如何设置 因为电子表格应用程序是用来处理数值数据的,所以数值格式可能是工作表中最关键的部分,格式化数值数据的方式由用户决定,但在每个工作簿的工作表之间应使用一致的处理数字的方法。...
- Excel最常用的5个函数!会用最后一个才是高手
-
是不是在处理Excel数据时,面对繁琐的操作烦恼不已?手动操作不仅耗时费力,还容易出错。别担心,表姐这就为你揭秘Excel中几个超实用的函数,让数据处理变得轻松高效!表姐整理了552页《Office从...
- 新手必会的53个Excel函数_惊呆小伙伴的全套excel函数技能
-
(新手入门+进阶+新函数)一、新手入门级(24个)1、Sum函数:求和=Sum(区域)2、Average函数:求平均值=Average(区域)3、Count函数:数字个数=Count(区域)4、Cou...
- 打工人私藏的4个Excel函数秘籍,效率提升3.7%
-
小伙伴们好啊,今天咱们分享几个常用函数公式的典型应用。合并内容如下图,希望将B列的姓名,按照不同部门合并到一个单元格里。=TEXTJOIN(",",1,IF(A$2:A$15=D2,B...
- Excel偷偷更新的8个函数!原来高手都在用这些隐藏技能
-
领导突然要销售数据,你手忙脚乱筛选到眼花...同事3分钟搞定的报表,你折腾半小时还在填充公式...明明用了VLOOKUP,却总显示#N/A错误...别慌!今天教你的8个动态数组函数,就像给Excel装...
- Excel表格随机函数怎么用?讲解三种随机函数在不同场景的应用
-
excel随机函数,其特点是能够生成一组随机数字,根据不同需求,还能批量生成小数位和整数,及指定行数和列数,或指定区间范围内的数字。这里根据需求,作者设置了三个问题,第1个是随机生成0至1之间的数字...
- 单纯随机抽样该如何进行?_单纯随机抽样的适用范围及注意事项
-
在数据分析中,抽样是指从全部数据中选择部分数据进行分析,以发掘更大规模数据集中的有用信息。在收集数据过程中,绝大多数情况下,并不采取普查的方式获取总体中所有样本的数据信息,而是以各类抽样方法抽取其中若...
- 随机函数在Excel中的应用_随机函数在excel中的应用实例
-
【分享成果,随喜正能量】职场,如果你没有价值,那么你随时可能被取代;如果你的价值不如别人,那么社会也不会惯你,你将被无情地淘汰掉。不管什么时候,你一定要学会构建自己的价值。每个人都应该思考这个问题:我...
- 一周热门
- 最近发表
- 标签列表
-
- 外键约束 oracle (36)
- oracle的row number (32)
- 唯一索引 oracle (34)
- oracle in 表变量 (28)
- oracle导出dmp导出 (28)
- 多线程的创建方式 (29)
- 多线程 python (30)
- java多线程并发处理 (32)
- 宏程序代码一览表 (35)
- c++需要学多久 (25)
- css class选择器用法 (25)
- css样式引入 (30)
- css教程文字移动 (33)
- php简单源码 (36)
- php个人中心源码 (25)
- php小说爬取源码 (23)
- 云电脑app源码 (22)
- html画折线图 (24)
- docker好玩的应用 (28)
- linux有没有pe工具 (34)
- mysql数据库源码 (21)
- php开源万能表单系统源码 (21)
- 可以上传视频的网站源码 (25)
- match函数的功能是 (21)
- 随机函数如何生成小数点数字 (31)