[fpc-pascal] Unhandled exception from library crashes host exe
Sven Barth
pascaldragon at googlemail.com
Wed Jun 27 19:15:11 CEST 2012
Am 27.06.2012 15:59 schrieb "kyan" <alfasud.ti at gmail.com>:
>
> I am sure that this has been asked before but I couldn't find an answer.
>
> I am in the process of porting a large application consisting of an
> exe and many dlls from Delphi7 to FPC 2.7.1/Lazarus for Windows/WinCE
> with hopes of being able to finally port it to Linux. I have managed
> to overcome all obstacles but this seems like a brick wall: An
> exception raised from a dll that is not handled by the dll's code will
> crash the exe, bypassing any try/finally/except handlers around the
> call into the dll that raised it. This is of course a complete
> showstopper because the API and code of the dlls is way too massive to
> re-engineer so that it does not let exceptions bubble up to the exe.
>
> In Delphi without packages the aforementioned situation can be handled
> reasonably well because despite the fact that operators "is" and "as"
> won't work on the dll's Exception object (its class pointer points
> inside the dll's Exception class and not the exe's Exception class) at
> least the exception handlers work so one can display an error message
> and keep the main application loop running. It is solved perfectly if
> one builds all executables with runtime packages so that there is only
> one Exception class for the exe and all dlls. But in FPC there are no
> "runtime packages" in the Delphi sense, therefore there doesn't seem
> to be a solution to this.
The problem is the following: the exception mechanism in FPC is implemented
in a FPC-only way and only interfaces with the OS at certain points. To be
more precise in Windows we use the API SetUnhandledExceptionFilter which
registers a callback function with the OS which is called once an exception
anywhere in the program (this includes DLLs) happens that is not handled by
a SEH handler. FPC does not support such SEH handlers, thus if an exception
is raised in a DLL (and here more especially an external, non-FPC
exception) the unhandled exception handler callback is called which tries
to find a fitting FPC except handler. I don't know the exact implementation
of the handler, but it might be that it either ignores exceptions which
happened in loaded DLLs (which leads to Windows terminating the process) or
terminates the process itself.
On Win64 it was started to support Windows' SEH (you need to build complete
trunk with "-dTEST_WIN64_SEH" to enable it), but this won't help you for
Win32 and WinCE. Adding support for WinCE on ARM might be rather easy
though (maybe not for you, but for someone experienced with the topic) as
it has a similar scheme as Win64. Win32 uses a different approach though,
so this will no be that easy...
Unix based systems might be a different topic altogether. I've no
experience regarding cross module excetions on *nix, so I can't comment
whether it works or not...
> Can someone suggest a solution, even if I have to manually apply a
> patch to FPC and build it myself? Because if there isn't one I will
> have to scrap the whole project.
You could try to fiddle around with the unhandled exception handler
callback in the system unit, but I can't help you there...
Nevertheless you need to search for SetUnhandledExceptionFilter in
%fpcdir%\rtl\win32 and then look for the function that is given there as an
argument.
Summa summarum: don't let exceptions travel past the DLL boundary. One
might be able to fix it on Windows, but *nix maybe not so much...
Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20120627/2bf6435b/attachment.html>
More information about the fpc-pascal
mailing list