View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0031844 | Community | OCCT:Coding | public | 2020-10-12 22:42 | 2023-08-01 15:09 |
Reporter | galbramc | Assigned To | |||
Priority | normal | Severity | minor | ||
Status | new | Resolution | open | ||
Platform | Linux | OS | Debian 6.0 | ||
Product Version | 6.3.1 | ||||
Target Version | Unscheduled | ||||
Summary | 0031844: Coding - memory leak in Standard_MMgrFactory | ||||
Description | The pointer myFMMgr is not deleted in the Standard_MMgrFactory destructor (reported by valgrind). The following fixes the memory leak:Standard_MMgrFactory::~Standard_MMgrFactory() { if ( myFMMgr ) { myFMMgr->Purge(Standard_True); delete myFMMgr; } } | ||||
Steps To Reproduce | Run any OCCT 7.5.0 beta test with valgrind. | ||||
Tags | No tags attached. | ||||
Test case number | |||||
|
Branch CR31844 has been created by kgv. SHA-1: 2d869dc15560446c9dbcbade3c2fe21582346f45 Detailed log of new commits: Author: kgv Date: Tue Oct 13 07:50:19 2020 +0300 0031844: Coding - memory leak in Standard_MMgrFactory Added missing deletion (previously commented without a hint why). |
|
The memory manager object is not deleted on destruction because we cannot guarantee that at this moment there are no other global objects storing pointers to memory blocks allocated using this manager, which will try to release that memory on their desruction. Consider the following possible situation: * Some file in TKernel contains global object, e.g. Handle(TCollection_HAsciiString). * That global object is initialized as null handle at the load time (during TKernel libary initialization) and before initialization of Standard_MMgrFactory * Later during the program execution this object is assigned a string allocated using OCCT memory manager. In this situation, memory manager would be destroyed before such global object, and destruction of the later would cause unexpected behavior (most likely a crash due to access violation). Thus I believe we shall keep the existing implementation until we find a way to guarantee that the described situation will not happen. |
|
I believe the factory function you have saves the day: Standard_MMgrRoot* Standard_MMgrFactory::GetMMgr() { static Standard_MMgrFactory aFactory; return aFactory.myFMMgr; } Have you tried to write a unit test that reproduces the situation you are concerned with? |
|
No I have not tried to reproduce this situation artifically (do not have time for that), but from the past experience I know that it can happen easily (recall 0030563). |
|
So I'm guessing the problem is the factory function is not called as part of the constructor of any global variable? I also have interdependent singletons in our software, but I rigged them up so global variable constructors would call factory functions to guarantee the inter dependent global variables would be constructed and destructed in proper order. Adding a call to the opencascade::handle<T> constructor that invokes the Standard_MMgrFactory::GetMMgr() should resolve the issue for global pointers, but I don't know if that would create too much of an overhead. I did run through our ~1,700 tests and didn't have any problems with deleting myFMMgr, but our test suite is not a comprehensive test of OCCT. |
|
Note that problem with Standard_MMgrFactory destruction is unlikely affects default Standard_MMgrRaw memory manager, which does not hold any class fields and just wrapper standard malloc()/free() routines. So that hypothetical problem should be tested with other memory managers - like Standard_MMgrOpt (which is, however, not promoted for regular use on modern configurations). |
|
I think the concern is that the destructor for static Standard_MMgrFactory aFactory; is called before the last destructor of a global handle. If the global handle destructor is called after the aFactory is destroyed, then you get undefined (segfault) during shutdown of the program. This happens regardless of which memory manager is used. |
|
Yes, this is the concern. The point is that this is potential issue, not really experienced in practice, but its appearance depends not only on the code but also on the compiler and linker (and build system in general -- all that can affect the order of initialization of global objects). I will try to make a reproducer when I have time. |
Date Modified | Username | Field | Change |
---|---|---|---|
2020-10-12 22:42 | galbramc | New Issue | |
2020-10-12 22:42 | galbramc | Assigned To | => abv |
2020-10-12 23:07 | kgv | Product Version | => 7.5.0 |
2020-10-12 23:08 | kgv | Relationship added | related to 0025616 |
2020-10-12 23:09 | kgv | Summary | [OCCT] 7.5.0 Beta memory leak in Standard_MMgrFactory => Coding - memory leak in Standard_MMgrFactory |
2020-10-13 07:33 | kgv | Product Version | 7.5.0 => 6.3.1 |
2020-10-13 07:33 | kgv | Target Version | => 7.6.0 |
2020-10-13 07:33 | kgv | Target Version | 7.6.0 => 7.5.0 |
2020-10-13 07:37 | kgv | Relationship added | child of 0008503 |
2020-10-13 07:38 | kgv | Description Updated | |
2020-10-13 07:46 | git | Note Added: 0095909 | |
2020-10-25 12:07 |
|
Note Added: 0096255 | |
2020-10-25 12:09 |
|
Note Edited: 0096255 | |
2020-10-25 12:10 |
|
Target Version | 7.5.0 => 7.6.0 |
2020-10-25 19:49 | galbramc | Note Added: 0096256 | |
2020-10-26 15:42 |
|
Note Added: 0096269 | |
2020-10-26 16:34 | galbramc | Note Added: 0096272 | |
2020-10-26 16:59 | kgv | Note Added: 0096274 | |
2020-10-26 17:24 | galbramc | Note Added: 0096277 | |
2020-10-31 10:59 |
|
Note Added: 0096418 | |
2021-09-20 10:09 | kgv | Target Version | 7.6.0 => 7.7.0 |
2022-08-17 12:01 | kgv | Target Version | 7.7.0 => 7.8.0 |
2023-08-01 15:09 | dpasukhi | Target Version | 7.8.0 => Unscheduled |