Memory Manager is called from the system.pp initialization section
Original Reporter info from Mantis: maxim-masiutin
-
Reporter name: Maxim Masiutin
Original Reporter info from Mantis: maxim-masiutin
- Reporter name: Maxim Masiutin
Description:
Memory Manager's function GetMem is called from the system.pp initialization section.
The initialization section should not allocate any memory, because it prevents installing custom memory manager before the first call to GetMem, so you will get different memory block allocated by different memory managers which will cause further troubles. You should make the changes to prevent FreePascal from allocating any memory (GetMem) before the program will be able to set up custom memory manager with SetMemoryManager.
Steps to reproduce:
Compile and run the following program:
program Test;
var
HeapTotalAllocated: Cardinal;
begin
HeapTotalAllocated := GetHeapStatus.TotalAllocated;
WriteLn(HeapTotalAllocated);
end.
It displays the number of heap bytes allocated (HeapTotalAllocated), and it displays values more than 0 indicating that some memory is allocated from the system.pp initialization clause. This code compiled with FreePascal displays 160 bytes under Win64 or 96 bytes under Win32. It would have displayed 0 if there were no bug (like in Delphi).
Additional information:
Specifically, FreePascal calls setup_arguments from the "system.pp" unit to initialize argc and argv variables.
I have checked FreePasal 3.0.4 (that only calls setup_arguments that allocates at least 160 bytes under 64-bit Windows target) and 3.2.0 (allocates at least 96 bytes for 32-bit Windows target).
But 3.3.1 allocates even more bytes, at least 448 bytes, see https://github.com/maximmasiutin/FastMM4-AVX/pull/13#issuecomment-737404905
Thus, if I later install a custom memory manager via SetMemoryManager, some memory will be already allocated by the old memory manager. This is in contrast to Delphi that does not allocate any memory in the System unit, allowing to define a custom memory manager as the first module in the uses list. FreePascal does not allow it. If I add the first unit as the memory manager, when its "initialize" section will be called, some memory is already allocated.
Can you please change this behavior, e.g. remove argc and argv from global variables and add a function like GetCommandLineArgs to return them, so it will only call setup_arguments then, so you will remove the call setup_arguments from the system.pp unit. It was a bad idea after all to add this call there. I understand that this will break compatibility and will require documentation change, but this should be good approach, since command line may not be needed for some applications while you are making unnecessary calls always to get the memory for the argc and argv which is not good.
Mantis conversion info:
- Mantis ID: 38391
- Version: 3.2.0
- Monitored by: » @martok (Martok), » @xhajt03 (Tomas Hajny), » VDPasha (Pavel), » @sergy.larin (Sergey Larin)