How can i generate a file with the information generated by _CrtDumpMemoryLeaks

114 views Asked by At

I am trying to implement a log file creation based on CRT debug tools, so far i have generated a simple file with some leaks on purpose just to see how it works.

#include "OtherSource.h"

#include <iostream>
#include <stdio.h>

int Simulation::SimulateLeak()
{
#ifdef _DEBUG
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif 

int* offset_x = DBG_NEW int;
int* offset_y = DBG_NEW int;

if (offset_x == NULL || offset_y == NULL) {
    return 1;
}

*offset_x = 10;
*offset_y = 20;

delete offset_x;

#ifdef _DEBUG
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
_CrtDumpMemoryLeaks();
#endif

return 0;

}

Then i tried what i thought would be simple, create a file, grab the memory leak info and write to it, even CRT offers something called _CrtSetReportFile()

so i tried to implement something with it

#include "OtherSource.h"
#include <iostream>
#include <stdio.h>

int Simulation::SimulateLeak()
{
#ifdef _DEBUG
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif 

// Set the file where the report should go
FILE* leakReportFile = fopen("MemoryLeakReport.txt", "w");
_CrtSetReportFile(_CRT_WARN, leakReportFile);

int* offset_x = DBG_NEW int;
int* offset_y = DBG_NEW int;

if (offset_x == NULL || offset_y == NULL) {
    return 1;
}

*offset_x = 10;
*offset_y = 20;

delete offset_x;

#ifdef _DEBUG
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
_CrtDumpMemoryLeaks();
#endif

// Close the file after dumping memory leaks
fclose(leakReportFile);

return 0;
}

The file is indeed generated but even though in my output i get memory leaks

Detected memory leaks!
Dumping objects ->
C:\C++\CRTDebugTest\CRTDebugTest\Source.cpp(10) : {183} normal block at 0x000002CEAFE21FF0, 4        bytes long.
Data: <(   > 28 00 00 00 
C:\C++\CRTDebugTest\CRTDebugTest\OtherSource.cpp(29) : {181} normal block at    0x000002CEAFE22570, 4 bytes long.
Data: <    > 14 00 00 00 
C:\C++\CRTDebugTest\CRTDebugTest\OtherSource.cpp(28) : {180} normal block at 0x000002CEAFE21BF0, 4 bytes long.
Data: <    > 0A 00 00 00 
Object dump complete.

My file comes empty, what am i doing wrong or missing? Please Help

2

There are 2 answers

5
Simon Mourier On

There are two problems in your code:

  • A CRT file descriptor is not the same as the underlying operating system handle (whatever that is)
  • You must specify _CRTDBG_MODE_FILE to use a file as output

So you can change your code like this for example, using _get_osfhandle:

// Set the file where the report should go
FILE* leakReportFile = fopen("MemoryLeakReport.txt", "w");
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, (void*)_get_osfhandle(_fileno(leakReportFile)));
1
Zevahc On

Based on the answer by Simon, i started researching and found a way to properly grab everything from the debug output to my file

#include "OtherSource.h"
#include <iostream>
#include <cstdio>
#include <corecrt_io.h>

int Simulation::SimulateLeak()
{
#ifdef _DEBUG
  _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif

// Open the file for writing
FILE* outFile = nullptr;
if (fopen_s(&outFile, "MemoryLeakReport.txt", "w") != 0 || outFile == 
nullptr) {
    std::cerr << "Failed to open file for writing." << std::endl;
    return 1;
}

// Redirect stdout to the file
if (_dup2(_fileno(outFile), _fileno(stdout)) != 0) {
    std::cerr << "Failed to redirect stdout to file." << std::endl;
    fclose(outFile);
    return 1;
}
#ifdef _DEBUG
// Redirect debug output to stdout
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
#endif

// Actual memory allocations and operations
int* offset_x = DBG_NEW int;
int* offset_y = DBG_NEW int;

if (offset_x == nullptr || offset_y == nullptr) {
    std::cerr << "Memory allocation failed." << std::endl;
    fclose(outFile);
    return 1;
}

*offset_x = 10;
*offset_y = 20;
#ifdef _DEBUG
// Trigger memory leak check
_CrtDumpMemoryLeaks();
#endif

// Close the file
fclose(outFile);


return 0;
}

I had to create a redirect stdout to file to handle what was going to be added to the file and then with CRT redirect the debug output to stdout, a bit of extra steps, but the result is the one i expected, all debug console reported memory leaks appear in my log file even if there are on other file that has no CRT declared