Re: [Lazarus] How to catch an unhandled exception? [FIXED - but there is an FPC bug here]
2018. 03. 09. 12:09 keltezéssel, Tony Whyman via Lazarus írta: Finally, knowing all this, I go back to Gabor's program and add the line (again shown in context): repeat SQR:=SM.Query(nil,SRB); for i:=0 to SQR.GetCount-1 do begin case SQR[i].getItemType of isc_info_svc_line:begin s:=SQR[i].getAsString; end; end; if (s<>'') then WriteLn(s); s := ''; {Line added here} end; until (s=''); and guess what - bug goes away. Confirmed. Executed the Debug and Release builds more than 100 times without any exception. Gabor -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] How to catch an unhandled exception? [FIXED - but there is an FPC bug here]
A supplementary for anyone confused by the last extra parameter to SetString in the previous post (repeated below). When I wrote up the bug report, I should have gone one step lower in the code. The SetString commented out below is actually an internal function: procedure TOutputBlockItem.SetString(out S: AnsiString; Buf: PByte; Len: integer; CodePage: TSystemCodePage); var rs: RawByteString; begin system.SetString(rs,PAnsiChar(Buf),len); SetCodePage(rs,CodePage,false); S := rs; end; However, the same result (e.g. the bug disappears) is achieved by commenting out the call to system.Setstring. On 09/03/18 11:09, Tony Whyman via Lazarus wrote: Thanks to Giuliano mentioning debug libraries I have been able to duplicate the problem and to find the source of the bug - but it is as weird as it gets. FYI: tests done on Linux Mint 18 with Lazarus 1.8.0 and fpc 3.0.4. The evidence so far: 1. Gabor's program ends with an exception when using the FPC release RTL and FCL, but not when using RTL and FCL libraries compiled for debugging. 2. If I use GDB to step through the final steps of the program, the bug disappears! 3. If I add a delay at the end (e.g. a call to sleep(1)), the bug disappears. 4. Playing around with code optimisations and debugging flags seems to have no effect. 5. Using the age old technique of commenting out bits of the code until the bug disappears, I tracked the problem down. In Gabor's program, the bug is removed by commenting out this line (shown in context) for i:=0 to SQR.GetCount-1 do begin case SQR[i].getItemType of isc_info_svc_line:begin // s:=SQR[i].getAsString; {This is where the problem starts} end; end; if (s<>'') then WriteLn(s); end; Going deeper into the fbintf package, I have further tracked the problem down to this line of code SetString(Result,FBufPtr+3,len,CP_ACP); FBufPtr is a pointer and it is fairly simple bit of code, copying a string from a buffer (received from Firebird) into an AnsiString. Commenting out the line stops the bug. The bug also goes away by changing it to var s: string; i: integer; ... Result := ''; SetString(s,FBufPtr+3,len,CP_ACP); for i := 1 to length(s) do Result += s[i]; which can only be described as a WTF moment. The problem has to be due to string disposal. Finally, knowing all this, I go back to Gabor's program and add the line (again shown in context): repeat SQR:=SM.Query(nil,SRB); for i:=0 to SQR.GetCount-1 do begin case SQR[i].getItemType of isc_info_svc_line:begin s:=SQR[i].getAsString; end; end; if (s<>'') then WriteLn(s); s := ''; {Line added here} end; until (s=''); and guess what - bug goes away. It looks like what is happening is that SetString is setting an AnsiString in such as away as to cause a problem when the memory manager cleans up - but only as a race condition and if the string is not cleaned up explicitly. Looks like an FPC bug report to me. On 09/03/18 09:14, Gabor Boros via Lazarus wrote: Hi All, The result of the attached example (which use MWA's Firebird Pascal API) for me is an exception: Gstat execution time Fri Mar 9 09:29:18 2018 Database header page information: Flags 0 Generation 173 System Change Number 0 Page size 8192 ODS version 12.0 Oldest transaction 161 Oldest active 162 Oldest snapshot 162 Next transaction 164 Sequence number 0 Next attachment ID 27 Implementation HW=AMD/Intel/x64 little-endian OS=Linux CC=gcc Shadow count 0 Page buffers 0 Next header page 0 Database dialect 3 Creation date Feb 2, 2018 14:07:24 Attributes force write Variable header data: *END* Gstat completion time Fri Mar 9 09:29:18 2018 Heap dump by heaptrc unit 355 memory blocks allocated : 948252/948432 355 memory blocks freed : 948252/948432 0 unfreed memory blocks : 0 True heap size : 131072 True free heap : 131072 An unhandled exception occurred at $7FF97F0A3147: EAccessViolation: $7FF97F0A3147 If comment out cthreads from the uses the exception is: An unhandled exception occurred at $7F21B71F5147: EAccessViolation: $7F21B71F5147 $7F21B71F751B $7F21B71F769C $7F21B746BFFF If run with gdb (and cthreads): Heap dump by heaptrc unit 355 memory blocks allocated : 948252/948432 355 memory blocks freed : 948252/948432 0 unfreed memory blocks : 0 True heap size : 131072 True free heap : 131072 [Thread 0x75991700 (LWP 2874) exited] [Thread
Re: [Lazarus] How to catch an unhandled exception? [FIXED - but there is an FPC bug here]
Thanks to Giuliano mentioning debug libraries I have been able to duplicate the problem and to find the source of the bug - but it is as weird as it gets. FYI: tests done on Linux Mint 18 with Lazarus 1.8.0 and fpc 3.0.4. The evidence so far: 1. Gabor's program ends with an exception when using the FPC release RTL and FCL, but not when using RTL and FCL libraries compiled for debugging. 2. If I use GDB to step through the final steps of the program, the bug disappears! 3. If I add a delay at the end (e.g. a call to sleep(1)), the bug disappears. 4. Playing around with code optimisations and debugging flags seems to have no effect. 5. Using the age old technique of commenting out bits of the code until the bug disappears, I tracked the problem down. In Gabor's program, the bug is removed by commenting out this line (shown in context) for i:=0 to SQR.GetCount-1 do begin case SQR[i].getItemType of isc_info_svc_line:begin // s:=SQR[i].getAsString; {This is where the problem starts} end; end; if (s<>'') then WriteLn(s); end; Going deeper into the fbintf package, I have further tracked the problem down to this line of code SetString(Result,FBufPtr+3,len,CP_ACP); FBufPtr is a pointer and it is fairly simple bit of code, copying a string from a buffer (received from Firebird) into an AnsiString. Commenting out the line stops the bug. The bug also goes away by changing it to var s: string; i: integer; ... Result := ''; SetString(s,FBufPtr+3,len,CP_ACP); for i := 1 to length(s) do Result += s[i]; which can only be described as a WTF moment. The problem has to be due to string disposal. Finally, knowing all this, I go back to Gabor's program and add the line (again shown in context): repeat SQR:=SM.Query(nil,SRB); for i:=0 to SQR.GetCount-1 do begin case SQR[i].getItemType of isc_info_svc_line:begin s:=SQR[i].getAsString; end; end; if (s<>'') then WriteLn(s); s := ''; {Line added here} end; until (s=''); and guess what - bug goes away. It looks like what is happening is that SetString is setting an AnsiString in such as away as to cause a problem when the memory manager cleans up - but only as a race condition and if the string is not cleaned up explicitly. Looks like an FPC bug report to me. On 09/03/18 09:14, Gabor Boros via Lazarus wrote: Hi All, The result of the attached example (which use MWA's Firebird Pascal API) for me is an exception: Gstat execution time Fri Mar 9 09:29:18 2018 Database header page information: Flags 0 Generation 173 System Change Number 0 Page size 8192 ODS version 12.0 Oldest transaction 161 Oldest active 162 Oldest snapshot 162 Next transaction 164 Sequence number 0 Next attachment ID 27 Implementation HW=AMD/Intel/x64 little-endian OS=Linux CC=gcc Shadow count 0 Page buffers 0 Next header page 0 Database dialect 3 Creation date Feb 2, 2018 14:07:24 Attributes force write Variable header data: *END* Gstat completion time Fri Mar 9 09:29:18 2018 Heap dump by heaptrc unit 355 memory blocks allocated : 948252/948432 355 memory blocks freed : 948252/948432 0 unfreed memory blocks : 0 True heap size : 131072 True free heap : 131072 An unhandled exception occurred at $7FF97F0A3147: EAccessViolation: $7FF97F0A3147 If comment out cthreads from the uses the exception is: An unhandled exception occurred at $7F21B71F5147: EAccessViolation: $7F21B71F5147 $7F21B71F751B $7F21B71F769C $7F21B746BFFF If run with gdb (and cthreads): Heap dump by heaptrc unit 355 memory blocks allocated : 948252/948432 355 memory blocks freed : 948252/948432 0 unfreed memory blocks : 0 True heap size : 131072 True free heap : 131072 [Thread 0x75991700 (LWP 2874) exited] [Thread 0x76192700 (LWP 2873) exited] [Thread 0x77fe3740 (LWP 2869) exited] Cannot find user-level thread for LWP 2875: generic error Any idea how to detect what/where is the source of the exception? I use Linux 64bit, FPC 3.0.4 and Lazarus fixes_1_8. Gabor -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org https://lists.lazarus-ide.org/listinfo/lazarus