FPC internal exception lazarus / 64-FPC development ---------------------------------------------------------------------- 440bx · 2024-05-20 17:42 Hello, This applies to the current release of FPC, i.e, v3.2.2.  when compiling the following unit: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$MODESWITCH ADVANCEDRECORDS    ON}  unit ErrorHandler;  { ----------- ---------------------------------------------------------------- }INTERFACE{ ---------------------------------------------------------- ----------------- } type  TERROR_ID =  (   eid_no_error,    eid_uninitialized_program_data  ); type  TERROR_STATE    = record    strict private      es_procname_last_entered : pchar;   { name of last entered function/proc}      es_error                 : TERROR_ID;     public      procedure Init();      function  Errored()          : boolean;      procedure SetError(InErrorId : TERROR_ID);      procedure SetProcName(InProcName : pchar = {$I %CURRENTROUTINE%}};  end;  var  ErrorState     : TERROR_STATE;  { ------------------------- -------------------------------------------------- }IMPLEMENTATION{ -- ---------------------------------------------------------------------- --- }  procedure TERROR_STATE.Init();begin  es_procname_last_entered := nil;  es_error                 := eid_no_error;end;  function TERROR_STATE.Errored : boolean;begin  result := es_error <> eid_no_error;end; procedure TERROR_STATE.SetError(InErrorId : TERROR_ID);begin  es_error := InErrorId;end; procedure TERROR_STATE.SetProcName(InProcName : pchar};begin  es_procname_last_entered := InProcName;end;  end. The compiler reports an internal exception: Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i [size=10pt]Verbose: Compiling ErrorHandler.pasErrorHandler.pas(33,51) Error: Compilation raised exception internallyVerbose: Compilation abortedDebug: An unhandled exception occurred at $00000001000B7860:Debug: EAccessViolation: Access violationDebug:   $00000001000B7860Debug:   $00000001000BB450Debug:   $00000001000BC0A9Debug:   $00000001000BC43EDebug:   $000000010015AC62Debug:   $00000001000E7344Debug:   $00000001000E6FDDDebug:   $00000001000E8A33Debug:   $00000001000EA924Debug:   $00000001000EAC47Debug:   $000000010017BFBEDebug:   $000000010017C624Debug:   $000000010017CE90Debug:   $00000001001601F2Debug:   $0000000100160EBDDebug:   $00000001000E669EDebug:   $000000010019D592Debug: Verbose: D:\fpcTrunk2\fpc\bin\x86_64-win64\ppcx64.exe returned an error exitcode[/size] It does not like having the {$I %CURRENTROUTINE%} as the default value for an optional parameter. ETA: Just to be on the safe side, this is on Windows, specifically Windows 7, 64 bit using the 64 bit version of the FPC compiler executed by Lazarus 64bit v3.99 Anything else you want to know, just ask. ---------------------------------------------------------------------- 440bx · 2024-05-20 17:54 It's probably obvious what I was trying to accomplish.  Have the "SetProcName" automatically grab the function/procedure name of the function/procedure where it is being invoked.  It would be very convenient to make that work somehow. So that's my question now: does anyone know a way that is acceptable to the compiler to have it feed the function/procedure name as a parameter value ? thank you for your help. ---------------------------------------------------------------------- Martin_fr · 2024-05-20 17:55 It also fails if the "{$I %CURRENTROUTINE%}" is placed outside the class in the interface section... And in both cases, I would ask what should it include? There can't be a current routine, outside of a routine? (not sure if the header of a routine is considered part of it for that particular directive). Of course, it still shouldn't crash, but rather give an error.... ---------------------------------------------------------------------- Martin_fr · 2024-05-20 17:57 Quote from: 440bx on May 20, 2024, 07:54:08 pmHave the "SetProcName" automatically grab the function/procedure name of the function/procedure where it is being invoked.  I was thinking about 2nd guessing that... Because (if that code worked), I would expect it to include the name of the procedure that contains the directive. So always "SetProcName". IIRC someone did once try that with macros, and that did not work either. ---------------------------------------------------------------------- 440bx · 2024-05-20 18:09 Quote from: Martin_fr on May 20, 2024, 07:57:48 pmIIRC someone did once try that with macros, and that did not work either. That's the kind of stuff that crosses the mind while coding and tried to see if by any chance it works (don't want to miss out on a good thing if it works.) It was worth a try... didn't work... oh well. but, as you said, it should emit an error not an internal exception. ---------------------------------------------------------------------- Martin_fr · 2024-05-20 18:22 Btw, depending on the underlaying needs.... If you did not plan on local debug logging, but rather something like printing traces "client side" at runtime, so people using your app can send in a (meaningful) trace for errors, then you don't need the names. Well in most cases. If the target OS allows a non-relocating exe (Mac does not, but afaik Win and Linux do). - Compile with debug info - keep a copy with debug info - create a stripped copy (must be from the same compiler run. Not just same source, but really same compilation) - distribute the stripped copy - use Leak-and-traces resolve button, to resolve address traces against the copy with debug info. Test it before relaying on it. ---------------------------------------------------------------------- 440bx · 2024-05-20 18:59 Thank you Martin. Like most everyone, I try to keep error handling as simple as possible (not always easy.)  My preferred method so far, is to output the routine name and a number that identifies the error sequentially in the routine.  That way if the same error can occur more than once, both errors have different identifiers because one has to forcefully be before or after the other, hence have a different sequence number. Fortunately, the program I'm currently working on is fairly simple and, doesn't require anything complicated. Your mentioning macros gave me an idea.  The following works and comes reasonably close to what I originally wanted: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$define _Entered:=ErrorState.SetProcName({$I %CURRENTROUTINE%})}That macro along with the error management unit works great All I need is to code "_Entered;" upon routine entry and the name is all set.  To set the error (if any), I've got: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$define _Errored:=ErrorState.SetError} Prefixing the macro names with "_" also makes them stand out (and no other routine in my code is prefixed with "-", therefore that really makes the macros stand out.) Now that I'm thinking about making the macros stand out, I might make them uppercase too.  They would be the ONLY non-type uppercase identifiers, since all the code is in lowercase, they would really stand out. Thank you for the help and the mention of the macro... that definitely helped. ---------------------------------------------------------------------- Martin_fr · 2024-05-20 19:32 Interesting that this macro works, because IIRC (need double checking) someone tried that with the filename/linenumber, and it added the line number where the macro was declared, rather that where it was used. Of course there is no routine where you declare the macro (I assume...) Personally, I use a code template Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i debugln(['$ProcedureName() '|]);The text is inserted, when I initially create the template. So it doesn't follow renames. And I can't copy and paste it. Actually, I could just put the compiler directive there, and that would work (for me). I don't mind, if it is longer text to read. It gets all auto inserted, so no work to type.