3

I'm running a software written in C# (WPF) that uses a lot of native legacy code. When I close the software, the debugger keeps running and my debug output screen prints this:

Detected memory leaks!
Dumping objects ->
{41198} normal block at 0x00000211F11C58F0, 16 bytes long.
 Data: <                > D8 CE DF B0 8D 00 00 00 00 00 00 00 00 00 00 00 
{41194} normal block at 0x00000211C66AD710, 96 bytes long.
 Data: <D:\mydir\somedir> 44 3A 5C 72 65 70 6F 5C 69 71 73 2D 74 72 75 6E 
{41193} normal block at 0x00000211F11C5210, 16 bytes long.
 Data: <                > 80 83 A1 E1 11 02 00 00 00 00 00 00 00 00 00 00 
{41192} normal block at 0x00000211E1A18360, 88 bytes long.
 Data: <                > 90 80 9D E0 11 02 00 00 90 80 9D E0 11 02 00 00 
(Repeated)

(I changed the path that shows there to "mydir\somedir")

The messages just keep coming for probably more than a minute until I shut it down from the "Stop Debugging" button.

The software is using many libraries written in C and C++. There are several C++/CLI projects that perform as wrappers and used by the C# code.

I do have access to the native source code that's being used so I ran a search for all the definitions of _CRTDBG_MAP_ALLOC and re-defined the new operator as explained in MSDN, but the output remained the same and did not show line/file info whatsoever. I'm not even sure that it's coming from our code.

How can I trace the source of this memory leak? Is there a way to at least identify what file/project is causing this? Assuming this is coming from our code, is there any way to use the C++/CLI code to debug this?

asaf92
  • 1,557
  • 1
  • 19
  • 30
  • If this has been covered before or if the question violates the rules than I'd appreciate if you let me know in the comments and I'll even close it myself, but there's no need to down-vote and vote for closing without explanation – asaf92 Jan 22 '20 at 14:55
  • 1
    if you have all the sourcecodes then yes, but it is a very advanced debugging. It cannot be explained how to as every case is different. This knowledge comes with experience and there is no other way to gain it – 0___________ Jan 22 '20 at 14:57
  • And if it comes from compiled DLLs? Is there any way to know which one creates this output? We're talking about a solution with 190 projects – asaf92 Jan 22 '20 at 14:58
  • 1
    I have voted to close as you do not ask any specific question here, there is no attempt to sort it out yoursel etc etc – 0___________ Jan 22 '20 at 14:58
  • I asked 3 specific questions at the end and I've specified how I debugged this by modifying the native code and trying to print the source of the memory allocation. It's legacy code that was written by people from another country several years ago. – asaf92 Jan 22 '20 at 15:01
  • 1
    It really doesn't matter who wrote the code, whether they're in another country, or even whether they're alive or dead. The code is C++, and C++ programmers worth their salt can find and identify these types of bugs in a short period of time, even if they didn't write the code themselves. You have the entire source code, so that makes it even more of a sure bet that the bug can be discovered by a C++ programmer. – PaulMcKenzie Jan 22 '20 at 15:16
  • 1
    Oh sorry, I thought you meant a C++ programmer that's familiar to this code. I don't know why you're acting so cynical and negative around this question, I'm not spamming I'm really asking a genuine question. "Unfortunately it's not possible to locate where the output is coming from without deep debugging into the native code" with some explanation as to why would have been a totally legitimate answer to my question and I would have gladly accepted it. – asaf92 Jan 22 '20 at 15:21
  • 2
    The issue is that the topic of debugging is a long one. However you *do* have all of the source code. So I don't know what to tell you except either spend the time learning how to debug C++ issues as a non-C++ person (which IMO is not easy), or hire / get / hijack a (good) C++ programmer for a period of time to identify the problem. The issue is one of a memory leak, and there could be many reasons for it -- a bug, or it could be "legitimate" (i.e. the entity is global, and it is expected to leak on closure of the program), etc. – PaulMcKenzie Jan 22 '20 at 15:26
  • 2
    I *understand* that debugging the C++ code directly is the only way to continue at this point and that it's impossible to trace the source (in terms of project being imported, not specific memory allocation) without it. What I don't understand what's so illegitimate about this question and this answer. Had I seen it two weeks ago I would have probably saved myself some time, and it can help people in the future. Isn't that the point of "Is it possible to X" questions? sometimes the answer is a simple "No". – asaf92 Jan 22 '20 at 15:31
  • The leaks definitely come from unmanaged C++ code. Try a memory profiler: Deleaker, or whatever. – Artem Razin Jan 22 '20 at 15:40

1 Answers1

5

The problem was actually in the C++/CLI wrappers.

All the code that's responsible for freeing memory was written in the destructors of the classes, assuming that they will be called automatically by the garbage collector.

However, it turns out that the GC does not invoke the destructor, rather it calls the finalizer.

The solution was to move all the code from destructors to finalizers, and after that not a single dump line is shown in the debug output when I close the program and memory is freed when the GC runs and the class is considered dead.

asaf92
  • 1,557
  • 1
  • 19
  • 30