View Issue Details

IDProjectCategoryView StatusLast Update
0012528FPCRTLpublic2012-11-04 21:41
ReporterericiskoAssigned ToFlorian 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product Version2.2.2Product Build 
Target VersionFixed in Version3.0.0 
Summary0012528: TFPList exception with no excpetion stack printed
DescriptionRunning simple program (see attached file) produces exception without traceback which is not very useful.

Exception produced:

An unhandled exception occurred at $0040CA7F :
EListError : List index (0) out of bounds
  $0040CA7F TFPLIST__RAISEINDEXERROR, line 24 of C:/temp/lazbuild/fpc-patched/
rtl/objpas/classes/lists.inc

I would expect the whole exception stack to be printed.
Additional InformationLooking at the code, it seems the issue is in TFPList.Error that calls raise with 'at get_caller_addr(get_frame)'. This will cause that AFrame parameter to fpc_raiseexception is nil. Therefore, backtrace stack will be empty.


Modifying procedure p3() in the attached file produces the following results:

-----------------------------------
procedure p3();
begin
  raise Exception.Create('test');
end;

An unhandled exception occurred at $004014AE :
Exception : test
  $004014AE P1, line 14 of project2.pas
  $00401508 P2, line 22 of project2.pas
  $00401518 P3, line 27 of project2.pas
  $0040152D main, line 31 of project2.pas


-----------------------------------
procedure p3();
begin
  raise Exception.Create('test') at get_caller_addr(get_frame);
end;

An unhandled exception occurred at $00401508 :
Exception : test
  $00401508 P2, line 22 of project2.pas

This is the same scenario as with TFPList.Error().


-----------------------------------
procedure p3();
begin
  raise Exception.Create('test') at get_caller_addr(get_frame), get_caller_frame(get_frame);
end;

An unhandled exception occurred at $00401518 :
Exception : test
  $00401518 P2, line 22 of project2.pas
  $00401528 P3, line 27 of project2.pas
  $0040153D main, line 31 of project2.pas

This produces the correct stack (the last procedure called (p1) is removed but the stack after that is printed).
TagsNo tags attached.
Fixed in Revision22935
FPCOldBugId
FPCTarget
Attached Files
  • project2.pas (386 bytes)
    program project2;
    
    {$mode objfpc}{$H+}
    
    uses
      Classes, SysUtils
      { you can add units after this };
      
      procedure p1();
      var
        list: TFPList;
        i: integer;
      begin
        list := TFPList.Create;
        for i:=0 to list.Count do
          list[i];
      end;
    
      procedure p2();
      begin
        p1;
      end;
    
      procedure p3();
      begin
        p2;
      end;
    
    begin
      p3;
    end.
    
    
    project2.pas (386 bytes)
  • lists_inc.patch (436 bytes)
    --- lists.inc_orig	2008-10-30 19:20:54.466615252 -0400
    +++ lists.inc	2008-10-30 19:32:31.453614702 -0400
    @@ -132,7 +132,7 @@
     
     class procedure TFPList.Error(const Msg: string; Data: PtrInt);
     begin
    -  Raise EListError.CreateFmt(Msg,[Data]) at get_caller_addr(get_frame);
    +  Raise EListError.CreateFmt(Msg,[Data]) at get_caller_addr(get_frame), get_caller_frame(get_frame);
     end;
     
     procedure TFPList.Exchange(Index1, Index2: Integer);
    
    lists_inc.patch (436 bytes)

Relationships

related to 0019310 resolvedFlorian "assert", raises exception with wrong code/frame-address 

Activities

2008-10-30 15:39

 

project2.pas (386 bytes)
program project2;

{$mode objfpc}{$H+}

uses
  Classes, SysUtils
  { you can add units after this };
  
  procedure p1();
  var
    list: TFPList;
    i: integer;
  begin
    list := TFPList.Create;
    for i:=0 to list.Count do
      list[i];
  end;

  procedure p2();
  begin
    p1;
  end;

  procedure p3();
  begin
    p2;
  end;

begin
  p3;
end.

project2.pas (386 bytes)

Florian

2008-10-30 15:58

administrator   ~0023043

Due to optimization, the whole stack is not always available. If you depend on this information, recompile everything (including rtl etc.) without optimization.

ericisko

2008-10-30 16:25

reporter   ~0023044

I don't think this is due to optimizations. The same RTL WILL produce traceback if you call:

raise Exception.Create('test') at get_caller_addr(get_frame),get_caller_frame(get_frame);

(see get_caller_frame(get_frame) at the end of raise)

ericisko

2008-10-31 00:39

