DTrace 和 strace 概述
moboyou 2025-04-09 13:40 50 浏览
使用这些惊人的工具,无需源代码或对环境的深入了解即可跟踪应用程序中的错误及其外部依赖项!
通常,在调试时,我们需要跳出 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. PrimeMainstrace 的输出很长,我们来看几行:
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)brJava 尝试使用系统打开调用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常用函数详解,内含示例
相关推荐
- Excel技巧:SHEETSNA函数一键提取所有工作表名称批量生产目录
-
首先介绍一下此函数:SHEETSNAME函数用于获取工作表的名称,有三个可选参数。语法:=SHEETSNAME([参照区域],[结果方向],[工作表范围])(参照区域,可选。给出参照,只返回参照单元格...
- Excel HOUR函数:“小时”提取器_excel+hour函数提取器怎么用
-
一、函数概述HOUR函数是Excel中用于提取时间值小时部分的日期时间函数,返回0(12:00AM)到23(11:00PM)之间的整数。该函数在时间数据分析、考勤统计、日程安排等场景中应用广泛。语...
- Filter+Search信息管理不再难|多条件|模糊查找|Excel函数应用
-
原创版权所有介绍一个信息管理系统,要求可以实现:多条件、模糊查找,手动输入的内容能去空格。先看效果,如下图动画演示这样的一个效果要怎样实现呢?本文所用函数有Filter和Search。先用filter...
- FILTER函数介绍及经典用法12:FILTER+切片器的应用
-
EXCEL函数技巧:FILTER经典用法12。FILTER+切片器制作筛选按钮。FILTER的函数的经典用法12是用FILTER的函数和切片器制作一个筛选按钮。像左边的原始数据,右边想要制作一...
- office办公应用网站推荐_office办公软件大全
-
以下是针对Office办公应用(Word/Excel/PPT等)的免费学习网站推荐,涵盖官方教程、综合平台及垂直领域资源,适合不同学习需求:一、官方权威资源1.微软Office官方培训...
- WPS/Excel职场办公最常用的60个函数大全(含卡片),效率翻倍!
-
办公最常用的60个函数大全:从入门到精通,效率翻倍!在职场中,WPS/Excel几乎是每个人都离不开的工具,而函数则是其灵魂。掌握常用的函数,不仅能大幅提升工作效率,还能让你在数据处理、报表分析、自动...
- 收藏|查找神器Xlookup全集|一篇就够|Excel函数|图解教程
-
原创版权所有全程图解,方便阅读,内容比较多,请先收藏!Xlookup是Vlookup的升级函数,解决了Vlookup的所有缺点,可以完全取代Vlookup,学完本文后你将可以应对所有的查找难题,内容...
- 批量查询快递总耗时?用Excel这个公式,自动计算揽收到签收天数
-
批量查询快递总耗时?用Excel这个公式,自动计算揽收到签收天数在电商运营、物流对账等工作中,经常需要统计快递“揽收到签收”的耗时——比如判断某快递公司是否符合“3天内送达”的服务承...
- Excel函数公式教程(490个实例详解)
-
Excel函数公式教程(490个实例详解)管理层的财务人员为什么那么厉害?就是因为他们精通excel技能!财务人员在日常工作中,经常会用到Excel财务函数公式,比如财务报表分析、工资核算、库存管理等...
- Excel(WPS表格)Tocol函数应用技巧案例解读,建议收藏备用!
-
工作中,经常需要从多个单元格区域中提取唯一值,如体育赛事报名信息中提取唯一的参赛者信息等,此时如果复制粘贴然后去重,效率就会很低。如果能合理利用Tocol函数,将会极大地提高工作效率。一、功能及语法结...
- Excel中的SCAN函数公式,把计算过程理清,你就会了
-
Excel新版本里面,除了出现非常好用的xlookup,Filter公式之外,还更新一批自定义函数,可以像写代码一样写公式其中SCAN函数公式,也非常强大,它是一个循环函数,今天来了解这个函数公式的计...
- Excel(WPS表格)中多列去重就用Tocol+Unique组合函数,简单高效
-
在数据的分析和处理中,“去重”一直是绕不开的话题,如果单列去重,可以使用Unique函数完成,如果多列去重,如下图:从数据信息中可以看到,每位参赛者参加了多项运动,如果想知道去重后的参赛者有多少人,该...
- Excel(WPS表格)函数Groupby,聚合统计,快速提高效率!
-
在前期的内容中,我们讲了很多的统计函数,如Sum系列、Average系列、Count系列、Rank系列等等……但如果用一个函数实现类似数据透视表的功能,就必须用Groupby函数,按指定字段进行聚合汇...
- Excel新版本,IFS函数公式,太强大了!
-
我们举一个工作实例,现在需要计算业务员的奖励数据,右边是公司的奖励标准:在新版本的函数公式出来之前,我们需要使用IF函数公式来解决1、IF函数公式IF函数公式由三个参数组成,IF(判断条件,对的时候返...
- Excel不用函数公式数据透视表,1秒完成多列项目汇总统计
-
如何将这里的多组数据进行汇总统计?每组数据当中一列是不同菜品,另一列就是该菜品的销售数量。如何进行汇总统计得到所有的菜品销售数量的求和、技术、平均、最大、最小值等数据?不用函数公式和数据透视表,一秒就...
- 一周热门
- 最近发表
-
- Excel技巧:SHEETSNA函数一键提取所有工作表名称批量生产目录
- Excel HOUR函数:“小时”提取器_excel+hour函数提取器怎么用
- Filter+Search信息管理不再难|多条件|模糊查找|Excel函数应用
- FILTER函数介绍及经典用法12:FILTER+切片器的应用
- office办公应用网站推荐_office办公软件大全
- WPS/Excel职场办公最常用的60个函数大全(含卡片),效率翻倍!
- 收藏|查找神器Xlookup全集|一篇就够|Excel函数|图解教程
- 批量查询快递总耗时?用Excel这个公式,自动计算揽收到签收天数
- Excel函数公式教程(490个实例详解)
- Excel(WPS表格)Tocol函数应用技巧案例解读,建议收藏备用!
- 标签列表
-
- 外键约束 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)
- 可以上传视频的网站源码 (25)
- 随机函数如何生成小数点数字 (31)
- 随机函数excel公式总和不变30个数据随机 (33)
- 所有excel函数公式大全讲解 (22)
- 有动图演示excel函数公式大全讲解 (32)
