Question

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.

Was it helpful?

Solution

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


Use the api registry functions as pointed out in the previous question or Blorgbeard commented to this question. Incorporated with the previous code, it would become something like this:

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.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top