reporter   ~0023051

Recompiled RTL with attached patch (lists_inc.patch).

Running the same program (project2.pas) now produces the following backtrace:

An unhandled exception occurred at $0806A64F :
EListError : List index (0) out of bounds
  $0806A64F TFPLIST__RAISEINDEXERROR, line 26 of /var/lib/vmware/VirtualMachines/portage/dev-lang/fpc-2.2.2/work/fpcbuild-2.2.2/fpcsrc/rtl/objpas/classes/lists.inc
  $0806A690 TFPLIST__GET, line 32 of /var/lib/vmware/VirtualMachines/portage/dev-lang/fpc-2.2.2/work/fpcbuild-2.2.2/fpcsrc/rtl/objpas/classes/lists.inc
  $080480DE P1, line 16 of project2.pas
  $080480F8 P2, line 22 of project2.pas
  $08048108 P3, line 26 of project2.pas
  $0804811D main, line 29 of project2.pas

2008-10-31 00:39

 

lists_inc.patch (436 bytes)
--- lists.inc_orig	2008-10-30 19:20:54.466615252 -0400
+++ lists.inc	2008-10-30 19:32:31.453614702 -0400
@@ -132,7 +132,7 @@
 
 class procedure TFPList.Error(const Msg: string; Data: PtrInt);
 begin
-  Raise EListError.CreateFmt(Msg,[Data]) at get_caller_addr(get_frame);
+  Raise EListError.CreateFmt(Msg,[Data]) at get_caller_addr(get_frame), get_caller_frame(get_frame);
 end;
 
 procedure TFPList.Exchange(Index1, Index2: Integer);
lists_inc.patch (436 bytes)

Marco van de Voort

2008-12-27 23:14

manager   ~0024010

I suspect there is something to it: I tried to duplicate by defining

procedure p5();
begin
  raise Exception.Create('test') at get_caller_addr(get_frame);
end;

and calling that as first line in p1. I compiled using -gl -O- and added {$stackframe on}. I also tried with the raise xx at x1,x2 syntax, and I wasn't able to get a full traceback using recent trunk.

Bernd Kreuss

2011-07-05 01:03

reporter   ~0049679

Last edited: 2011-07-05 22:18

with current 2.5.1 SVN from today (rev 17935)

the following will produce a proper stacktrace:

  raise Exception.Create('foo') at get_caller_addr(get_frame), get_caller_frame(get_frame);

and the following will not:

  raise Exception.Create('foo') at get_caller_addr(get_frame);

is this a bug in FPC or is this a bug in all the RTL files using the "raise ... at" the wrong way? I had the very same problem causing me quite some confusion with a TStringList today.

I ask because if it really is a bug in the RTL due to wrong usage of raise (and not wrong behavior of raise itself) then it would be trivial to fix and I would happily spend some time this week grepping through the entire RTL and prepare a patch to replace each and every occurrence.

Florian

2012-11-04 21:41

administrator   ~0063669

Fixed the mentioned issue as well as other places in the rtl/packages. However, to get a proper stack trace, recompiling the rtl with -O- is required.

Issue History

Date Modified Username Field Change
2008-10-30 15:39 ericisko New Issue
2008-10-30 15:39 ericisko File Added: project2.pas
2008-10-30 15:58 Florian Status new => resolved
2008-10-30 15:58 Florian Resolution open => no change required
2008-10-30 15:58 Florian Assigned To => Florian
2008-10-30 15:58 Florian Note Added: 0023043
2008-10-30 16:25 ericisko Status resolved => feedback
2008-10-30 16:25 ericisko Resolution no change required => reopened
2008-10-30 16:25 ericisko Note Added: 0023044
2008-10-31 00:39 ericisko Note Added: 0023051
2008-10-31 00:39 ericisko File Added: lists_inc.patch
2008-12-27 23:14 Marco van de Voort Note Added: 0024010
2008-12-27 23:15 Marco van de Voort Status feedback => assigned
2011-05-15 17:03 Florian Relationship added related to 0019310
2011-07-05 01:03 Bernd Kreuss Note Added: 0049679
2011-07-05 01:04 Bernd Kreuss Note Edited: 0049679
2011-07-05 22:18 Bernd Kreuss Note Edited: 0049679
2012-11-04 21:41 Florian Fixed in Revision => 22935
2012-11-04 21:41 Florian Status assigned => resolved
2012-11-04 21:41 Florian Fixed in Version => 2.7.1
2012-11-04 21:41 Florian Resolution reopened => fixed
2012-11-04 21:41 Florian Note Added: 0063669