You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note: problem is limited to applications that use the Microsoft C\C++ runtime library on the Windows platform.
Compiler name and version (including patch level)
Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26732.1 for x86
AREA/CLASS/EXAMPLE AFFECTED:
global_macros.h
The problem effects:
The debug build of the ACE library disables the memory tracking feature of the Microsoft C\C++ runtime library.
Synopsis
The ACE library uses the ACE_NO_HEAP_CHECK macro at a couple of places to disable/enable memory tracking for a local function, however this design fails for multi-threading applications.
Description
The ACE library provides a class and macro to disable temporarily the memory leak tracking feature of the debug build of the Microsoft C\C++ runtime:
The intend of the macro is that it should be used when a function is entered, to suppress false leaks. At function exit the original tracking state is restored.
However the concept of this design is flawed:
As long as the ACE_Export ACE_No_Heap_Check instance exists in one thread, all other memory allocations in other threads are also excluded from the memory tracking. All leakage during that time period are not reported by the CRT debug report when the application is exited.
If another thread uses also the ACE_NO_HEAP_CHECK ACE_No_Heap_Check macro when the tracking is already disabled by another ACE_NO_HEAP_CHECK ACE_No_Heap_Check macro, the old_state variable that will be retrieved to restore is the "disabled" state. Depending on the timing which destructor is executed first, the memory tracking is disabled completely for the remaining lifetime of the app. For example:
Thread 1: ACE_NO_HEAP_CHECK ACE_No_Heap_Check constructor -> disables memory tracking
Thread 2: ACE_NO_HEAP_CHECK ACE_No_Heap_Check constructor -> disables memory tracking, (old_state = disabled)
Thread 1: ACE_NO_HEAP_CHECK ACE_No_Heap_Check destructor -> enables memory tracking
Thread 2: ACE_NO_HEAP_CHECK ACE_No_Heap_Check destructor -> disables memory tracking
Thread 3: ACE_NO_HEAP_CHECK ACE_No_Heap_Check constructor -> disables memory tracking
Thread 3: ACE_NO_HEAP_CHECK ACE_No_Heap_Check destructor -> disables memory tracking
Repeat by
Add a explicit memory leak somewhere in code that is executed by a worker thread.
Execute the application (debug build)
Close the application
Expected result: the MS CRT gives a list of leaked memory blocks.
Actual result: no leaks are reported.
Sample fix/ workaround
My recommendation is remove the ACE_NO_HEAP_CHECK ACE_No_Heap_Check macro and the class ACE_Export ACE_No_Heap_Check to solve this issue.
If there are memory leaks reported afterwards (created by global singletons, for example), it means that additional modifications are needed to remove those, currently hidden, leaks.
Note: the Microsoft C runtime also provides a special debug version of malloc_dbg (internally used by the memory tracking system) that accept a blockType parameter. Passing "IGNORE_BLOCK" means that the leaked memory will not be reported as leaked. This could be an alternative solution to suppress leak warnings, when it is difficult\impossible to modify the leaking implementation.
The text was updated successfully, but these errors were encountered:
Version
ACE 6.5.1, problem also applies to 6.5.2
Host machine and operating system
Windows 10 64 bit
Note: problem is limited to applications that use the Microsoft C\C++ runtime library on the Windows platform.
Compiler name and version (including patch level)
Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26732.1 for x86
AREA/CLASS/EXAMPLE AFFECTED:
global_macros.h
The problem effects:
The debug build of the ACE library disables the memory tracking feature of the Microsoft C\C++ runtime library.
Synopsis
The ACE library uses the ACE_NO_HEAP_CHECK macro at a couple of places to disable/enable memory tracking for a local function, however this design fails for multi-threading applications.
Description
The ACE library provides a class and macro to disable temporarily the memory leak tracking feature of the debug build of the Microsoft C\C++ runtime:
#define ACE_NO_HEAP_CHECK ACE_No_Heap_Check ____no_heap;
class ACE_Export ACE_No_Heap_Check
{
public:
ACE_No_Heap_Check (void)
: old_state (_CrtSetDbgFlag (_CRTDBG_REPORT_FLAG))
{ _CrtSetDbgFlag (old_state & ~_CRTDBG_ALLOC_MEM_DF);}
~ACE_No_Heap_Check (void) { _CrtSetDbgFlag (old_state);}
private:
int old_state;
};
The intend of the macro is that it should be used when a function is entered, to suppress false leaks. At function exit the original tracking state is restored.
However the concept of this design is flawed:
As long as the ACE_Export ACE_No_Heap_Check instance exists in one thread, all other memory allocations in other threads are also excluded from the memory tracking. All leakage during that time period are not reported by the CRT debug report when the application is exited.
If another thread uses also the ACE_NO_HEAP_CHECK ACE_No_Heap_Check macro when the tracking is already disabled by another ACE_NO_HEAP_CHECK ACE_No_Heap_Check macro, the old_state variable that will be retrieved to restore is the "disabled" state. Depending on the timing which destructor is executed first, the memory tracking is disabled completely for the remaining lifetime of the app. For example:
Thread 1: ACE_NO_HEAP_CHECK ACE_No_Heap_Check constructor -> disables memory tracking
Thread 2: ACE_NO_HEAP_CHECK ACE_No_Heap_Check constructor -> disables memory tracking, (old_state = disabled)
Thread 1: ACE_NO_HEAP_CHECK ACE_No_Heap_Check destructor -> enables memory tracking
Thread 2: ACE_NO_HEAP_CHECK ACE_No_Heap_Check destructor -> disables memory tracking
Thread 3: ACE_NO_HEAP_CHECK ACE_No_Heap_Check constructor -> disables memory tracking
Thread 3: ACE_NO_HEAP_CHECK ACE_No_Heap_Check destructor -> disables memory tracking
Repeat by
Expected result: the MS CRT gives a list of leaked memory blocks.
Actual result: no leaks are reported.
Sample fix/ workaround
My recommendation is remove the ACE_NO_HEAP_CHECK ACE_No_Heap_Check macro and the class ACE_Export ACE_No_Heap_Check to solve this issue.
If there are memory leaks reported afterwards (created by global singletons, for example), it means that additional modifications are needed to remove those, currently hidden, leaks.
Note: the Microsoft C runtime also provides a special debug version of malloc_dbg (internally used by the memory tracking system) that accept a blockType parameter. Passing "IGNORE_BLOCK" means that the leaked memory will not be reported as leaked. This could be an alternative solution to suppress leak warnings, when it is difficult\impossible to modify the leaking implementation.
The text was updated successfully, but these errors were encountered: