Valgrind 1.0 发布已经二十年了。
Valgrind 网站说:
Valgrind 是一个用于构建动态分析工具的仪器框架。Valgrind 工具可以自动检测许多内存管理和线程错误,并详细分析您的程序。您还可以使用 Valgrind 构建新工具。
–
我之一次见到 Julian Seward 是在 2001 年底。我从澳大利亚搬到英国的剑桥,攻读“函数式语言的缓存优化”主题的博士学位。剑桥计算机实验室就在微软研究办公室的隔壁,我很快就与那里的 Glasgow Haskell 编译器工作人员进行了交流。朱利安就是其中之一。
此后不久,朱利安在 GHC 上的工作就结束了。在他的最后一天,他来到我在计算机实验室的办公室告别。我问他现在要做什么,他说他将花一些时间在他的一个名为 Valgrind 的项目上。“什么是瓦尔格林?” 我问。这是那些将改变你生活的时刻之一。
–
在 90 年代中期,Julian 编写了bzip2 压缩实用程序。他花了一些时间 调查它的缓存行为以使其更快。在此过程中,他创建了一个名为 cacheprof 的缓存分析工具。它解析和注释汇编代码以添加检测代码,在源代码中逐行注释缓存未命中,并附带 gcc 的包装器以使其使用简单。( cacheprof 文档的第 7 节有更多关于其起源的详细信息。)
Julian 也是Purify的粉丝,这是一种商业工具,可以在运行时检测程序中的内存错误并在 Solaris 上运行。他希望有人会为 x86/Linux 做一个开源版本,但最终决定自己做。他对名为 Heimdall 的 x86 二进制解释器有一定的经验,但知道二进制解释速度太慢,不实用。也许 JIT 编译会有所帮助?
经过大量的努力,他有了一个工作内存错误检测器,最终命名为 Valgrind。它是独立于语言的,不需要对源代码进行任何预先测试。它工作得很好,可以处理大型程序,并且得到了 KDE 开发人员的一些使用。
所有这一切都是一个令人印象深刻的成就,因为 Valgrind 必须做很多聪明和/或讨厌的低级事情才能工作。它必须拦截客户端程序执行的每条指令,而不会失去控制,即使面对系统调用、信号和 longjmp。最重要的是,它必须添加大量工具来维护有关客户端程序操作的每一位数据的元数据。
–
当 Julian 向我展示 Valgrind 时,我觉得它很酷。我得到了一份代码并提交了一些小的改进。
我自己一直在使用 cacheprof,但是它的程序集注释 *** 很脆弱,并且没有为系统库提供任何覆盖。在了解 Valgrind 后不久,我意识到它的动态二进制检测可以为缓存分析工具提供更强大的基础。我编写了 Cachegrind,它于 2002 年 4 月提交到存储库中。
2002 年 7 月,Valgrind 1.0 发布。SlashDot 的帖子说 :
Valgrind 是 C/C++ 程序员的梦想成真:轻松的内存分配检查、未初始化的内存访问、泄漏等。Purify for Linux 已经到来,只有更好:与它的商业(非 Linux)兄弟相反,检查是直接在可执行文件上执行的,无需重新链接。
在这一点上,Valgrind 做了两件事。默认情况下,它会查找内存错误,但您可以使用该--cachesim选项调用 Cachegrind。两种模式之间的集成很笨拙,但两者都很有用。
然后我意识到通用检测代码和工具特定代码之间存在潜在的清晰划分。几个月后,我做了这个拆分,打开了一个充满可能性的新世界。Memcheck 诞生了:它成为了进行原始内存检查的工具的名称,而 Valgrind 成为了整个系统的名称。(话虽如此,即使在今天,“Valgrind”和“Memcheck”也基本上是同义词。)而且 Cachegrind 不再是一个笨拙的额外部分。
我们称之为“核心/皮肤分裂”。这些名字是我选择的,灵感来自当时你可以放在软件 MP3 播放器上的自定义 UI“皮肤”。过了一会儿,我们意识到“皮肤”是一个愚蠢而令人困惑的名字,我们改用“工具”。“core”这个名字一直存在,尽管我们在得知某些 Linux 系统被配置为定期删除任何名为 的文件后, 将存放核心代码的目录的名称从core更改为,假设这些文件是核心转储!coregrindcore
大约在这个时候,许多做出重要贡献的才华横溢的人加入了我们。尤其是 Jeremy Fitzhardinge 极大地改进了线程、系统调用和信号的棘手交点,Tom Hughes 修复了许多早期错误并改进了 debuginfo 读取。
更多工具随之而来。
Julian 编写了一个名为 Helgrind 的数据竞争检测器。
Josef Weidendorfer 编写了一个增强版的 Cachegrind,称为 Callgrind。
2003 年,我编写了一个堆分析器 Massif。
2007 年,Bart Van Assche 编写了 DRD,一种不同类型的种族检测器。
2010 年,Julian 编写了 DHAT,一个不同的堆分析器。它可以做一些令人难以置信的事情,但基于文本的输出很笨拙。在 2019 年,我 对其进行了大修 ,以拥有更好的 UI。
已经编写了各种其他鲜为人知的工具,其中一些被用作研究论文的基础。
–
在核心/工具拆分之后,我将我的博士学位主题从函数式编程转移开来。我在 2004 年底完成了我的论文,题为Dynamic Binary Analysis and Instrumentation。我不建议今天阅读它,除了第 3 章,它对 Cachegrind 的工作原理有很好的描述。然而,这足以让我毕业并永远告诉人们,从字面上看,“我在 Valgrind 拥有博士学位”。(这是一个为期三年的英国博士学位,而不是一个残酷的六年或更长时间的美国博士学位。对于任何阅读本文的潜在研究生:10/10,会推荐。)
2005 年,我们在 USENIX 上发表了一篇题为Using Valgrind to detection undefined value errors with bit-precision 的论文。我们在论文截止日期前两天才得知会议的消息,当时位于同一地点的 FREENIX 研讨会的组织者建议我们向 FREENIX 提交一份关于 Valgrind 的论文摘要。我们建议向 USENIX 提交论文,但被告知“两天内不可能完成 USENIX 论文”。48 个小时后,我们做到了,它被接受了,万岁!
那篇论文主要关注 Memcheck 的定义性检查。这是跟踪客户端程序接触的每一位数据的定义性的部分,并确定客户端程序是否对未定义或部分定义的值进行了危险的操作,例如在使用未定义值的条件上进行分支,或传递系统调用的未定义值,或使用未定义值作为内存操作中的地址。这是 Julian 发明的一个非常优雅的系统,结合了速度和精度。即使在今天,它仍然是 Memcheck 相对于类似检查工具的独特优势。
2007年我们发表了两篇论文。之一篇论文是在 PLDI,题为 Valgrind: A Framework for Heavyweight Dynamic Binary Instrumentation。这个花了两天多的时间。它仍然是对 Valgrind 内部结构的更佳概述,也是关于 Valgrind 被引用次数最多的论文。十年后获更具影响力论文 武器奖。我当然没想到。
奖
第二篇论文是在 VEE 上,题为How to Shadow Every Byte of Memory Used by a Program。它很好地概述了 Memcheck 如何跟踪内存中每个值的额外状态。
还有其他一些奖项。
2004 年,Valgrind 获得了优秀(铜)开源奖。( 当时对朱利安的采访 有一些很好的历史资料。)
2006 年,Julian 获得了Google-O'Reilly 开源奖“更佳工具制造商”。
2008 年,Valgrind 获得了TrollTech 的首届 Qt 开源开发奖,以表彰 其更佳开源开发工具。
–
到 2010 年,我完全脱离了学术界,不再撰写研究论文。Julian 和我最终都去了 Mozilla,我在那里工作了 12 年,而 Julian 仍然在那儿。我们对 Valgrind 的参与逐渐减少——我的参与比 Julian 早得多——而我们今天的状态更好被描述为“退休人员”。多年来,还有许多其他 贡献者,Mark Wielaard 今天是主要维护者。
–
看到 Valgrind 至今仍在广泛使用,这既令人愉快又超现实。Julian 最初的目标是提高 C 和 C++ 程序的正确性。这显然取得了巨大的成功。Memcheck 在无数程序中发现了无数错误,并且是其中许多程序测试设置的标准部分。
不过,它确实需要一段时间才能渗透。2005 年,我做了一个博士后,从事一个涉及新颖硬件设计的项目。有几个 C 程序可以模拟正在设计的硬件。学生们会在一夜之间运行这些程序来模拟少量的机器时间。有时当他们早上返回时,模拟会崩溃,这会浪费很多时间。我建议他们尝试 Memcheck,它发现了一些他们修复的问题,并且程序停止了崩溃。但回应不是“解决了问题!” 就像“嗯,那个问题似乎已经消失了”一样。
值得庆幸的是,随着时间的推移,Memcheck 的价值已经变得更加深刻。我很确定 ASan 直接受到了 Memcheck 的启发。ASan 使用静态检测,这意味着它比 Memcheck 更快,但覆盖范围不完整,例如运行时生成的代码和系统库。出于这个原因,除了定义性检查之外,它执行 Memcheck 所做的工作,因为该部分需要 100% 的仪器覆盖率才能可靠地工作。
说到软件质量,我认为我现在 *** 从事 Rust 工作是合适的,Rust 是一种在创建 Valgrind 时还不存在的系统编程语言,但它基本上可以防止 Memcheck 检测到的所有问题。因此,我对 Memcheck 并没有太多用处,但我仍然一直在使用 Cachegrind、Callgrind 和 DHAT。我很惊讶我今天还在使用 Cachegrind,因为它在 20 年里几乎没有改变。(不过,我只将它用于指令计数。我根本不相信 icache/dcache 的结果,因为它们来自大约 2002 年对 AMD Athlon 的更佳猜测模拟。)而且 DHAT 是一个持续的快乐源泉:我从来没有使用过任何其他分析器能够准确地告诉我我想知道什么。
–
这些是我在过去二十年中的一些 Valgrind 故事。这远不是一个完整的帐户,但我希望它很有趣。
最后,我将引用 我很久以前写的 Valgrind FAQ中的之一个条目:
1.1。你如何发音“Valgrind”?
“价值”一词中的“Val”。“grind”的发音是短的“i”——即。“grinned”(与“tinned”押韵)而不是“grinned”(与“find”押韵)。
不要难过:几乎每个人一开始都会弄错。
生日快乐,瓦尔格林!