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

_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to