Valgrind 可以捕获各种未定义的行为吗?
换句话说,如果我的程序运行时没有任何 Valgrind 错误消息,我能否确定它没有未定义行为?
In other words can I be sure that my program is undefined behaviour free if it runs without any Valgrind error messages?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一旦程序被编译,行为就被定义了。如果您想检测未定义的行为,您需要在工具链的早期开始。
未定义的行为意味着由编译器实现来决定如何实现行为,标准没有规定行为必须是什么。也就是说,问UB只对源代码有意义,对编译后的代码没有意义。
Once the program has been compiled, behaviour is defined. If you want to detect undefined behaviour you need to start earlier in the toolchain.
Undefined behaviour means that it is up to the compiler implementation to decide how to implement behaviour, the standard does not dictate what the behaviour must be. In other words, it's only meaningful to ask about UB for source code rather than compiled code.
这里有一个根本性的错误。
Valgrind 不是某种理解 C++ 语法语义并因此知道何时调用 C++ 标准指定的未定义行为的静态分析工具。
然而,Valgrind 是一个工具,只要您在内存中执行的操作是程序未定义行为的结果,它就会向您发出警报。例如,每当您访问未分配或释放的内存时,它都会检测到,当您使用未初始化(或部分未初始化)的值/缓冲区进行系统调用时,它都会检测到,等等......
打个医学比喻,Valgrind 会检测到 未定义行为的>症状。没有症状并不意味着没有未定义的行为。
此外,由于 Valgrind 只检查运行的代码,因此它会留下一些未检查的“代码”。
摆脱未定义的行为非常复杂。如果您的程序很重要,那么它可能相当于解决停机问题。但是,这不应该阻止您采取预防措施:
-Wall -Werror
是给定的,-Wextra
对于新代码库来说非常有用(另外)( 初级)gcov
来检查覆盖范围)(良好实践)完成所有这些工作后,您可能已经发现了程序中的大部分技术错误。不幸的是,有些可能仍然潜伏着。有一天,随着优化选项的更改、重构或其他什么原因,它们可能会暴露出来……为了获得更强的保证,您将需要另一种语言。
There is a fundamental error here.
Valgrind is not some sort of static analysis tool that understand the semantics of the C++ grammar and thus know when you are invoking Undefined Behavior as specified by the C++ Standard.
Valgrind is a tool that will however alert you whenever you are doing operations in the memory that are the results of the Undefined Behavior of your program. For example, it will detect whenever you access unallocated or freed memory, it will detect when you make a system call with an uninitialized (or partly unitialized) value/buffer, etc...
To take a medical analogy, Valgrind detects the symptoms of Undefined Behavior. The absence of symptoms does not imply the absence of Undefined Behavior.
Furthermore, because Valgrind only ever inspect code that runs, it will leave some "code" uninspected.
Getting rid of Undefined Behavior is extremely complicated. If your program is non-trivial, it is likely to be equivalent to solving the Halting Problem. However, that should not prevent you from taking precautions:
-Wall -Werror
is a given,-Wextra
is great (in addition) for new codebases (Elementary)gcov
to check the coverage)(Good Practice)Once you've done all that, you've probably uncovered most of the technical errors within your program. Some, unfortunately, may be latent still. They may be exposed, one day, following a change of optimization options, a refactoring, or whatever... For stronger guarantees, you'll need another language.
一句话:不。没有什么是完美的——甚至 valgrind 也不例外。
In a word: no. Nothing -- not even valgrind -- is perfect.