Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2018-03

How to catch an unhandled exception?

7 messages · 3 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Gabor Boros

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 --------------
A non-text attachment was scrubbed...
Name: FB3API_IBX.tar.gz
Type: application/x-gzip
Size: 1617 bytes
Desc: not available
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20180309/bac08696/attachment.bin>

Reply by email

Tony Whyman
to Gabor Boros

Gabor,

I can't duplicate your problem which probably implies that we are looking at some weird race condition during the program tidy up phase. I did see occasionally something like this before with Lazarus 1.6.4 on Windows with heaptrc - but I never saw it without heaptrc and it cleared up with Lazarus 1.8 and hence  I never bothered to pursue it assuming that it was a Lazarus bug that got fixed.

You are seeing this problem not so much with IBX, but with the Firebird Pascal API. Your example program has excluded the IBX part and focused purely on the API.

What might be an issue here is that the FirebirdAPI is accessed via a COM interface and the IFirebirdAPI interface is not explicitly released. The software just relies upon the system to clean it up at the end. There may be a race condition here between the clear up of the interface and the dynamic library manager. This is because when the interface is released, it then unloads the Firebird DLL/SO. Try adding a finalization clause to IB.pas setting "FFirebirdAPI := nil" and see if that clears it up - or whether the exception occurs before this point.

It is not obvious if there is a real issue with cthreads. The library should only create multiple threads when handling asynchronous Firebird events and your program is not using this capability.

Otherwise, yes, it would be really useful to be able to find where this exception is being raised.

Tony Whyman

MWA

Gabor Boros wrote 77 lines
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/b1dbc57e/attachment.html>

Reply by email

Giuliano Colla
to Gabor Boros: The result of the attached example (which use MWA's Firebird Pascal API) for me is an…

Il 09/03/2018 10:14, Gabor Boros via Lazarus ha scritto:

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.

To obtain meaningful information from gdb I do the following:
1) Compile both Lazarus LCL and fpc with debug info
2) Install the glibc-debuginfo packages
Otherwise you get only the information about exceptions which generate directly from your source code, which is many cases isn't sufficient.

Hope that it helps,

Giuliano

Reply by email

Tony Whyman
to Giuliano Colla

Giulian,

You may in a roundabout way have pointed me at where the problem lies. I always work with fpc debug libraries as well and I can't catch the problem. I changed to the standard release and the bug appears! Unfortunately, while duplicating the problem is one thing, tracking it down when your main debugging tool is unavailable is another...

Tony Whyman

MWA

Giuliano Colla wrote 15 lines
Il 09/03/2018 10:14, Gabor Boros via Lazarus ha scritto: > 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. To obtain meaningful information from gdb I do the following: 1) Compile both Lazarus LCL and fpc with debug info 2) Install the glibc-debuginfo packages Otherwise you get only the information about exceptions which generate directly from your source code, which is many cases isn't sufficient. Hope that it helps, Giuliano

Reply by email

Tony Whyman
to Gabor Boros: The result of the attached example (which use MWA's Firebird Pascal API) for me is an…

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.

Gabor Boros wrote 77 lines
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>

Reply by email

Tony Whyman
to Tony Whyman

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.

Tony Whyman wrote 165 lines
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>

Reply by email

Gabor Boros
to Tony Whyman: Thanks to Giuliano mentioning debug libraries I have been able to duplicate the problem…

2018. 03. 09. 12:09 keltezéssel, Tony Whyman via Lazarus írta:

Show quoted text 18 lines
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

Reply by email