Recent

Author Topic: mORMot memory manager  (Read 2625 times)

spenov

  • New Member
  • *
  • Posts: 13
mORMot memory manager
« on: August 09, 2025, 02:34:53 pm »
I'm using the mORMot memory manager. When handling an exception in the program, the stack is being read (DumpCallStack). While reading the stack, the executable (exe) file is opened (OpenExeFile). When the application shuts down, the memory manager's unit is finalized first, and then the system units that close the previously opened exe file (CloseExeFile). At this point, an exception occurs because the memory manager has already been changed (deinitialized). How can I avoid this conflict?


Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12527
  • Debugger - SynEdit - and more
    • wiki
Re: mORMot memory manager
« Reply #1 on: August 09, 2025, 02:59:22 pm »
Add the unit with the mem mgr by using the command line  -FaUnitWithMemMgr

That way it will be added earlier, initialized earlier, and de-initialized later.

spenov

  • New Member
  • *
  • Posts: 13
Re: mORMot memory manager
« Reply #2 on: August 09, 2025, 03:07:35 pm »
This didn't help. The unit initialization order remained the same, and the same error still occurs.

spenov

  • New Member
  • *
  • Posts: 13
Re: mORMot memory manager
« Reply #3 on: August 09, 2025, 03:12:07 pm »
I have attached a test project. On the form, you need to click the button, and an error will occur when closing the application.

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
Re: mORMot memory manager
« Reply #4 on: August 09, 2025, 04:33:46 pm »
I'm using the mORMot memory manager.

Hello.

In your attached project, I dont not see how you use the mormot memory manager.

Usually it is done by adding  mormot.core.fpcx64mm (for  x86_64) as first unit in uses section of the main program unit (project1.lpr).

Sure I miss something but what?

[EDIT]
I suppose that you have added this parameter, so, sorry for the noise.
$ fpc -Famormot.core.fpcx64mm project1.lpr

« Last Edit: August 10, 2025, 05:52:32 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
Re: mORMot memory manager
« Reply #5 on: August 09, 2025, 05:16:43 pm »
Re-hello.

I think the problem comes from sysutils conflicting with mormot manager.
CloseExeFile is used by sysutils after a OpenExeFile at finalization of sysutils.
But if using mormot.core.fpcx64mm as first unit, finalization of this unit will be done after finalization of sysutils (it is the fpc reverse order).


So a workaround is to create a "PreSysUtils" unit, add it before mormot.core.fpcx64mm, then as usual, add the "original" sysutils:

Code: Pascal  [Select][+][-]
  1. unit PreSysUtils;
  2. interface
  3. implementation
  4. uses
  5.   SysUtils;
  6. end.

and in project:

Code: Pascal  [Select][+][-]
  1. program project1;
  2. uses
  3.   PreSysUtils,
  4.   mormot.core.fpcx64mm,
  5.   SysUtils;
  6. begin
  7.   // Your program code
  8. end.

Compile it without -Famormot.core.fpcx64mm.

That way, finalization of SysUtils will be done before finalization of mormot manager.

