[fpc-pascal] Manually handling all exceptions
OBones
obones at free.fr
Tue Jul 3 17:16:16 CEST 2012
Hello all,
While I'm experimenting with DLLs generated by FreePascal, I made sure
that every exported function has its own try..except construct so that
no exception escapes from those functions. Instead, in the except part,
I do something like that:
on E: TObject do
begin
SetLastExceptionDetails(E);
Result := False;
end;
This works fine, but it has a cost both in writing and in execution time.
To avoid this, I would like to hook into the raise keyword with my own
code so that it does the following pseudo code:
Call SetLastExceptionDetails with the exception object
Set the return value to False (asm mov eax, 0 end;)
Resume execution at the end of the function located at the frontier
between the DLL and the host process.
To achieve this, I thought about using RaiseProc at first, but using
ExceptProc seems more promising. At least, I can do the first two steps,
but I'm having a hard time doing the last one.
I know I have to walk the stack to find procedure pointers inside it and
stop at the first valid one that is outside the DLL, but are there any
code examples around for this?
To test for the frontier between DLL and host process, I can use this
function:
function GetModuleBaseByAddr(Addr: Pointer): Pointer;
var
Tmm: TMemoryBasicInformation;
begin
if VirtualQuery(addr, @Tmm, SizeOf(Tmm)) <> SizeOf(Tmm) then
Result := nil
else
Result := Tmm.AllocationBase;
end;
in such a test :
if GetModuleBaseByAddr(AddressInStack) <>
GetModuleBaseByAddr(@someLabelInTheDLL) then
set eax to zero
return to caller of previous address in stack (using leave asm
instruction?)
However, I fear this would trash the stack and assume I would have to do
some cleanup.
What do you all think about that? Does it sound feasible? Do you have
any advices on how best to proceed?
Thanks in advance
OBones.
More information about the fpc-pascal
mailing list