0
votes

i am working on a application in Delphi 7 that will run and display the the log created by FastMM4.pas.

The application will be installed anywhere on the system. I have modified the FastMM4.pas so that it will CreateProcess(inshort execute my application) The code from my previous Question and Sertac Akyuz's answer

The leakTracker.exe will take in the fastmm4's log file as the parameter and open the file and display. The modified fastMM4.pas will be used in any other application.

Procedure OpenTheLeakReader
 begin
 CmdLine := 'C:\Program Files\leakTracker\leakTracker.exe "';  
 lstrcat(CmdLine,CTheArGuements ); 
 ZeroMemory(@SInfo, SizeOf(SInfo));
 SInfo.cb := SizeOf(SInfo);
 CreateProcess(nil, CmdLine, nil, nil, False,  NORMAL_PRIORITY_CLASS, nil, nil, sInfo, pInfo);
end;

This works fine but i have hardcoded the path because to get my application path..

                 [FastMM4]  -cannot use SysUtils.pas     //*1
                            -cannot use Registry.pas     //*2
                            -cannot use ParamStr(0)      //*3
                            -cannot use unitWithSysRegis //*4

                 [someAplicationWhichWillUseFastMM4] -Uses FastMM4.pas  

in the FAstMM4.pas finalization i have this

          if ifLeakedMemory then OpenTheLeakReader;

since i cannot have

*1 - SysUtils.pas - in FastMM4.pass as this will un-install fastmmm4

*2 - Registry.pas - to search leakTracker installation path but will uninstall fastmm4

*3 - paramstr(0) - it gives a error at the close of application.

*4 - unitWithSysRegis - with SysUtils,Registry also not possible in Fastm4 uses clause.

So I am stuck as how to get the path of leakTracker.exe and send the path of the log file to the `leakTracker.exe' through CreateProcess.

1
You could import the Windows registry functions yourself?Blorgbeard
@Blorgbeard i didnt get how to do that..any examples?PresleyDias
Actually, can you use windows unit? It has RegOpenKeyEx, RegGetValueEx etc. If not, you could copy the definitions from there.Blorgbeard
@Blorg FastMM cannort use any units other than implicit System.David Heffernan
@sertac if so then that is because Windows.pas does not do heap allocation in its initializationDavid Heffernan

1 Answers

2
votes

(For an explanation first (regarding the linked question in the question), this question is not just about not being able to use units (having initialization sections requiring memory allocation) in FastMM4.pas. OP thinks that his code has to run after FastMM finalizes the memory manager. FastMM raises an exception if memory is allocated after that, so allocating memory via RTL is prohibited.)


var
  hReg: HKEY;
  Ret: Longint;
  RegDataType, RegDataSize: DWORD;
  CmdLine: array [0..560] of Char; // increase as needed
  Len: Integer;
  SInfo: TStartupInfo;
  PInfo: TProcessInformation;


initialization
{$ifndef BCB}
  // fastmm code
{$endif}

finalization
{$ifndef PatchBCBTerminate}
  FinalizeMemoryManager;  // fastmm code



  Ret := windows.RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                  'SOFTWARE\[YourProgram]', // registry key to your program's path
                  0, KEY_READ, hReg);

  RegDataType := REG_SZ;
  RegDataSize := 260;
  Ret := windows.RegQueryValueEx(hReg,
                  'path',       // registry value containing your program's path
                  nil, @RegDataType, @CmdLine, @RegDataSize);
  RegCloseKey(hReg);

  CmdLine[RegDataSize - 1] := ' ';
  CmdLine[RegDataSize] := '"';     // open doublequote in case spaces in path
  Len := windows.GetModuleFileName(0,
          PChar(@CmdLine[RegDataSize + 1]), 260) + RegDataSize;

  while CmdLine[Len] <> '.' do     // assumes executable has an extension
    Dec(Len);
  CmdLine[Len] := #0;
  lstrcat(CmdLine, '_MemoryManager_EventLog.txt"'#0);  // closing doublequote

  ZeroMemory(@SInfo, SizeOf(SInfo));
  SInfo.cb := SizeOf(SInfo);
  CreateProcess(nil, CmdLine, nil, nil, False,
                NORMAL_PRIORITY_CLASS, nil, nil, sInfo, pInfo);

{$endif}
end.