Jump to content
Darian Miller

AssertErrorProc usage

Recommended Posts

I was digging into some code that leverages a custom AssertErrorProc to handle some unique errors in an app and I examined the help page (https://docwiki.embarcadero.com/CodeExamples/en/AssertErrorProc_(Delphi)) which states in a code comment:

{ No local variables. Not compiler generated temporary variables. }
{ Using the call stack here will cause Access Violation errors.

 

The routine I'm looking at uses a local variable...so the question is what is the downside of doing so?   

 

I couldn't find much info on this - few blog entries.

http://www.blong.com/Conferences/BorCon2002/Debugging/3188.htm

http://www.blong.com/Conferences/DCon99/VCLSourcery/VCLSourcery.htm

https://blog.matthewskelton.net/2012/01/29/assert-based-error-reporting-in-delphi/

 

I asked ChatGPT "In Delphi, you can reassign the default error handler for assertions by leveraging the AssertErrorProc system variable.  In the help file it is stated not to use local variables within this custom error procedure.  Why would that be a problem?"

Which responded:

"The reason for not using local variables within the custom error procedure assigned to the AssertErrorProc variable in Delphi is that the procedure is called at a very low-level when an assertion fails.  When an assertion fails, Delphi's runtime system calls the custom error procedure pointed to by AssertErrorProc. At this point, the program is in an unknown state, and the system stack may be corrupted. In this situation, local variables may not behave as expected, leading to unpredictable results or even crashes.  To avoid this problem, it is recommended to keep the custom error procedure as simple as possible and avoid using local variables or other resources that may rely on a stable system state. It's also a good idea to log any relevant information about the error before attempting to handle it, as the program's behavior may be unpredictable after an assertion failure."

 

Does anyone have further insight?  Currently it's just a matter of curiousity and I'm not tracking down a specific error.

 

 

Edited by Darian Miller
  • Like 1

Share this post


Link to post

Hm, I didn't read that comment when I used AssertErrorProc for tracing process flow. Never had any problem with the following procedure assigned to it:

var
  gblAssertTraceOn: Boolean = False;

var
  Trace: TStringList = nil;

procedure DebugAssertLine(const _Message, _Filename: string; _LineNumber: Integer; _ErrorAddr: Pointer);
var
  Line: string;
begin
  if gblAssertTraceOn then begin
    if not Assigned(Trace) then
      Trace := TStringList.Create;
    Line := ChangeFileExt(ExtractFileName(_Filename), '') + ':' + IntToStr(_LineNumber) + ' ' + _Message;
    Trace.Add(Line);
  end;
end;

But on the other hand, these calls were no error conditions but simply

Assert(False, 'Some descriptive text');

 

In the end the content of the Trace list was written to a file.

 

It allowed me to write a trace log with information like filename and line number which is difficult to get otherwise.

 

No idea whether using a local variable and the temporary storage used for string concatenation and all these function calls can actually become a problem. Also the code in question is single threaded.

 

I'd never use this in production code though.

Edited by dummzeuch

Share this post


Link to post
21 hours ago, Darian Miller said:

I asked ChatGPT ... Which responded:

Wow, that was actually a half-decent response, for once.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×