On Sun, Sep 15, 2013 at 6:56 AM, Sven Barth <pascaldra...@googlemail.com> wrote: > On 15.09.2013 03:21, Marcos Douglas wrote: >> >> Hi, >> >> 1) I have a code like that: >> >> procedure TghSQLConnector.Connect; >> begin >> try >> FLib.Connect; >> except >> on E: Exception do >> DoOnException(E); >> end; >> end; >> >> https://github.com/mdbs99/Greyhound/blob/0.1.8/src/ghsql.pas#L1565 >> >> >> 2) DoOnException was implemented so: >> >> procedure TghSQLHandler.DoOnException(E: Exception); >> begin >> if Assigned(FOnException) then >> FOnException(Self, E) >> else >> raise E; >> end; >> >> https://github.com/mdbs99/Greyhound/blob/0.1.8/src/ghsql.pas#L443 >> >> >> So, as you see, if occurs a Exception the code checks if the event >> (OnException) was setted. If yes, call user implementation; if no, >> call raise E; >> It works... but not when I uses in FPCUnit tests. >> >> See a simple test (this works): >> >> procedure TghSQLConnectorTest.TestOnException; >> begin >> // catch >> FConn.OnException := @DoOnException; >> FConn.Script.Text := 'foo'; >> FConn.Execute; >> end; >> >> https://github.com/mdbs99/Greyhound/blob/0.1.8/test/ghsqltest.pas#L246 >> >> >> The code DoOnException is: >> >> procedure TghSQLTest.DoOnException(Sender: TObject; E: Exception); >> begin >> AssertTrue(Assigned(E)); >> end; >> >> https://github.com/mdbs99/Greyhound/blob/0.1.8/test/ghsqltest.pas#L141 >> >> So, if I change the test like bellow... BUM! SIGSEGV!! >> >> procedure TghSQLConnectorTest.TestOnException; >> begin >> // removed >>> FConn.OnException := @DoOnException; >> FConn.Script.Text := 'foo'; >> FConn.Execute; >> end; >> >> >> The ERROR is: >> [Content] >> Project test raised exception class 'External: SIGSEGV'. >> >> At address 40B758 > > > Could you as a test replace the > > raise E > > with > > raise E at get_caller_addr(get_frame), get_caller_frame(get_frame); > > and check whether this makes a difference?
I tried. No makes difference. (could you explain which the difference to call "raise" using "raise E at [...]"?) I implemented -- but not up to Git yet -- some like that: procedure TghSQLHandler.DoOnException(E: Exception); var NewEx: EghSQLError; begin if Assigned(FOnException) then FOnException(Self, E) else begin NewEx := EghSQLError.Create(Self, E.Message); // <<< NewEx.InnerException := E; // <<< raise NewEx; end; end; So, if I recreate the Exception, it works in any cases. As you see, I created a new property (InnerException) to save the original exception to know what the real Exception happened... But I think this introduces much more overhead to processing. In my code I have classes that inherited from TghSQLHandler. This class have the DoOnException method. So DoOnException can be call many times in override methods. Maybe the program "broke" the stack because "raise E" can be call and raise an exception; the next "level" raise another; and next call again. :/ > Could you also compile the RTL with debug information and maybe also without > optimizations (CROSSOPT="-gl -O-") and rerun your test and display the stack > trace (you'll need to enable "-gl" for your test as well)? > > Regards, > Sven I will try too. Marcos Douglas _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal