Skip to content

TServiceManager.QueryServiceConfig() creates a memory leak

Summary

TServiceManager.QueryServiceConfig() creates a memory leak.

System Information

  • Operating system: Windows 11
  • Processor architecture: x86-64, AARCH64 (FPC runs as true x64 version on native Windows 11 on ARM64.)
  • Compiler version: 3.2.2, trunk

Steps to reproduce

Call TServiceManager.QueryServiceConfig() with Heaptrc enabled. In my case 388 bytes got allocated via GetMem() but only 328 bytes released via FreeMem().

Example Project

Attached a simple sample project for Windows with Heaptrc on: ServiceManagerMemoryLeak.zip

What is the current bug behavior?

Memory allocated gets not fully released as the actual size gets overridden as BytesNeeded is used twice in the actual Windows API call QueryServiceConfig(SHandle,SvcCfg,BytesNeeded,BytesNeeded).

What is the expected (correct) behavior?

Full release of memory allocated.

Possible fixes

Here is a simple fix for trunk: ServiceManager.diff

procedure TServiceManager.QueryServiceConfig(SHandle : THandle; Var Config : TServiceDescriptor);

Var
  SvcCfg : PQueryServiceConfig;
  BytesNeeded, BytesSize : DWord;

begin
  {$IFDEF FPC_DOTTEDUNITS}WinApi.Jedi.WinSvc{$ELSE}jwawinsvc{$ENDIF}.QueryServiceConfig(SHandle,Nil,0,BytesNeeded);
  If (GetLastError<>ERROR_INSUFFICIENT_BUFFER) then
    RaiseLastOSError;
  BytesSize := BytesNeeded;
  GetMem(SvcCfg,BytesSize);
  Try
    If Not {$IFDEF FPC_DOTTEDUNITS}WinApi.Jedi.WinSvc{$ELSE}jwawinsvc{$ENDIF}.QueryServiceConfig(SHandle,SvcCfg,BytesSize,BytesNeeded) then
      RaiseLastOSError;
    With config,SvcCfg^ do
      begin
      Password:='';
      Name:='';
      DesiredAccess:=0;
      ErrorControl:=dwErrorControl;
      ServiceType:=dwServiceType;
      StartType:=dwStartType;
      TagID:=dwTagID;
      CommandLine:=lpBinaryPathName;
      LoadOrderGroup:=lpLoadOrderGroup;
      Dependencies:=lpDependencies;
      UserName:=lpServiceStartName;
      DisplayName:=lpDisplayName;
      end;
  Finally
    FreeMem(SvcCfg,BytesSize);
  end;
end;
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information