Re: [fpc-pascal] FPCUnit test + raise E;
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? 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 ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] FPCUnit test + raise E;
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
Re: [fpc-pascal] Get empty memory quickly or... an empty file
On 13/09/2013 16:17, Michael Van Canneyt wrote: On Fri, 13 Sep 2013, Reinier Olislagers wrote: On 13/09/2013 15:38, Marco van de Voort wrote: In our previous episode, Reinier Olislagers said: However, I'm sure there must be quicker ways (e.g. less newbie code; using OS functions to quickly create empty memor, or alternatively create a sparse file and zip the file instead of the stream). Do not create the data, but generate it in an overriden tstream read() call? If you can define a function that can generate count bytes of data at position n (in this case the function is constant), then you don't have to write it out. Ken in mind that TStream is an abstraction, not necessarily a block of (RAM or disk) memory. Mmm, yes, that sounds very smart, thanks! Attached a NullStream implementation. Thanks a lot; I extended it a bit so it looks a bit more like a TMemoryStream and use it in the tests for zipping. Works nicely. Oh, in case somebody wants to have a look, I've uploaded a patch for zip64 support ;) http://bugs.freepascal.org/view.php?id=23533 Thanks to everybody here and on the forum for the help. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] FPCUnit test + raise E;
On 15.09.2013 13:05, Marcos Douglas wrote: 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 [...]?) The raise-at statement allows you to raise an exception for a specific address. This allows you to have e.g. a error handling procedure (to wrap a more compilated generation of a exception class) but have the exception address still point to the original call site. E.g.: === code begin === procedure Error(aArg: Boolean); begin if aArg then raise Exception.Create('Test') else raise Exception.Create('Test') at get_caller_addr(get_frame), get_caller_frame(get_frame); end; procedure Test1; begin Error(True); end; procedure Test2; begin Error(False); end; begin try Test1; except DumpExceptionBackTrace(Output); end; try Test2; except DumpExceptionBackTrace(Output); end; end; === code end === In case one the stack trace will contain Test1 and Error in case two the stack trace will be only Test2. 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. Can you access fields of the InnerException? Maybe it's a problem of reraising an existing exception... 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 possibly be. If you could reproduce it in an as simple example as possible that would help. Another thing you could try (just for testing): change your exception handler procedure to a function that returns bool and use it like this: === code begin === procedure TghSQLConnector.Connect; begin try FLib.Connect; except on E: Exception do if not DoOnException(E) then raise; end; end; === code end === Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Parser bug or what?
15.09.13, 21:14, Daniel Gaspary wrote: On Sun, Sep 15, 2013 at 6:37 AM, Sven Barth pascaldra...@googlemail.com wrote: Seems to be a bug related to scoped enums (in your example that would be TMyEnum.me1). Please report it as a bug with the example mentioned above as a file. Done: http://bugs.freepascal.org/view.php?id=25029 Fixed in r25493. The fix also helped to find a bug in fpmake.pp which is used to compile a52 package. Thank you. Best regards, Paul Ishenin ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Parser bug or what?
I cannot update my Environment at the moment, so I will just close the bug. Thank you, Paul On Sun, Sep 15, 2013 at 11:52 PM, Paul Ishenin paul.ishe...@gmail.com wrote: 15.09.13, 21:14, Daniel Gaspary wrote: On Sun, Sep 15, 2013 at 6:37 AM, Sven Barth pascaldra...@googlemail.com wrote: Seems to be a bug related to scoped enums (in your example that would be TMyEnum.me1). Please report it as a bug with the example mentioned above as a file. Done: http://bugs.freepascal.org/view.php?id=25029 Fixed in r25493. The fix also helped to find a bug in fpmake.pp which is used to compile a52 package. Thank you. Best regards, Paul Ishenin ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal