4

I'm currently in debuging some code, removing or at least locating memory leaks using Visual Studio 2012 with CrtDbg.

The problem is, as long as the allocation number does not change, tracking down the allocation is rather easy. When the allocation number changes a lot (or is not really deterministic), how can I locate the allocation point of that leak? Can I a least say, which module was allocating the memory?

I have following lines on shutdown of the application:

Detected memory leaks!
Dumping objects ->
{2789444} normal block at 0x0000000006103CB0, 32 bytes long.
 Data: < q f            > B8 71 E4 66 00 00 00 00 00 00 00 00 00 00 00 00 
{1269709} normal block at 0x000000000A50C6A0, 1008 bytes long.
 Data: <        )       > 01 00 00 00 0B 00 00 00 29 00 00 00 CD CD CD CD 
...
{2194} normal block at 0x0000000000278060, 16 bytes long.
 Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
Object dump complete.

The last allocation number, 2194, is reproducable and is related to a static initializer. But the other numbers are changing.

Can't I use the address to locate it? Or is there a simpler solution to it?

Help would be great.

roalter
  • 259
  • 1
  • 2
  • 13
  • Is it at all possible to use a profiler like valgrind with this code? – roelofs Aug 13 '14 at 14:36
  • No, it's a native Windows Application. – roalter Aug 13 '14 at 14:38
  • Ah, well, there goes that idea :( – roelofs Aug 13 '14 at 14:39
  • Already thought of that... Valgrind looks pretty cool... when on Linux – roalter Aug 13 '14 at 14:40
  • If it wasn't a native app, it might've been an option ;) – roelofs Aug 13 '14 at 14:42
  • Go from the lowest to highest allocation number use _CrtSetBreakAlloc(lowest number) and solve one by one. For higher random number it's harder. You have to try _CrtSetBreakAlloc to close number to locate approximately or to check at exist if number where you break is really the same as the dumped leak. – ColdCat Aug 13 '14 at 15:40
  • @roelofs - I am experiencing the same problem - see http://stackoverflow.com/questions/25103724/allocation-numbers-in-c-windows-and-its-predictibility – Ed Heal Aug 13 '14 at 16:18

4 Answers4

1

I recommend you use visual leak detector. I should give you all the details you need so you can track the leak and it's easy to install. See here

0x26res
  • 11,925
  • 11
  • 54
  • 108
  • Already tried this. But the problem is that the code generating these allocations might be third-party without source code. Or can I use it without including it in the proper files? I don't think so. – roalter Aug 13 '14 at 14:39
  • If it's third party libraries without debugging information, you're out of luck no matter what you do. Best you can get then, is actually pinpointing the leak to a particular library. – roelofs Aug 13 '14 at 14:43
  • That's what i want to do. But how can I (easily?) match the leaks to a specific library. Any suggestion? – roalter Aug 13 '14 at 14:47
  • The profiler (I'm not familiar with VLD - disclaimer) *should* tell you from which module/library/object file the leak is originating, at the very least. If you have debug info, then you can see if it's a function you might be using (or using incorrectly). – roelofs Aug 13 '14 at 16:21
1

Try the Debug Diagnostic Tool v2.0, it is a very good memory dector tool on Windows, it is from Microsoft and it is free.

If the 3rd party libraries leaks memory, the tool can locate the library, just without the call stack information.

To start the exe via this debugger, go to the menu 'Tools'->"Pre-Attach Configuration', enable pre attach debugger for your exe.

Matt
  • 6,010
  • 25
  • 36
0

Download visual-leak-detector and commence the following:

Create the following directory structure:

Visual Leak Detector
    include
        vld.h
        vld_def.h
    lib
        Win32
            vld.lib
        Win64
            vld.lib
    bin
        Win32
            vld_x86.dll
        Win64
            vld_x64.dll

Add the following above your main function:

#ifdef _DEBUG_MEM
#include <vld.h>
#endif

Add the following in your project settings:

_DEBUG_MEM in the preprocessor-definitions
Visual Leak Detector\include in the include-path
Visual Leak Detector\lib\Win<xx> in the library-path
Visual Leak Detector\bin\Win<xx> in the executable-path
barak manos
  • 29,648
  • 10
  • 62
  • 114
  • I have found that it can generate false positives – Ed Heal Aug 13 '14 at 16:15
  • No profiler is perfect, in my experience. It's often an educated guessing game in complex code. – roelofs Aug 13 '14 at 16:22
  • Why would I need another LeakDetector? WinDbg is alredy included and own tracking routines using these features as well. The problem is not my code, the leaks are from third-party libraries with do not come with Debug Information or Leak Tracing. – roalter Aug 14 '14 at 12:20
0

You can use these technique:

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
class MemChecker 
{
   friend class foo;
   struct foo 
   {
      HANDLE hLogFile;
      _CrtMemState _ms; 

      foo() 
      {
         hLogFile = CreateFile(TEXT("memory_leaks.txt"), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

         _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); // enable file output
         _CrtSetReportFile( _CRT_WARN, hLogFile ); // set file to stdout
         _CrtMemCheckpoint(&_ms); // now forget about objects created before

         // breaks on N-th memory allocation
         // look for this number in report file (in curved brackets)
         //_CrtSetBreakAlloc(1518);
      }
      ~foo() 
      { 
         _CrtMemDumpAllObjectsSince(&_ms); // dump leaks
         CloseHandle(hLogFile);
      }
   };
   static foo obj;
};
MemChecker::foo MemChecker::obj;

with this declaration, every time you run your programm memory leaks will be detected and reported in a proper way.

Also, you can set breakpoint to a particularly memory leak (read the comments in code). How to do that: you run application, see, what the number of memory leak, then you set _CrtSetBreakAlloc(2789444*), so next time you run the app - it breaks on the place, where the memory (that leaked) was allocated.

You can read more carefully about flags _CRTDBG_MODE_FILE, _CRTDBG_MODE_DEBUG, to specify the place, where debug messages will be outputed.

*from your example, {2789444} normal block at 0x0000000006103CB0, 32 bytes long.

ars
  • 707
  • 4
  • 14
  • Does not work for thirdparty libraries, especially when using Qt... (see http://qt-project.org/forums/viewthread/837 and https://bugreports.qt-project.org/browse/QTBUG-40575) – roalter Aug 19 '14 at 13:51