[fpc-pascal] Exception handling and .dylibs on MacOS
    Adriaan van Os 
    adriaan at adriaan.biz
       
    Thu Apr  3 14:47:32 CEST 2025
    
    
  
I recall this thread from last October
> I reported this, with a test program, as bug #40950 
> <https://gitlab.com/freepascal.org/fpc/source/-/issues/40950>.
The problem is that the fpc RTL, with its global variables, is duplicated in the .dylib as well as 
in the main program, which confuses the exception handling code. To resolve that, I have been 
experimenting with replacing exception-handling global variables in the RTL with functions and 
implementing those functions once (not twice) in a separate dynamic library. For example, adding 
rtl/inc/except.inc
{$ifdef FPC_HAS_EXTERNAL_EXCEPTION_GLOBALS}
function GetExceptAddrStack: PPExceptAddr; cdecl; external;
function GetExceptObjectStack: PPExceptObject; cdecl; external;
function GetExceptTryLevel: PObjpasInt; cdecl; external;
{$else}
{$ifdef FPC_HAS_FEATURE_THREADING}
ThreadVar
{$else FPC_HAS_FEATURE_THREADING}
Var
{$endif FPC_HAS_FEATURE_THREADING}
   ExceptAddrStack   : PExceptAddr;
   ExceptObjectStack : PExceptObject;
   ExceptTryLevel    : ObjpasInt;
{$endif}
etcetera. And then
unit exceptvars;
interface
   uses
     cthreads;
   type
     ObjpasInt = Longint;
     PObjpasInt = ^ObjpasInt;
function GetExceptAddrStack: PPExceptAddr; cdecl; public;
function GetExceptObjectStack: PPExceptObject; cdecl; public;
function GetExceptTryLevel: PObjpasInt; cdecl; public;
implementation
threadvar
   ExceptAddrStack   : PExceptAddr;
   ExceptObjectStack : PExceptObject;
   ExceptTryLevel    : ObjpasInt;
function GetExceptAddrStack: PPExceptAddr; cdecl; public;
begin
   GetExceptAddrStack := @ExceptAddrStack
end;
function GetExceptObjectStack: PPExceptObject; cdecl; public;
begin
   GetExceptObjectStack  := @ExceptObjectStack
end;
function GetExceptTryLevel: PObjpasInt; cdecl; public;
begin
   GetExceptTryLevel := @ExceptTryLevel
end;
begin
end.
and
library lib;
   uses
     exceptvars;
exports
   GetExceptAddrStack,
   GetExceptObjectStack,
   GetExceptTryLevel;
begin
end.
Now, the example code in the bug report 
<https://gitlab.com/freepascal.org/fpc/source/-/issues/40950> (when linked to the .dylib with the 
exception variables) no longer crashes and the exception is handled gracefully. Wel, actually I 
have to add an
erroraddr := nil
manually before exiting, because that variable and others need also be included in the 
exception-globals dylib (in the same way). I think these are the following, but correct me if I 
forget one:
erroraddr
errrorcode
errorbase
ErrorProc
Well, in what form will a patch along these lines be accepted ? I really need this to be fixed.
Another idea, that should work but that I didn't test yet, is to store the mentioned variables with 
pthread_getspecific and pthread_setspecific. In that case also, there is no duplication of them. An 
exception-globals dylib would not be needed, but it might be slower ?
Regards,
Adriaan van Os
    
    
More information about the fpc-pascal
mailing list