Root > How to... > ...add an event handler? > ...register event handler for leaks?

...register event handler for leaks?

Previous pageReturn to chapter overviewNext page   

Important Note: Leaks checking happens at a very special moment in your application: everything is already dead (finalized). Be sure to review your handler's code, so it will not access any globals, because these will be already finalized when leaks checking is running. Write code very carefully, don't forget that your whole application is basically already dead. This includes even most basic routines from the SysUtils unit! E.g. even a simple Format may fail. Definitely no throwing exceptions at this point!

 

Since leaks checking is such a special place - your typical event handlers will not run, as people usually write handler's code without such strict restrictions. However, you still can register event handler for leaks checking. You just need to (re-)register your event handlers during leaks checks. For example:

 

uses
  EException, // for TEurekaExceptionInfo
  EEvents,    // for RegisterEventXYZ
  ETypes;     // for MemLeaksShow
 
// Your event handlers
// It is just an example
procedure YourHandler1
 (const ACustom: Pointer;
  AExceptionInfo: TEurekaExceptionInfo; 
  var AHandle: Boolean; 
  var ACallNextHandler: Boolean);
begin
  // ...
end;
 
procedure YourHandler2
 (const ACustom: Pointer;
  AExceptionInfo: TEurekaExceptionInfo;
  const AEurekaAction: TEurekaActionType;
  const AAdditionalInfo: String;
  var AExecute: Boolean;
  var ACallNextHandler: Boolean);
begin
  // Just an example
  if AEurekaAction = atShowingExceptionInfo then
  begin
    // ...
  end;
end;
 
var
  // Default EurekaLog's code to show/process leaks
  ShowMemLeaks: TMemLeaksProc;
 
// Asks EurekaLog to call our event handler for leaks
procedure AssignEventHandlersForLeaks;
begin
  // Registers the handlers
  RegisterEventExceptionNotify(nil, YourHandler1);
  RegisterEventExceptionAction(nil, YourHandler2);
  // ...
  
  // Shows leaks
  ShowMemLeaks;
end;
 
finalization
  // Asks EurekaLog to call our code when leaks are found
  ShowMemLeaks := MemLeaksShow;
  MemLeaksShow := AssignEventHandlersForLeaks;
end.

 

Note: leaks checking is always run from the main thread and all background threads should already be finalized, so no synchronization is (usually) necessary.

 

You may even assign the same event handler for both your normal exceptions and for leaks! Just be sure that its code is safe to be run during leaks checking. If you want to distinguish between normal exceptions and leaks - you can use custom parameter. For example:

 

uses
  EException, // for TEurekaExceptionInfo
  EEvents,    // for RegisterEventXYZ
  ETypes;     // for MemLeaksShow
 
const
  // A special flag to indicate that
  // code runs during leaks checking

  // It could be anything

  // It is just an example
  CalledFromLeaks = Pointer(1);
 
// Your event handler
// It is just an example
procedure DoYourThing
 (const ACustom: Pointer;
  AExceptionInfo: TEurekaExceptionInfo; 
  var AHandle: Boolean; 
  var ACallNextHandler: Boolean);
var
  Leaks: Boolean;
begin
  // Are we being called during leaks checks?
  Leaks := (ACustom = CalledFromLeaks);
 
  // When called for normal exceptions -
  // you may want to use synchronization 
  // to access some globals 
  if not Leaks then 
    // It is just an example
    CriticalSection.Enter;
  try
 
    // Your code here
    if Leaks then 
    begin
      // Globals are already finalized,
      // so you should not access them
    end
    else
    begin
      // You can access globals here

      // We have already acquired sync obj
    end
 
  finally
    // It is just an example
    if not Leaks then 
      CriticalSection.Leave;
  end;
end;
 
var
  // Default EurekaLog's code to show/process leaks
  ShowMemLeaks: TMemLeaksProc;
 
// Asks EurekaLog to call our event handler for leaks
procedure AssignEventHandlersForLeaks;
begin
  // Registers the handler for leaks
  // Use the special flag to indicate that 
  // this happens during leaks checking
  RegisterEventExceptionNotify(CalledFromLeaks, DoYourThing);
  
  // Shows leaks
  ShowMemLeaks;
end;
 
initialization
  // Registers the handler for normal exceptions
  // Do not use any flags
  RegisterEventExceptionNotify(nil, DoYourThing);
 
finalization
  // Asks EurekaLog to call our code when leaks are found
  ShowMemLeaks := MemLeaksShow;
  MemLeaksShow := AssignEventHandlersForLeaks;
end.

 

Alternatively, you may just use properties of AExceptionInfo:

 

  // Are we being called during leaks checks?
  Leaks := (AExceptionInfo.ExceptionClass = 'EMemoryLeak') or

           (AExceptionInfo.ExceptionClass = 'EResourceLeak');
 

 

See also:




Send feedback... Build date: 2022-03-28
Last edited: 2022-03-09
PRIVACY STATEMENT
The documentation team uses the feedback submitted to improve the EurekaLog documentation. We do not use your e-mail address for any other purpose. We will remove your e-mail address from our system after the issue you are reporting has been resolved. While we are working to resolve this issue, we may send you an e-mail message to request more information about your feedback. After the issues have been addressed, we may send you an email message to let you know that your feedback has been addressed.


Permanent link to this article: https://www.eurekalog.com/help/eurekalog/how_to_register_event_handler_for_leaks.php