View Issue Details

IDProjectCategoryView StatusLast Update
0031844CommunityOCCT:Codingpublic2023-08-01 15:09
Reportergalbramc Assigned Toabv 
PrioritynormalSeverityminor 
Status newResolutionopen 
PlatformLinuxOSDebian 6.0 
Product Version6.3.1 
Target VersionUnscheduled 
Summary0031844: Coding - memory leak in Standard_MMgrFactory
DescriptionThe 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 ReproduceRun any OCCT 7.5.0 beta test with valgrind.
TagsNo tags attached.
Test case number

Relationships

related to 0025616 closedbugmaster Open CASCADE Avoid Classes using "new" to allocate Instances but not defining a copy Constructor 
child of 0008503 closedskl Open CASCADE FIP 8.17 : Hide the objects to deny unauthorized operations with memory manager 

Activities

git

2020-10-13 07:46

administrator   ~0095909

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).

abv

2020-10-25 12:07

manager   ~0096255

Last edited: 2020-10-25 12:09

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.

galbramc

2020-10-25 19:49

reporter   ~0096256

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?

abv

2020-10-26 15:42

manager   ~0096269

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).

galbramc

2020-10-26 16:34

reporter   ~0096272

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.

kgv

2020-10-26 16:59

developer   ~0096274

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).

galbramc

2020-10-26 17:24

reporter   ~0096277

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.

abv

2020-10-31 10:59

manager   ~0096418

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.

Issue History

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 abv Note Added: 0096255
2020-10-25 12:09 abv Note Edited: 0096255
2020-10-25 12:10 abv Target Version 7.5.0 => 7.6.0
2020-10-25 19:49 galbramc Note Added: 0096256
2020-10-26 15:42 abv 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 abv 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