Detecting memory leaks in MFC application - c++

I'm writing an MFC app using Visual 2017 and when the application exits in debug mode, I get this:
Detected memory leaks! Dumping objects -> {74} normal block at
0x00000230E49A7000, 16 bytes long. Data: <0 0 > 30 00 97
E4 30 02 00 00 00 00 00 00 00 00 00 00 Object dump complete.
So, in order to know which function is causing the leak, I've added these lines in stdafx.h:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
And these lines in CWinApp::InitInstance():
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetBreakAlloc(74);
Though, it did not work. I suspect that the 74th memory allocation number has been made before my code is executed. Which method could I overload to be certain to be called first?

Step into your app to start debugging (that's step, not run, so you'll be stopped in the debugger before anything in your program has run), then set _crtBreakAlloc to the allocation you want to stop at (74). Then run and you should get a break on the 74th allocation. CRT Debug Heap Details has information on this variable.
This Microsoft support article also lists instructions for using _crtBreakAlloc in the debugger.

Writing this code
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
in top of each implementation (.CPP) file, can help you to detect the source of memory leaks.
See also: How to detect memory leaks in MFC.

Related

_CrtMemDumpAllObjectsSince not returning expected results

I'm using _CrtMemCheckpoint and _CrtMemDumpAllObjectsSince to track possible memory leaks in my dll.
In DllMain when DLL_PROCESS_ATTACH is detected an init function is called which calls _CrtMemCheckpoint(&startState) on the global _CrtMemState variable startState. When DLL_PROCESS_DETACH is detected an exit function is called that calls _CrtMemDumpAllObjectsSince(&startState). This returns
ExitInstance()Dumping objects ->
{8706} normal block at 0x07088200, 8 bytes long.
Data: <p v > 70 FF 76 07 01 01 CD CD
{8705} normal block at 0x07084D28, 40 bytes long.
Data: < > 00 00 00 10 FF FF FF FF FF FF FF FF 00 00 00 00
{4577} normal block at 0x070845F0, 40 bytes long.
Data: <dbV > 64 62 56 0F 01 00 00 00 FF FF FF FF FF FF FF FF
{166} normal block at 0x028DD4B8, 40 bytes long.
Data: <dbV > 64 62 56 0F 01 00 00 00 FF FF FF FF FF FF FF FF
{87} normal block at 0x02889BA8, 12 bytes long.
Data: < P > DC 50 90 02 00 00 00 00 01 00 00 00
So far so good, except the last three entries (4577, 166 and 87) are also in startState. I.E. If I run _CrtDumpMemoryLeaks() in my Init function and in my Exit function those entries are in both lists.
The documentation says this:
_CrtMemDumpAllObjectsSince uses the value of the state parameter to determine where to initiate the dump operation. To begin dumping from
a specified heap state, the state parameter must be a pointer to a
_CrtMemState structure that has been filled in by _CrtMemCheckpoint before _CrtMemDumpAllObjectsSince was called.
Which makes me believe that items tracked in startState would be excluded from the output. At the end of the Init function where _CrtMemCheckpoint is called there have been about 4700 allocation calls. Shouldn't _CrtMemDumpAllObjectsSince only dump objects allocated after that checkpoint call?
What have I missed?
Short
This is apparently strange only, but it does the job (in part), however in an overzealous mode.
These functions are decades old, so not buggy but not completely well designed.
Truth is there is something in the "old" state that change after your "since" state.
So the question is "yes it does reflect a change since, but is it a lethal leak?"
This frequent and amplified with delayed init for DLL.
Also by a lot of complex objects like map/string/array/list which does delay allocation of internal buffer.
Bad news being that nearly all complex object declared as "static" are in fact inited on first use.
So theses change ought to be shown in _CrtMemDumpAllObjectsSince because they changed their memory alloc.
Unfortunately the display is so crude and unfiltered that it also show too many irrelevant blocks (not modified).
Typical biggest culprit is use of "realloc" that change state of old alloc
This may even look stranger as they may disappear,
For example when a genuine malloc is made after stat snapshoot, because this one will do a kind of 'reset' of the low water marker used for dump, setting it to a higher level. And this magically make a bunch of your "extra display" to disappear.
Behavior is even more erratic if you are doing Multithreading, as it becomes easily non repetitive.
Note:
The fact that it doesn't show a file name and line number is a sign that it's dealing here with a preinit.
So culprits are most likely static complex objetc inited BEFORE main() (or InitInstance();)
Long:
_CrtMemDumpAllObjectsSince is painful!
And in fact, can be so clutter of non-useful info that it defies the purpose for a day/day simple use of _CrtMemDumpAllObjectsSince.
(In the good essence it inspires)
Workaround
None simple!
You may try to do a malloc then free AFTER you do your "since" state snapshoot, in order to tease this marker.
But to be safer and more in control, unfortunetaly I did saw way around writting my own _MyCrtMemDumpAllObjectsSince that dump from the original MS structure.
This was inspired by static void __cdecl dump_all_object_since_nolock(_CrtMemState const* const state) throw()
( see "debug_heap.cpp") Copyright Microsoft!
Code available "as is" more for inspiration.
But before some explanation on the way _CrtMemState works:
A _CrtMemState state does have a pointer 'pBlockHeader' which is usually a link of a double linked list of '_CrtMemBlockHeader*'
This list is in fact more than a snapshoot at a time it is build, but a selection (unclear how) of all the memory blocks in use, arranged in such a way that the "current state" is directly pointed to by 'pBlockHeader'
So that going
-> _block_header_prev allows the exploration of older blocks
-> _block_header_next allows the exploration of newer blocks (the Juice you look for in the concept "Since" but very dangerous as there is no end marker)
The TRICKY part:
MS maintain a vital internal static _CrtMemBlockHeader* called __acrt_first_block
This __acrt_first_block continuously changes during alloc and realloc
However, _MyCrtMemDumpAllObjectsSince dump does start from this __acrt_first_block and go forward (use _block_header_next) until finding a NULL ptr
The first block handled is decided by this __acrt_first_block, and the 'state' you sent is not more than a STOP of the dump.
Otherwise said _CrtMemDumpAllObjectsSince doesn't really dump the "since" state
But dump from __acrt_first_block as it is to your "since" state.
The 'for' loop is overkilling by showing blocks from a 'start'(since) to an 'end'(oldest modified since).
This makes sense but this does also encompass dumping blocks that have NOT been modified. Showing things we don't care about.
MS structure is clever and can be used directly, while it is not guaranteed that Microsoft will maintain the same vital structure _CrtMemBlockHeader in future
But over the last 15 years I haven't seen a bit of change in it (nor do I foresee any reason they would change a strategical and critical structure.)
I dislike copy/paste of MS code and resolve linker with my piggyback code
So the workaround I used is based on the capability to intercept text message sent to "Output" windows, decoding and storing ALL information in my own bank
Structurally below gives an idea of the intercepts using a static struct under lock to store all infos
_CrtSetReportHook2(_CRT_RPTHOOK_INSTALL,MyReportHookDumpFilter);
_CrtMemDumpAllObjectsSince(state); // CONTRARY to what it says, this thing seems to dump everything until old_state
_CrtSetReportHook2(_CRT_RPTHOOK_REMOVE,MyReportHookDumpFilter);
_MyReportHookDumpFilterCommand(_CUST_SORT,NULL);
_MyReportHookDumpFilterCommand(_CUST_DUMP,NULL);
The `_MyReportHookDumpFilterCommand` does check the preexistence of blocks that are NOT modified at all and avoids displaying those during it's Dump phase
Take it as inspiration of code to ease display.
If anybody have simpler way to use it, please share!

Why is my linked list "next" pointer dereferencing to the wrong memory (XCode, C++)

Can someone please help me figure out why the "next" pointer in my linked list is dereferencing to the wrong memory address in code on 32-bit platform, but works fine on 64-bit platform? My program is built as a universal binary on Xcode 7.3 and written in C++.
I've got a linked list, and dereferencing the "next" pointer in the debugger shows the correct memory, but dereferencing it in code reads the memory that is 4-bytes beyond where it should read. I will try to explain..
The objects on the list are 4144 bytes each, the last 4-bytes are a 32-bit pointer to the "next" item on the list. Looking at the "next" pointer in memory (0xBFFD63AC), we see that it is 4 zeros (NULL), this is correct. BUT notice that memory at 0xBFFD63B0 is a 0x01. This is the byte beyond the "next" pointer. When I ask the debugger to print the next variable, it prints the proper value (NULL):
(lldb) print l_pObject->Next
(Object__t *) $0 = 0x00000000
(lldb) memory read &(l_pObject->Next)
0xbffd63ac: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
However, if I execute the code that dereferences the "next" pointer, it actually reads the data from 0xBFFD63B0 instead of 0xBFFD63AC:
l_pObject = l_pObject->Next;
(lldb) print l_pObject
(Object_t *) $3 = 0x00000001
(lldb) memory read &(l_pObject)
0xbffd2504: 01 00 00 00 80 53 fd bf 00 00 00 00 6c 82 2e
I am positive it is reading the 0x01 from 0xBFFD63B0. The debugger seems to know that "next" indicates the memory at 0xBFFD63AC, but for some reason dereferencing "next" in code actually reads from 0xBFFD63B0, but I'm not sure how to figure out why. I've tried adding __attribute__((packed)) to the struct, but that made no difference. It's difficult to determine where things are going wrong because the debugger is telling me something different from what is really happening. Any tips on how to proceed from here would be very greatly appreciated!
EDITED TO ADD MORE INFO:
In the least there is a debugger error here! I ask the debugger to print the sizeof the struct and it gives me 4144, but in code I use the C funciton sizeof() and that gives me 4148! So there is definitely padding happening in the struct, but the debugger and apparently this section of code are blind to it. This is the root of my problem.
Debugger:
(lldb) print sizeof(*l_pObject)
(unsigned long) $0 = 4144
Code:
unsigned int iSizeOf = sizeof(*l_pObject); /* iSizeOf will equal 4148! */
Something funny is happening...
Without seeing the code it is impossible to tell. In general though, pointers tend to be 8-bytes wide on 64-bit systems and 4-bites wide on 32-bit systems. Obviously you observed that it's jumping 4 bytes beyond where it should be, which is a strong indicator. (0xBFFD63B0 - 0xBFFD63AC) == 4.
OK I found the problem, I should have realized it right away. The code that was crashing is in a library. Both the library and the calling application share definitions for variable types. Due to a missing preprocessor flag on the application side, one of those types was being allocated 4-bytes smaller on the application side than in the library code. So when the application created a linked list of objects and passed a reference to the library, each object on that list was 4-bytes smaller than the library was expecting them to be. What made it less obvious was the debugger was showing me addresses and offsets based on what was allocated in the application, so at first glance everything appeared to be sized correctly. I decided to not trust the debugger and wrote my own code to check addresses and offsets, and that's when it became obvious what was happening. So anyway, long story short, be sure your application and library allocate types to be the same size and then things will work much better. :)

Proper way to check for memory leaks in Visual C++

I've been trying to improve my own personal C++ skills lately, so I implemented an Array List as a learning exercise. After I got it working, I started checking for memory leaks, and became very confused by the output.
Source on GitHub (main.cpp, ArrayList.cpp, ArrayList.h)
I got a lot of information about how to start checking for leaks from this page
from Microsoft (hence the declarations at the top of the main file, the start of the main function, and the top of the ArrayList.cpp file.
Visual Studio is telling me this information:
Detected memory leaks!
Dumping objects ->
c:\users\cody\desktop\arraylist\arraylist\arraylist.cpp(48) : {4267} normal block at 0x007F9BC8, 3992 bytes long.
Data: < > 00 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00
Object dump complete.
The program '[16620] ArrayList.exe' has exited with code -1073741510 (0xc000013a).
And the section of code in question
void AL::ShrinkToFit()
{
int* newArray = new int[currentIndexOfFirstOpen]; //Line 48, as mentioned in the mem leak output
for (int i = 0; i < currentIndexOfFirstOpen; i++)
{
newArray[i] = currentArray[i];
}
int* oldArray = currentArray;
currentArray = newArray;
delete[] oldArray;
currentMaxLoad = currentIndexOfFirstOpen;
}
So clearly I'm missing something. If you check the ArrayList.cpp file linked above, it (under different circumstances) tells me I have a leak anywhere in that file that I have "new int[some number]". The page from Microsoft says that I have to use the preprocessor to redefine new because it only works with the C runtime, but it makes no mention of delete (or delete[]). Is this memory actually being leaked? I have a matching delete[] for every new[], but I can't tell if it is a legitimate leak or if the leak detecting tools just don't understand delete. I tried replacing delete with free (I let the preprocessor redefine new as in the Microsoft article), and it made no change. If I am leaking, can someone point out where/why?
I tried to run your code with Visual Leak Detector (https://vld.codeplex.com/) and it appears you don't have a memory leak, but when exiting (with the close button) the command prompt the leak detector fails and detects a leak in the line you mentioned. Try deleting this line in the main.cpp
Sleep(1000000); //hold the prompt open
and put this instead
std::cin.get();
return 0;
Provide a keystroke at the end of the program and exit with code 0 to the operating system, this should solve your problem.

How to ignore false positive memory leaks from _CrtDumpMemoryLeaks?

It seems whenever there are static objects, _CrtDumpMemoryLeaks returns a false positive claiming it is leaking memory. I know this is because they do not get destroyed until after the main() (or WinMain) function. But is there any way of avoiding this? I use VS2008.
I found that if you tell it to check memory automatically after the program terminates, it allows all the static objects to be accounted for. I was using log4cxx and boost which do a lot of allocations in static blocks, this fixed my "false positives"...
Add the following line, instead of invoking _CrtDumpMemoryLeaks, somewhere in the beginning of main():
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
For more details on usage and macros, refer to MSDN article:
http://msdn.microsoft.com/en-us/library/5at7yxcs(v=vs.71).aspx
Not a direct solution, but in general I've found it worthwhile to move as much allocation as possible out of static initialization time. It generally leads to headaches (initialization order, de-initialization order etc).
If that proves too difficult you can call _CrtMemCheckpoint (http://msdn.microsoft.com/en-us/library/h3z85t43%28VS.80%29.aspx) at the start of main(), and _CrtMemDumpAllObjectsSince
at the end.
1) You said:
It seems whenever there are static objects, _CrtDumpMemoryLeaks returns a false positive claiming it is leaking memory.
I don't think this is correct. EDIT: Static objects are not created on heap. END EDIT: _CrtDumpMemoryLeaks only covers crt heap memory. Therefore these objects are not supposed to return false positives.
However, it is another thing if static variables are objects which themselves hold some heap memory (if for example they dynamically create member objects with operator new()).
2) Consider using _CRTDBG_LEAK_CHECK_DF in order to activate memory leak check at the end of program execution (this is described here: http://msdn.microsoft.com/en-us/library/d41t22sb(VS.80).aspx). I suppose then memory leak check is done even after termination of static variables.
Old question, but I have an answer. I am able to split the report in false positives and real memory leaks. In my main function, I initialize the memory debugging and generate a real memory leak at the really beginning of my application (never delete pcDynamicHeapStart):
int main()
{
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
char* pcDynamicHeapStart = new char[ 17u ];
strcpy_s( pcDynamicHeapStart, 17u, "DynamicHeapStart" );
...
After my application is finished, the report contains
Detected memory leaks!
Dumping objects ->
{15554} normal block at 0x00000000009CB7C0, 80 bytes long.
Data: < > DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD
{14006} normal block at 0x00000000009CB360, 17 bytes long.
Data: <DynamicHeapStart> 44 79 6E 61 6D 69 63 48 65 61 70 53 74 61 72 74
{13998} normal block at 0x00000000009BF4B0, 32 bytes long.
Data: < ^ > E0 5E 9B 00 00 00 00 00 F0 7F 9C 00 00 00 00 00
{13997} normal block at 0x00000000009CA4B0, 8 bytes long.
Data: < > 14 00 00 00 00 00 00 00
{13982} normal block at 0x00000000009CB7C0, 16 bytes long.
Data: < # > D0 DD D6 40 01 00 00 00 90 08 9C 00 00 00 00 00
...
Object dump complete.
Now look at line "Data: <DynamicHeapStart> 44 79 6E 61 6D 69 63 48 65 61 70 53 74 61 72 74".
All reportet leaks below are false positives, all above are real leaks.
False positives don't mean there is no leak (it could be a static linked library which allocates heap at startup and never frees it), but you cannot eliminate the leak and that's no problem at all.
Since I invented this approach, I never had leaking applications any more.
I provide this here and hope this helps other developers to get stable applications.
Can you take a snapshot of the currently allocated objects every time you want a list? If so, you could remove the initially allocated objects from the list when you are looking for leaks that occur in operation. In the past, I have used this to find incremental leaks.
Another solution might be to sort the leaks and only consider duplicates for the same line of code. This should rule out static variable leaks.
Jacob
Ach. If you are sure that _CrtDumpMemoryLeaks() is lying, then you are probably correct. Most alleged memory leaks that I see are down to incorect calls to _CrtDumpMemoryLeaks(). I agree entirely with the following; _CrtDumpMemoryLeaks() dumps all open handles. But your program probably already has open handles, so be sure to call _CrtDumpMemoryLeaks() only when all handles have been released. See http://www.scottleckie.com/2010/08/_crtdumpmemoryleaks-and-related-fun/ for more info.
I can recommend Visual Leak Detector (it's free) rather than using the stuff built into VS. My problem was using _CrtDumpMemoryLeaks with an open source library that created 990 lines of output, all false positives so far as I can tell, as well as some things coming from boost. VLD ignored these and correctly reported some leaks I added for testing, including in a native DLL called from C#.

Visual Studio 2008 (C++) memory leak detection not showing file/method location - how to get that to work?

I am using the instructions found here to try to find memory leaks in a Win32 application. As described, I put the
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
Lines at the top of a file (the cpp file that contains WINAPI _tWinMain) and then at the exit point of winmain I added
_CrtDumpMemoryLeaks();
Unfortunately I do not see the line numbers/locations for the leaks (but I do get a list of leaks).
I also tried putting
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode ( _CRT_ERROR, _CRTDBG_MODE_DEBUG);
at the beginning of winmain - and again, no luck.
I find this odd because I usually have had no problems ever finding leaks or having them reported automatically.
This is a huge, old legacy app I am working on for a new employer. In the past I have worked from the standard VS wizard.
Any suggestions on how to get source lines/methods that are causing the leaks? (or at least the lines for the "new" calls?
EDIT:
I also tried visual leak detector - with no success.
Very strange.
EDIT
I tried using the redefinition of new as listed below, however I get errors when boost is compiled in.
Are you sure the code that's leaking is using the CRT debug allocation routines? That requires using malloc() or new (as opposed to LocalAlloc, GlobalAlloc, some custom block allocator, etc..) and that _DEBUG (I think) must be defined when the CRT headers were included.
In order to get source lines for leaks, you will need to define DEBUG_NEW everywhere the allocations occur. This is because in order to track them, each allocation must be replaced with a call that includes __FILE__ and __LINE__. The standard definition from the wizard looks something like:
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#endif
This doesn't handle malloc, there's probably a similar incantation for that, if the code you're debugging uses malloc instead of new.
If you're using pre-compiled headers, you can just put this in the precompiled header file and it will affect all the source files in that project.
Given a list of leaks at the end of the run, something like:
Detected memory leaks!
Dumping objects ->
{12913} normal block at 0x000002BC648BB9D0, 82 bytes long.
Data: <h t t p : / / a > 68 00 74 00 74 00 70 00 3A 00 2F 00 2F 00 61 00
{12912} normal block at 0x000002BC648B8030, 24 bytes long.
Data: <0 d ` > 30 CD 89 64 BC 02 00 00 D8 02 60 E5 F7 7F 00 00
...
It is easy to find where these memory blocks were allocated using _CrtSetBreakAlloc for example for stop when allocation with allocation number 12913 happens one has to put
...
_CrtSetBreakAlloc(12913);
...
somewhere in code before the allocation happens: beginning of the unit tests or main-function are some possible examples. Now, void* __CRTDECL operator new(size_t const size) will throw an exception when block with allocation number 12913 is allocated and from the call-stack in debugger it is easy to find where the allocation did happen.