[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:09:24 CET 2018


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/1e48ff4c/attachment.html>


More information about the Lazarus mailing list