windows 如何使用应用程序验证器查找内存泄漏
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2955858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use Application Verifier to find memory leaks
提问by Patrick
I want to find memory leaks in my application using standard utilities. Previously I used my own memory allocator, but other people (yes, you AlienFluid) suggested to use Microsoft's Application Verifier, but I can't seem to get it to report my leaks. I have the following simple application:
我想使用标准实用程序在我的应用程序中查找内存泄漏。以前我使用我自己的内存分配器,但其他人(是的,你 AlienFluid)建议使用 Microsoft 的应用程序验证器,但我似乎无法让它报告我的泄漏。我有以下简单的应用程序:
#include <iostream>
#include <conio.h>
class X
{
public:
X::X() : m_value(123) {}
private:
int m_value;
};
void main()
{
X *p1 = 0;
X *p2 = 0;
X *p3 = 0;
p1 = new X();
p2 = new X();
p3 = new X();
delete p1;
delete p3;
}
This test clearly contains a memory leak: p2 is new'd but not deleted.
该测试显然包含内存泄漏:p2 是新的但未删除。
I build the executable using the following command lines:
我使用以下命令行构建可执行文件:
cl /c /EHsc /Zi /Od /MDd test.cpp
link /debug test.obj
I downloaded Application Verifier (4.0.0665) and enabled all checks.
我下载了 Application Verifier (4.0.0665) 并启用了所有检查。
If I now run my test application I can see a log of it in Application Verifier, but I don't see the memory leak.
如果我现在运行我的测试应用程序,我可以在 Application Verifier 中看到它的日志,但我没有看到内存泄漏。
Questions:
问题:
- Why doesn't Application Verifier report a leak?
- Or isn't Application Verifier really intended to find leaks?
- If it isn't which other tools are available to clearly report leaks at the end of the application (i.e. not by taking regular snapshots and comparing them since this is not possible in an application taking 1GB or more), including the call stack of the place of allocation (so not the simple leak reporting at the end of the CRT)
- 为什么应用程序验证程序不报告泄漏?
- 或者应用程序验证器真的不是为了发现泄漏?
- 如果没有其他工具可以在应用程序结束时清楚地报告泄漏(即不通过定期快照并比较它们,因为这在占用 1GB 或更多内存的应用程序中是不可能的),包括调用堆栈分配地点(所以不是 CRT 末尾的简单泄漏报告)
If I don't find a decent utility, I still have to rely on my own memory manager (which does it perfectly).
如果我找不到合适的实用程序,我仍然必须依靠我自己的内存管理器(它完美地做到了)。
采纳答案by Alex F
CRT memory leaks detection (without stack trace):
CRT 内存泄漏检测(无堆栈跟踪):
// debug_new.h #pragma once #include "crtdbg.h" #ifdef _DEBUG #ifndef DEBUG_NEW #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__) #endif #endif
All .cpp files:
所有 .cpp 文件:
#include "debug_new.h" ... // After all other include lines: #ifdef _DEBUG #define new DEBUG_NEW #endif ...
Write this once in the program initialization code:
在程序初始化代码中写一次:
_CrtSetDbgFlag( _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
In MFC, all this is already implemented in MFC headers. You only need to ensure, that every cpp file contains these lines:
在 MFC 中,所有这些都已在 MFC 标头中实现。您只需要确保每个 cpp 文件都包含以下几行:
#ifdef _DEBUG #define new DEBUG_NEW #endif
Restrictions: this catches only "new" memory leaks, all leaks, caused by another functions, like malloc, are not caught.
限制:这仅捕获“新”内存泄漏,不会捕获由其他函数(如 malloc)引起的所有泄漏。
Don't make any allocations inside of .h files - they will be printed without source lines, because DEBUG_NEW is defined after all #include lines.
不要在 .h 文件内进行任何分配 - 它们将在没有源代码行的情况下打印,因为 DEBUG_NEW 是在所有 #include 行之后定义的。
回答by Wanderley Caloni
Application Verifier only catches leaks in DLLs. Try to read the tooltip in the leak checkbox. That's what it says.
应用程序验证程序仅捕获 DLL 中的泄漏。尝试阅读泄漏复选框中的工具提示。这就是它所说的。
回答by Alienfluid
I have a feeling that Application Verifier special cases the exit path and doesn't flag these as leaks - after all, the entire process heap is free on process exit.
我有一种感觉,Application Verifier 特殊情况下退出路径,并且不会将这些标记为泄漏 - 毕竟,整个进程堆在进程退出时是空闲的。
Try writing another sample where you initialize the same pointer again - basically lose the reference to the previous allocation. That should certainly be flagged. Let me know the results.
尝试编写另一个示例,再次初始化相同的指针 - 基本上丢失了对先前分配的引用。这当然应该被标记。让我知道结果。
Also, AppVerifier (if you have all the options enabled) should also catch buffer overflows, underflows, writing to stack locations marked RO etc.
此外,AppVerifier(如果您启用了所有选项)还应该捕获缓冲区溢出、下溢、写入标记为 RO 的堆栈位置等。
回答by StarPilot
Memory Validator from Software Verification will catch memory leaks, and show the complete callstack from the leak's allocation. While it is a commercial product, it has a trial period so programmers can try it and see if it is worth the price to them.
来自软件验证的内存验证器将捕获内存泄漏,并显示泄漏分配的完整调用堆栈。虽然它是一个商业产品,但它有一个试用期,所以程序员可以尝试一下,看看它对他们来说是否物有所值。
回答by philipvr
Visual Leak Detector(v2.2) is more useful than the CRT Debug Library because it will show the complete callstack used for memory allocation has led to the leak.
Visual Leak Detector(v2.2) 比 CRT Debug Library 更有用,因为它将显示用于内存分配的完整调用堆栈导致了泄漏。
回答by philipvr
The simplest solution is not to write the leaks or the buffer overflows in the first place- detecting them after the event is really a waste of effort. In my own code, for years I have had zero problems in these areas. Why? Becauase I use the mechanisms that C++ provides to avoid them. For example:
最简单的解决方案是首先不要写入泄漏或缓冲区溢出- 在事件发生后检测它们确实是浪费精力。在我自己的代码中,多年来我在这些领域遇到过零问题。为什么?因为我使用 C++ 提供的机制来避免它们。例如:
X *p1 = 0;
p1 = new X();
should be:
应该:
shared_ptr <X> p1 = new X();
and you no longer worry about p1 leaking. Better still, don't use dynamic allocation at all:
并且您不再担心 p1 泄漏。更好的是,根本不要使用动态分配:
X x1;
For buffer overflows, always use types like std::string which will grow on input, or if they do not grow will detect the possible overflow and warn you.
对于缓冲区溢出,始终使用像 std::string 这样的类型,它会随着输入增长,或者如果它们不增长,则会检测到可能的溢出并警告您。
I'm not boasting about my prowess in avoiding memory leaks - this stuff really does work, and allows you to get on with the much more difficult task of debugging the businesslogic of your code.
我并不是在吹嘘我在避免内存泄漏方面的能力——这些东西确实有效,并且允许您继续调试代码的业务逻辑这一更困难的任务。