(Yes, indeed, Gork helped me a little  :-[ )

« Last Edit: August 10, 2025, 05:53:39 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Zoran

  • Hero Member
  • *****
  • Posts: 1990
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: mORMot memory manager
« Reply #6 on: August 09, 2025, 11:11:16 pm »
Re-hello.

I think the problem comes from sysutils conflicting with mormot manager.
CloseExeFile is used by sysutils after a OpenExeFile at finalization of sysutils.
But if using mormot.core.fpcx64mm as first unit, finalization of this unit will be done before finalization of sysutils (it is the fpc order).


So a workaround is to create a "PreSysUtils" unit, add it before mormot.core.fpcx64mm, then as usual, add the "original" sysutils:

Code: Pascal  [Select][+][-]
  1. unit PreSysUtils;
  2. implementation
  3. uses
  4.   SysUtils;
  5. end.

and in project:

Code: Pascal  [Select][+][-]
  1. program project1;
  2. uses
  3.   PreSysUtils,
  4.   mormot.core.fpcx64mm,
  5.   SysUtils;
  6. begin
  7.   // Your program code
  8. end.

Compile it without -Famormot.core.fpcx64mm.

That way, finalization of SysUtils will be done before finalization of mormot manager.

(Yes, indeed, Gork helped me a little  :-[ )

That is same as just putting SysUtils before mormot manager unit in main unit uses section. SysUtils is initialized before mormot and finalized after it.
Just unnecessary complicated.
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

Zoran

  • Hero Member
  • *****
  • Posts: 1990
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: mORMot memory manager
« Reply #7 on: August 09, 2025, 11:17:51 pm »
And, I think the main problem is that the default memory manager is initialized in SysUtils, hence the point is that alternative memory manager must be initialized befoure SysUtils.
So, Fred, your proposal cannot help.
Swan, ZX Spectrum emulator https://github.com/zoran-vucenovic/swan

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
Re: mORMot memory manager
« Reply #8 on: August 09, 2025, 11:38:54 pm »
That is same as just putting SysUtils before mormot manager unit in main unit uses section. SysUtils is initialized before mormot and finalized after it.
Just unnecessary complicated.

That is exactly the problem: SysUtils is initialized before mormot and finalized after it.

// from Gork:
Quote
Why PreSysUtils Is NecessaryControl Over Finalization Order: Simply listing SysUtils before mormot.core.fpcx64mm in the main program doesn’t guarantee that SysUtils finalizes before the memory manager, because the main program’s uses clause directly controls the order of the listed units. SysUtils finalizing last in this case is the problem.

Dependency Chain: PreSysUtils creates an indirect dependency, making SysUtils part of a unit that is finalized after mormot.core.fpcx64mm but whose dependencies (i.e., SysUtils) finalize before it. This subtle shift in the dependency chain is what fixes the issue.
Avoiding Direct Conflict: Without PreSysUtils, there’s no way to force SysUtils to finalize before mormot.core.fpcx64mm using only the main program’s uses clause, as SysUtils would always finalize after the memory manager if listed directly.

Using the PreSysUtils unit is good if you want to rely on unit initialization order to ensure SysUtils finalizes before mormot.core.fpcx64mm, avoiding the need for manual file-closing workarounds.

the default memory manager is initialized in SysUtils

SysUtils uses the one defined by System that is replaced directly by mormot.core.fpcx64mm.
.
To resume:

Without PreSysUtils (with "direct" SysUtils):

Init: SysUtils → mormotMM
Fini: mormotMM → SysUtils (crash risk)

With PreSysUtils:

Init: PreSysUtils(SysUtils) → mormotMM
Fini: mormotMM → PreSysUtils(SysUtils) (safe)

That said, mORMot2 memory manager is a game changer and I dont understand why fpc does not adopt it as default memory manager.

Also note that this workaround was proposed by Elon's AI (and Elon has been rambling a bit lately  :-X ... but his Dragon worked great yesterday  ;) )
« Last Edit: August 10, 2025, 03:46:06 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 3952
    • StrumPract is the musicians best friend
Re: mORMot memory manager
« Reply #9 on: August 10, 2025, 04:53:56 am »
Ooops, forget all what I gave, I tested it and get a error when using sysutils or PreSysUtils as first unit in uses clause.

Code: Pascal  [Select][+][-]
  1. Run error(211) Call to abstract method.

So, I apologize for all the loud noise.

And Grrrrrr for Gork.   >:(

[EDIT] I created a issue on mORMot2. https://github.com/synopse/mORMot2/issues/373
« Last Edit: August 10, 2025, 05:46:41 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

spenov

  • New Member
  • *
  • Posts: 13
Re: mORMot memory manager
« Reply #10 on: August 10, 2025, 08:43:25 am »
The problem can be solved by modifying the compiler file lnfodwrf.pp. The module finalization procedure needs to be made public, and then called before finalizing the memory manager in your own unit.
But modifying the compiler's source code is not a very convenient or practical solution.


Code: Pascal  [Select][+][-]
  1. unit lnfodwrf;
  2. ...
  3. procedure FinalizeInfodwrf;
  4.  
  5. implementation
  6. ...
  7. procedure FinalizeInfodwrf;
  8. begin
  9.    CloseDwarf;
  10.    Abbrev_Offsets:=nil;
  11.    Abbrev_Tags:=nil;
  12.    Abbrev_Children:=nil;
  13.    Abbrev_Attrs:=nil;
  14. end;
  15. ...
  16. finalization
  17.   FinalizeInfodwrf;
  18.  

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. uses ... , lnfodwrf;
  4. ...
  5. finalization
  6.    FinalizeInfodwrf;
  7.  

abouchez

  • Full Member
  • ***
  • Posts: 138
    • Synopse
Re: mORMot memory manager
« Reply #11 on: August 11, 2025, 04:11:03 pm »
... the memory manager's unit is finalized first ...
I don't understand this statement.
I have never observed this.

Here is how the mormot.core.fpcx64mm unit is setup:
Code: [Select]
initialization
  InitializeMemoryManager;
  GetMemoryManager(OldMM);
  SetMemoryManager(NewMM);

finalization
  SetMemoryManager(OldMM);
  FreeAllMemory;
I don't see anything wrong in this code. It even restores any previous memory manager.

Therefore, two remarks:

1) debug a little more and check exactly the order of units initialization/finalization

2) mORmot has its own Dwarf reader and exception handling for the stack trace - you may consider using it instead of the one from the RTL (it can also shrink a lot the debug information using a compressed format on production)


spenov

  • New Member
  • *
  • Posts: 13
Re: mORMot memory manager
« Reply #12 on: August 11, 2025, 04:19:33 pm »
1) debug a little more and check exactly the order of units initialization/finalization

During call stack determination, memory is allocated, which is released in the module's finalization section. Since this module is finalized after the memory manager module, an error occurs when attempting to free the memory, as it was allocated by the mormot memory manager. I have verified this under the debugger. Therefore, my fix involves releasing the memory before unloading the mormot memory manager.

2) mORmot has its own Dwarf reader and exception handling for the stack trace - you may consider using it instead of the one from the RTL (it can also shrink a lot the debug information using a compressed format on production)

Could you provide a link where I can read more about this?

abouchez

  • Full Member
  • ***
  • Posts: 138
    • Synopse
Re: mORMot memory manager
« Reply #13 on: August 11, 2025, 05:00:48 pm »
this module is finalized after the memory manager module
I simply can not believe this.

spenov

  • New Member
  • *
  • Posts: 13
Re: mORMot memory manager
« Reply #14 on: August 11, 2025, 05:05:38 pm »
I simply can not believe this.

I uploaded the project demonstrating this above.

 

TinyPortal © 2005-2018