Darian Miller 361 Posted April 19, 2023 (edited) 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 April 19, 2023 by Darian Miller 1 Share this post Link to post
dummzeuch 1505 Posted April 19, 2023 (edited) 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 April 19, 2023 by dummzeuch Share this post Link to post
Remy Lebeau 1394 Posted April 19, 2023 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