[Lazarus] How to catch an unhandled exception? [FIXED - but there is an FPC bug here]

Tony Whyman tony.whyman at mccallumwhyman.com
Fri Mar 9 12:29:11 CET 2018


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 $00007FF97F0A3147:
>> EAccessViolation:
>>   $00007FF97F0A3147
>>
>>
>> If comment out cthreads from the uses the exception is:
>>
>>
>> An unhandled exception occurred at $00007F21B71F5147:
>> EAccessViolation:
>>   $00007F21B71F5147
>>   $00007F21B71F751B
>>   $00007F21B71F769C
>>   $00007F21B746BFFF
>>
>>
>> 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 0x7ffff5991700 (LWP 2874) exited]
>> [Thread 0x7ffff6192700 (LWP 2873) exited]
>> [Thread 0x7ffff7fe3740 (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
>>
>>
>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180309/bf7e1017/attachment.html>


More information about the Lazarus mailing list