[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