View Issue Details

IDProjectCategoryView StatusLast Update
0034881FPCCompilerpublic2019-11-09 05:17
ReporterMartin FriebeAssigned ToSven Barth 
PrioritynormalSeverityminorReproducibilityalways
Status feedbackResolutionopen 
Platformwin32 / 64 / any SEHOSwinOS Version-
Product Version3.2.0Product Build 
Target VersionFixed in Version 
Summary0034881: Request debug info for SEH (finally/except) to prevent regression when win32 switches to SEH
DescriptionThis issue is about:
- current Win64 SEH debug info. (to enable fixing some features of the debugger)
- upcoming Win32 SEH debug info. (to prevent regressions to the debugger)
- any other future changes to exception handling on any platform.

The debugger (in the Lazarus IDE) has several features regarding exception handling:

1) Single step over an ignored exception:
- Either steps normally to the next line (if except handler is inside the stepped-over code)
- Or steps to the except (or finally) handler. Similar to "step out", regarding the except handler as the next statement to which the current function returns.

2) If stopped at an exception (stopped at raise / fpc_raiseexception), then step-over/out will go to the next except/finally handler.

3) deal with fpc_reraise during stepping in the same manner as 1 (step to next handler).

----------

For this the debugger needs to be able to set a breakpoint that will stop when *any* except or finally handler is entered.
Without SEH this can be done by intercepting fpc_popaddrstack. (and then step out once)

With SEH this is not called.

On Win64 the debugger can get the address of the next "except" (but not "finally") handler by intercepting calls to the kernels RtlUnwindEx.
Fpc code passes the except handler address as argument, so the debugger can set a breakpoint on the correct except handler(s).

However an Win64 for a "finally" handler the OS calls __FPC_specific_handler.
And somewhere within it, this function will call the finally handler. The debugger has no way, where in that function the call to "finally" is made. It has therefore no way to intercept it. (It would need to set a breakpoint in the middle of __FPC_specific_handler, but there is no debug info to find the line that calls "finally")


In the Win32 SEH branch, there is even less information.

I did some testing with SEH, and IIRC (but not sure its a while ago) I could not catch except nor finally.
There are 2 Handlers that are being called:
 __FPC_default_handler
 __FPC_finally_handler
Both call the except/finally handler directly. (So again would need a breakpoint in the middle of it)


Any idea how to add/use debug info, so a debugger can deal with the above?
For anything GDB can not handle on its own, the IDE must be able to extract this info with the help of GDB and then set breakpoints to deal with it.

----------

Furthermore entering a finally handler (without an exception) is now a call to a function.

Stepping with F8 will step-over it (tested with GDB).

It needs to be explored if information can be added, to prevent this.
Also if there is no such info for GDB/LLDB, it should still be explored how this information can be embedded for the upcoming FpDebug (worst case is to guess from the function name)
TagsNo tags attached.
Fixed in Revision
FPCOldBugId0
FPCTarget-
Attached Files
  • dwarf-except-debuginfo.patch (32,105 bytes)
    diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas
    index 7d662323..2c816211 100644
    --- a/compiler/aasmtai.pas
    +++ b/compiler/aasmtai.pas
    @@ -351,8 +351,12 @@ interface
           TAsmMarker = (
             mark_NoPropInfoStart,mark_NoPropInfoEnd,
             mark_AsmBlockStart,mark_AsmBlockEnd,
    -        mark_NoLineInfoStart,mark_NoLineInfoEnd,mark_BlockStart,
    -        mark_Position
    +        mark_NoLineInfoStart,mark_NoLineInfoEnd,
    +        mark_TryBlockStart,mark_TryBlockEnd,
    +        mark_TryFinallyStart,mark_TryFinallyEnd,
    +        mark_TryExceptStart,mark_TryExceptEnd,
    +        mark_Raise,
    +        mark_BlockStart,mark_Position
           );
     
           TRegAllocType = (ra_alloc,ra_dealloc,ra_sync,ra_resize,ra_markused);
    @@ -789,9 +793,16 @@ interface
            { Insert a marker for assembler and inline blocks }
            tai_marker = class(tai)
               Kind: TAsmMarker;
    +          AsmLbl : TAsmSymbol;
    +          ExceptVar : tsymstr;
    +          ExceptDef : tdef;
    +          ExceptDefDeref : tderef;
               Constructor Create(_Kind: TAsmMarker);
    +          constructor Create(_kind:tasmmarker;_asmlbl:tasmsymbol);
               constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
               procedure ppuwrite(ppufile:tcompilerppufile);override;
    +          procedure derefimpl; override;
    +          procedure buildderefimpl; override;
            end;
     
            tai_tempalloc = class(tai)
    @@ -2545,7 +2556,7 @@ implementation
                                  Tai_Marker
      ****************************************************************************}
     
    -    constructor Tai_Marker.Create(_Kind: TAsmMarker);
    +    constructor tai_marker.Create(_Kind: TAsmMarker);
           begin
             Inherited Create;
             typ := ait_marker;
    @@ -2553,17 +2564,54 @@ implementation
           end;
     
     
    -    constructor Tai_Marker.ppuload(t:taitype;ppufile:tcompilerppufile);
    +    constructor tai_marker.Create(_kind: tasmmarker; _asmlbl: tasmsymbol);
    +      begin
    +        Inherited Create;
    +        typ:=ait_marker;
    +        Kind:=_kind;
    +        AsmLbl:=_asmlbl;
    +      end;
    +
    +
    +    constructor tai_marker.ppuload(t: taitype; ppufile: tcompilerppufile);
           begin
             inherited ppuload(t,ppufile);
             kind:=TAsmMarker(ppufile.getbyte);
    +        AsmLbl:=ppufile.getasmsymbol;
    +        ppufile.getderef(ExceptDefDeref);
    +{$ifdef symansistr}
    +        ExceptVar:=ppufile.getansistring
    +{$else symansistr}
    +        ExceptVar:=ppufile.getstring;
    +{$endif symansistr}
           end;
     
     
    -    procedure Tai_Marker.ppuwrite(ppufile:tcompilerppufile);
    +    procedure tai_marker.ppuwrite(ppufile: tcompilerppufile);
           begin
             inherited ppuwrite(ppufile);
             ppufile.putbyte(byte(kind));
    +        ppufile.putasmsymbol(AsmLbl);
    +        ppufile.putderef(ExceptDefDeref);
    +{$ifdef symansistr}
    +        ppufile.putansistring(ExceptVar);
    +{$else symansistr}
    +        ppufile.putstring(ExceptVar);
    +{$endif symansistr}
    +      end;
    +
    +
    +    procedure tai_marker.derefimpl;
    +      begin
    +        ExceptDef:=tdef(ExceptDefDeref.resolve);
    +        inherited derefimpl;
    +      end;
    +
    +
    +    procedure tai_marker.buildderefimpl;
    +      begin
    +        ExceptDefDeref.build(ExceptDef);
    +        inherited buildderefimpl;
           end;
     
     
    diff --git a/compiler/dbgdwarf.pas b/compiler/dbgdwarf.pas
    index 4bc522dd..0c0668ba 100644
    --- a/compiler/dbgdwarf.pas
    +++ b/compiler/dbgdwarf.pas
    @@ -2277,6 +2277,26 @@ implementation
               end
             end;
     
    +      type
    +        tblockkind = (bk_try, bk_finally, bk_except);
    +
    +        texceptinfo = record
    +          exceptvar : TSymStr;
    +          exceptdef : tdef;
    +          exceptstart : tasmsymbol;
    +          exceptend : tasmsymbol;
    +        end;
    +
    +        ttrycatchblock = record
    +          kind : tblockkind;
    +          trystart,
    +          tryend: tasmsymbol;
    +          finallystart,
    +          finallyend: tasmsymbol;
    +          excepts : array of texceptinfo;
    +        end;
    +        ptrycatchblock = ^ttrycatchblock;
    +
           var
             procendlabel   : tasmlabel;
             procentry,s    : string;
    @@ -2284,6 +2304,11 @@ implementation
             st             : tsymtable;
             vmtoffset      : pint;
             in_currentunit : boolean;
    +        ai : tai;
    +        trycatchblocks_wip,
    +        trycatchblocks_done : tfplist;
    +        trycatchblock : ptrycatchblock;
    +        i,j : sizeint;
           begin
             { only write debug info for procedures defined in the current module,
               except in case of methods (gcc-compatible)
    @@ -2438,6 +2463,8 @@ implementation
             }
             finish_entry;
     
    +        current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('ParaSyms')));
    +
             if assigned(def.parast) then
               begin
                 { First insert self, because gdb uses the fact whether or not the
    @@ -2452,14 +2479,17 @@ implementation
               end;
             { local type defs and vars should not be written
               inside the main proc }
    +          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('LocalSyms')));
             if in_currentunit and
                assigned(def.localst) and
                (def.localst.symtabletype=localsymtable) then
               write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],def.localst);
     
    +          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('ParaDefs')));
             { last write the types from this procdef }
             if assigned(def.parast) then
               write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.parast);
    +          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('LocalDefs')));
             { only try to write the localst if the routine is implemented here }
             if in_currentunit and
                assigned(def.localst) and
    @@ -2472,6 +2502,187 @@ implementation
                 // write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],def.localst);
               end;
     
    +        { we don't know how the C++ compatible exception blocks are done, so we
    +          only generate this for Pascal DWARF }
    +        if in_currentunit and not (ds_dwarf_cpp in current_settings.debugswitches) then
    +          begin
    +            trycatchblocks_wip:=tfplist.create;
    +            trycatchblocks_done:=tfplist.create;
    +            ai:=def.procstarttai;
    +            while assigned(ai) and (ai<>def.procendtai) do
    +              begin
    +                if ai.typ=ait_marker then
    +                  begin
    +                    case tai_marker(ai).Kind of
    +                      mark_TryBlockStart:
    +                        begin
    +                          if trycatchblocks_wip.count>0 then
    +                            begin
    +                              { if we have an except block with filled endlabels
    +                                then we can finish that block }
    +                              trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                              if (trycatchblock^.kind=bk_try) and assigned(trycatchblock^.tryend) then
    +                                internalerror(2019102205)
    +                              else if (trycatchblock^.kind=bk_finally) and assigned(trycatchblock^.finallyend) then
    +                                internalerror(2019102206)
    +                              else if trycatchblock^.kind=bk_except then
    +                                begin
    +                                  if not assigned(trycatchblock^.excepts) then
    +                                    internalerror(2019102207);
    +                                  if assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
    +                                    begin
    +                                      trycatchblocks_wip.extract(trycatchblock);
    +                                      trycatchblocks_done.add(trycatchblock);
    +                                    end;
    +                                end;
    +                            end;
    +                          new(trycatchblock);
    +                          trycatchblock^.kind:=bk_try;
    +                          trycatchblock^.trystart:=tai_marker(ai).AsmLbl;
    +                          trycatchblock^.tryend:=nil;
    +                          trycatchblock^.finallystart:=nil;
    +                          trycatchblock^.finallyend:=nil;
    +                          trycatchblocks_wip.Add(trycatchblock);
    +                        end;
    +                      mark_TryBlockEnd:
    +                        begin
    +                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_try) then
    +                            internalerror(2019102101);
    +                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                          trycatchblock^.tryend:=tai_marker(ai).AsmLbl;
    +                        end;
    +                      mark_TryFinallyStart:
    +                        begin
    +                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_try) then
    +                            internalerror(2019102202);
    +                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                          trycatchblock^.kind:=bk_finally;
    +                          trycatchblock^.finallystart:=tai_marker(ai).AsmLbl;
    +                        end;
    +                      mark_TryFinallyEnd:
    +                        begin
    +                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_finally) then
    +                            internalerror(2019102203);
    +                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                          trycatchblock^.finallyend:=tai_marker(ai).AsmLbl;
    +                          { we can't have any other block once we got a finally,
    +                            so the whole thing is finished }
    +                          trycatchblocks_wip.extract(trycatchblock);
    +                          trycatchblocks_done.add(trycatchblock);
    +                        end;
    +                      mark_TryExceptStart:
    +                        begin
    +                          if (trycatchblocks_wip.count=0) or not (ptrycatchblock(trycatchblocks_wip.last)^.kind in [bk_try,bk_except]) then
    +                            internalerror(2019102204);
    +                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                          trycatchblock^.kind:=bk_except;
    +                          if assigned(trycatchblock^.excepts) and not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
    +                            internalerror(2019102208);
    +                          setlength(trycatchblock^.excepts,Length(trycatchblock^.excepts)+1);
    +                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptstart:=tai_marker(ai).AsmLbl;
    +                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptvar:=tai_marker(ai).ExceptVar;
    +                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptdef:=tai_marker(ai).ExceptDef;
    +                        end;
    +                      mark_TryExceptEnd:
    +                        begin
    +                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_except) then
    +                            internalerror(2019102209);
    +                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                          if not assigned(trycatchblock^.excepts) or assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
    +                            internalerror(2019102210);
    +                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend:=tai_marker(ai).AsmLbl;
    +                        end;
    +                      else
    +                        { we ignore all other marks }
    +                        ;
    +                    end;
    +                  end;
    +                ai:=tai(ai.next);
    +              end;
    +
    +            while trycatchblocks_wip.count>0 do
    +              begin
    +                { the WIP list should only contain except blocks now }
    +                trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                if trycatchblock^.kind in [bk_try,bk_finally] then
    +                  internalerror(2019102211);
    +                if not assigned(trycatchblock^.excepts) or
    +                    not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptstart) or
    +                    not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
    +                  internalerror(2019102212);
    +                trycatchblocks_wip.extract(trycatchblock);
    +                trycatchblocks_done.add(trycatchblock);
    +              end;
    +
    +            trycatchblocks_wip.free;
    +
    +            for i:=0 to trycatchblocks_done.count-1 do
    +              begin
    +                trycatchblock:=ptrycatchblock(trycatchblocks_done[i]);
    +
    +                { the try block }
    +
    +                if trycatchblock^.kind=bk_finally then
    +                  current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Try Finally Block')))
    +                else
    +                  current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Try Except Block')));
    +
    +                append_entry(DW_TAG_try_block,false,[]);
    +
    +                append_labelentry(DW_AT_low_pc,trycatchblock^.trystart);
    +                append_labelentry(DW_AT_high_pc,trycatchblock^.tryend);
    +
    +                finish_entry;
    +
    +                case trycatchblock^.kind of
    +                  bk_try:
    +                    internalerror(2019102213);
    +                  bk_finally:
    +                    begin
    +                      { DWARF does not specifically specify a finally block,
    +                        so we use a catch block without any parameter... }
    +                      append_entry(DW_TAG_catch_block,false,[]);
    +
    +                      append_labelentry(DW_AT_low_pc,trycatchblock^.finallystart);
    +                      append_labelentry(DW_AT_high_pc,trycatchblock^.finallyend);
    +
    +                      finish_entry;
    +                    end;
    +                  bk_except:
    +                    begin
    +                      for j:=0 to high(trycatchblock^.excepts) do
    +                        begin
    +                          append_entry(DW_TAG_catch_block,true,[]);
    +
    +                          append_labelentry(DW_AT_low_pc,trycatchblock^.excepts[j].exceptstart);
    +                          append_labelentry(DW_AT_high_pc,trycatchblock^.excepts[j].exceptend);
    +
    +                          finish_entry;
    +
    +                          if assigned(trycatchblock^.excepts[j].exceptdef) then
    +                            begin
    +                              append_entry(DW_TAG_formal_parameter,false,[
    +                                DW_AT_name,DW_FORM_string,trycatchblock^.excepts[j].exceptvar+#0
    +                              ]);
    +                              append_labelentry_ref(DW_AT_type,def_dwarf_lab(trycatchblock^.excepts[j].exceptdef));
    +                              finish_entry;
    +                            end
    +                          else
    +                            begin
    +                              append_entry(DW_TAG_unspecified_parameters,false,[]);
    +                              finish_entry;
    +                            end;
    +
    +                          finish_children;
    +                        end;
    +                    end;
    +                end;
    +
    +                dispose(trycatchblock);
    +              end;
    +            trycatchblocks_done.free;
    +          end;
    +
             finish_children;
           end;
     
    diff --git a/compiler/i386/n386flw.pas b/compiler/i386/n386flw.pas
    index ab3c1921..69a75ba2 100644
    --- a/compiler/i386/n386flw.pas
    +++ b/compiler/i386/n386flw.pas
    @@ -272,6 +272,7 @@ procedure emit_scope_end;
     
     procedure ti386tryfinallynode.pass_generate_code;
       var
    +    marklabel,
         finallylabel,
         exceptlabel,
         safecalllabel,
    @@ -352,6 +353,10 @@ procedure ti386tryfinallynode.pass_generate_code;
             current_asmdata.RefAsmSymbol(finalizepi.procdef.mangledname,AT_FUNCTION)
           );
     
    +    current_asmdata.getlabel(marklabel,alt_addr);
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
    +    cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
         { try code }
         if assigned(left) then
           begin
    @@ -361,6 +366,10 @@ procedure ti386tryfinallynode.pass_generate_code;
               exit;
           end;
     
    +    current_asmdata.getlabel(marklabel,alt_addr);
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
    +    cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
         { don't generate line info for internal cleanup }
         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
     
    @@ -391,6 +400,9 @@ procedure ti386tryfinallynode.pass_generate_code;
         { right is a call to finalizer procedure }
         secondpass(right);
     
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,finallylabel));
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,endfinallylabel));
    +
         { goto is allowed if it stays inside the finally block,
           this is checked using the exception block number }
         if (flowcontrol-[fc_gotolabel])<>[fc_inflowcontrol] then
    @@ -445,6 +457,7 @@ procedure ti386tryfinallynode.pass_generate_code;
     
     procedure ti386tryexceptnode.pass_generate_code;
       var
    +    marklabel,
         exceptlabel,oldendexceptlabel,
         lastonlabel,
         exitexceptlabel,
    @@ -463,6 +476,7 @@ procedure ti386tryexceptnode.pass_generate_code;
         hnode : tnode;
         hlist : tasmlist;
         onnodecount : tai_const;
    +    marker : tai_marker;
       label
         errorexit;
       begin
    @@ -536,11 +550,19 @@ procedure ti386tryexceptnode.pass_generate_code;
             current_procinfo.CurrBreakLabel:=breaktrylabel;
           end;
     
    +    current_asmdata.getlabel(marklabel,alt_addr);
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
    +    cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
         secondpass(left);
         tryflowcontrol:=flowcontrol;
         if codegenerror then
           goto errorexit;
     
    +    current_asmdata.getlabel(marklabel,alt_addr);
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
    +    cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
         emit_scope_end;
         { jump over except handlers }
         cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
    @@ -596,7 +618,21 @@ procedure ti386tryexceptnode.pass_generate_code;
                 hlist.concat(tai_const.create_sym(current_asmdata.RefAsmSymbol(tonnode(hnode).excepttype.vmt_mangledname,AT_DATA)));
                 hlist.concat(tai_const.create_sym(onlabel));
                 cg.a_label(current_asmdata.CurrAsmList,onlabel);
    +
    +            marker:=tai_marker.create(mark_TryExceptStart,onlabel);
    +            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
    +            marker.ExceptDef:=tonnode(hnode).excepttype;
    +            current_asmdata.CurrAsmList.concat(marker);
    +
                 secondpass(hnode);
    +
    +            current_asmdata.getlabel(marklabel,alt_addr);
    +            marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
    +            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
    +            marker.ExceptDef:=tonnode(hnode).excepttype;
    +            current_asmdata.CurrAsmList.concat(marker);
    +            cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
                 inc(onnodecount.value);
                 hnode:=tonnode(hnode).left;
               end;
    @@ -617,7 +653,16 @@ procedure ti386tryexceptnode.pass_generate_code;
           begin
             { here we don't have to reset flowcontrol           }
             { the default and on flowcontrols are handled equal }
    +        current_asmdata.getlabel(marklabel,alt_addr);
    +        current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptStart,marklabel));
    +        cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
             secondpass(t1);
    +
    +        current_asmdata.getlabel(marklabel,alt_addr);
    +        current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptEnd,marklabel));
    +        cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
             cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
             if (flowcontrol*[fc_exit,fc_break,fc_continue]<>[]) then
               cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
    diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas
    index a16abcae..9e2d1cb9 100644
    --- a/compiler/ncgflw.pas
    +++ b/compiler/ncgflw.pas
    @@ -545,6 +545,7 @@ implementation
         procedure tcgtryexceptnode.pass_generate_code;
     
           var
    +         marklabel,
              oldendexceptlabel,
              lastonlabel,
              exitexceptlabel,
    @@ -609,10 +610,18 @@ implementation
                 current_procinfo.CurrBreakLabel:=breaktrylabel;
               end;
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              secondpass(left);
              if codegenerror then
                goto errorexit;
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              { don't generate line info for internal cleanup }
              current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
     
    @@ -675,8 +684,16 @@ implementation
                      { except block needs line info }
                      current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
     
    +                 current_asmdata.getlabel(marklabel,alt_addr);
    +                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptStart,marklabel));
    +                 hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
                      secondpass(t1);
     
    +                 current_asmdata.getlabel(marklabel,alt_addr);
    +                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptEnd,marklabel));
    +                 hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
                      cexceptionstatehandler.handle_nested_exception(current_asmdata.CurrAsmList,destroytemps,doobjectdestroyandreraisestate);
     
                      cexceptionstatehandler.unget_exception_temps(current_asmdata.CurrAsmList,destroytemps);
    @@ -741,6 +758,7 @@ implementation
     
         procedure tcgonnode.pass_generate_code;
           var
    +         marklabel,
              nextonlabel,
              exitonlabel,
              continueonlabel,
    @@ -753,6 +771,7 @@ implementation
              exceptvarsym : tlocalvarsym;
              exceptlocdef: tdef;
              exceptlocreg: tregister;
    +         marker : tai_marker;
           begin
              location_reset(location,LOC_VOID,OS_NO);
              oldCurrExitLabel:=nil;
    @@ -799,7 +818,21 @@ implementation
                      current_procinfo.CurrBreakLabel:=breakonlabel;
                    end;
     
    +              current_asmdata.getlabel(marklabel,alt_addr);
    +              marker:=tai_marker.create(mark_TryExceptStart,marklabel);
    +              marker.ExceptVar:=exceptvar.name;
    +              marker.ExceptDef:=excepttype;
    +              current_asmdata.CurrAsmList.concat(marker);
    +              hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
                   secondpass(right);
    +
    +              current_asmdata.getlabel(marklabel,alt_addr);
    +              marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
    +              marker.ExceptVar:=exceptvar.name;
    +              marker.ExceptDef:=excepttype;
    +              current_asmdata.CurrAsmList.concat(marker);
    +              hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
                end;
     
              cexceptionstatehandler.handle_nested_exception(current_asmdata.CurrAsmList,excepttemps,doobjectdestroyandreraisestate);
    @@ -906,6 +939,7 @@ implementation
     
         procedure tcgtryfinallynode.pass_generate_code;
           var
    +         marklabel,
              endfinallylabel,
              exitfinallylabel,
              continuefinallylabel,
    @@ -976,6 +1010,10 @@ implementation
                 current_procinfo.CurrBreakLabel:=breakfinallylabel;
               end;
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              { try code }
              if assigned(left) then
                begin
    @@ -984,6 +1022,10 @@ implementation
                     exit;
                end;
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              { don't generate line info for internal cleanup }
              current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
     
    @@ -1022,6 +1064,10 @@ implementation
              { end cleanup }
              current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              { finally code (don't unconditionally set fc_inflowcontrol, since the
                finally code is unconditionally executed; we do have to filter out
                flags regarding break/contrinue/etc. because we have to give an
    @@ -1035,6 +1081,10 @@ implementation
              if codegenerror then
                exit;
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              { don't generate line info for internal cleanup }
              current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
     
    diff --git a/compiler/nflw.pas b/compiler/nflw.pas
    index 2d85b997..5a01c086 100644
    --- a/compiler/nflw.pas
    +++ b/compiler/nflw.pas
    @@ -254,6 +254,7 @@ interface
               function pass_1 : tnode;override;
               function dogetcopy : tnode;override;
               function docompare(p: tnode): boolean; override;
    +          function exceptvar:tsym;
            end;
            tonnodeclass = class of tonnode;
     
    @@ -2600,4 +2601,12 @@ implementation
             docompare := false;
           end;
     
    +
    +    function tonnode.exceptvar:tsym;
    +      begin
    +        if exceptsymtable.symlist.count<>1 then
    +          internalerror(2019102401);
    +        result:=tsym(exceptsymtable.symlist[0]);
    +      end;
    +
     end.
    diff --git a/compiler/x86_64/nx64flw.pas b/compiler/x86_64/nx64flw.pas
    index b391d359..f889e3f0 100644
    --- a/compiler/x86_64/nx64flw.pas
    +++ b/compiler/x86_64/nx64flw.pas
    @@ -276,6 +276,7 @@ procedure tx64tryfinallynode.pass_generate_code;
     
         emit_nop;
         cg.a_label(current_asmdata.CurrAsmList,trylabel);
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,trylabel));
     
         { try code }
         if assigned(left) then
    @@ -321,6 +322,10 @@ procedure tx64tryfinallynode.pass_generate_code;
             cg.a_label(current_asmdata.CurrAsmList,endtrylabel);
           end;
     
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,endtrylabel));
    +
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,finallylabel));
    +
         flowcontrol:=[fc_inflowcontrol];
         { generate finally code as a separate procedure }
         if not implicitframe then
    @@ -337,6 +342,8 @@ procedure tx64tryfinallynode.pass_generate_code;
     
         cg.a_label(current_asmdata.CurrAsmList,endfinallylabel);
     
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,endfinallylabel));
    +
         { generate the scope record in .xdata }
         tcpuprocinfo(current_procinfo).add_finally_scope(trylabel,endtrylabel,
           current_asmdata.RefAsmSymbol(finalizepi.procdef.mangledname,AT_FUNCTION),catch_frame);
    @@ -359,6 +366,7 @@ procedure tx64tryexceptnode.pass_generate_code;
         oldCurrExitLabel,
         oldContinueLabel,
         oldBreakLabel : tasmlabel;
    +    marklabel,
         onlabel,
         filterlabel: tasmlabel;
         oldflowcontrol,tryflowcontrol,
    @@ -366,6 +374,7 @@ procedure tx64tryexceptnode.pass_generate_code;
         hnode : tnode;
         hlist : tasmlist;
         onnodecount : tai_const;
    +    marker : tai_marker;
       label
         errorexit;
       begin
    @@ -407,6 +416,7 @@ procedure tx64tryexceptnode.pass_generate_code;
         current_asmdata.getjumplabel(trylabel);
         emit_nop;
         cg.a_label(current_asmdata.CurrAsmList,trylabel);
    +    current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryBlockStart,trylabel));
     
         { control flow in try block needs no special handling,
           just make sure that target labels are outside the scope }
    @@ -421,6 +431,8 @@ procedure tx64tryexceptnode.pass_generate_code;
         { end of scope }
         cg.a_label(current_asmdata.CurrAsmList,exceptlabel);
     
    +    current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryBlockEnd,exceptlabel));
    +
         { set control flow labels for the except block }
         { and the on statements                        }
         current_procinfo.CurrExitLabel:=exitexceptlabel;
    @@ -451,7 +463,17 @@ procedure tx64tryexceptnode.pass_generate_code;
                 hlist.concat(tai_const.create_rva_sym(current_asmdata.RefAsmSymbol(tonnode(hnode).excepttype.vmt_mangledname,AT_DATA)));
                 hlist.concat(tai_const.create_rva_sym(onlabel));
                 cg.a_label(current_asmdata.CurrAsmList,onlabel);
    +            marker:=tai_marker.create(mark_TryExceptStart,onlabel);
    +            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
    +            marker.ExceptDef:=tonnode(hnode).excepttype;
    +            current_asmdata.CurrAsmList.Concat(marker);
                 secondpass(hnode);
    +            current_asmdata.getjumplabel(marklabel);
    +            cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +            marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
    +            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
    +            marker.ExceptDef:=tonnode(hnode).excepttype;
    +            current_asmdata.CurrAsmList.Concat(marker);
                 inc(onnodecount.value);
                 hnode:=tonnode(hnode).left;
               end;
    @@ -472,7 +494,11 @@ procedure tx64tryexceptnode.pass_generate_code;
           begin
             { here we don't have to reset flowcontrol           }
             { the default and on flowcontrols are handled equal }
    +        current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryExceptStart,lastonlabel));
             secondpass(t1);
    +        current_asmdata.getjumplabel(marklabel);
    +        cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +        current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryExceptEnd,marklabel));
             cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
             if (flowcontrol*[fc_exit,fc_break,fc_continue]<>[]) then
               cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
    
  • dwarf-except-debuginfo-2.patch (32,749 bytes)
    diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas
    index 7d662323..2c816211 100644
    --- a/compiler/aasmtai.pas
    +++ b/compiler/aasmtai.pas
    @@ -351,8 +351,12 @@ interface
           TAsmMarker = (
             mark_NoPropInfoStart,mark_NoPropInfoEnd,
             mark_AsmBlockStart,mark_AsmBlockEnd,
    -        mark_NoLineInfoStart,mark_NoLineInfoEnd,mark_BlockStart,
    -        mark_Position
    +        mark_NoLineInfoStart,mark_NoLineInfoEnd,
    +        mark_TryBlockStart,mark_TryBlockEnd,
    +        mark_TryFinallyStart,mark_TryFinallyEnd,
    +        mark_TryExceptStart,mark_TryExceptEnd,
    +        mark_Raise,
    +        mark_BlockStart,mark_Position
           );
     
           TRegAllocType = (ra_alloc,ra_dealloc,ra_sync,ra_resize,ra_markused);
    @@ -789,9 +793,16 @@ interface
            { Insert a marker for assembler and inline blocks }
            tai_marker = class(tai)
               Kind: TAsmMarker;
    +          AsmLbl : TAsmSymbol;
    +          ExceptVar : tsymstr;
    +          ExceptDef : tdef;
    +          ExceptDefDeref : tderef;
               Constructor Create(_Kind: TAsmMarker);
    +          constructor Create(_kind:tasmmarker;_asmlbl:tasmsymbol);
               constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
               procedure ppuwrite(ppufile:tcompilerppufile);override;
    +          procedure derefimpl; override;
    +          procedure buildderefimpl; override;
            end;
     
            tai_tempalloc = class(tai)
    @@ -2545,7 +2556,7 @@ implementation
                                  Tai_Marker
      ****************************************************************************}
     
    -    constructor Tai_Marker.Create(_Kind: TAsmMarker);
    +    constructor tai_marker.Create(_Kind: TAsmMarker);
           begin
             Inherited Create;
             typ := ait_marker;
    @@ -2553,17 +2564,54 @@ implementation
           end;
     
     
    -    constructor Tai_Marker.ppuload(t:taitype;ppufile:tcompilerppufile);
    +    constructor tai_marker.Create(_kind: tasmmarker; _asmlbl: tasmsymbol);
    +      begin
    +        Inherited Create;
    +        typ:=ait_marker;
    +        Kind:=_kind;
    +        AsmLbl:=_asmlbl;
    +      end;
    +
    +
    +    constructor tai_marker.ppuload(t: taitype; ppufile: tcompilerppufile);
           begin
             inherited ppuload(t,ppufile);
             kind:=TAsmMarker(ppufile.getbyte);
    +        AsmLbl:=ppufile.getasmsymbol;
    +        ppufile.getderef(ExceptDefDeref);
    +{$ifdef symansistr}
    +        ExceptVar:=ppufile.getansistring
    +{$else symansistr}
    +        ExceptVar:=ppufile.getstring;
    +{$endif symansistr}
           end;
     
     
    -    procedure Tai_Marker.ppuwrite(ppufile:tcompilerppufile);
    +    procedure tai_marker.ppuwrite(ppufile: tcompilerppufile);
           begin
             inherited ppuwrite(ppufile);
             ppufile.putbyte(byte(kind));
    +        ppufile.putasmsymbol(AsmLbl);
    +        ppufile.putderef(ExceptDefDeref);
    +{$ifdef symansistr}
    +        ppufile.putansistring(ExceptVar);
    +{$else symansistr}
    +        ppufile.putstring(ExceptVar);
    +{$endif symansistr}
    +      end;
    +
    +
    +    procedure tai_marker.derefimpl;
    +      begin
    +        ExceptDef:=tdef(ExceptDefDeref.resolve);
    +        inherited derefimpl;
    +      end;
    +
    +
    +    procedure tai_marker.buildderefimpl;
    +      begin
    +        ExceptDefDeref.build(ExceptDef);
    +        inherited buildderefimpl;
           end;
     
     
    diff --git a/compiler/dbgdwarf.pas b/compiler/dbgdwarf.pas
    index 4bc522dd..512b2009 100644
    --- a/compiler/dbgdwarf.pas
    +++ b/compiler/dbgdwarf.pas
    @@ -2277,6 +2277,57 @@ implementation
               end
             end;
     
    +      type
    +        tblockkind = (bk_try, bk_finally, bk_except);
    +
    +        texceptinfo = record
    +          exceptvar : TSymStr;
    +          exceptdef : tdef;
    +          exceptstart : tasmsymbol;
    +          exceptend : tasmsymbol;
    +        end;
    +
    +        ttrycatchblock = record
    +          kind : tblockkind;
    +          trystart,
    +          tryend: tasmsymbol;
    +          finallystart,
    +          finallyend: tasmsymbol;
    +          excepts : array of texceptinfo;
    +        end;
    +        ptrycatchblock = ^ttrycatchblock;
    +
    +      var
    +        trycatchblocks_wip,
    +        trycatchblocks_done : tfplist;
    +
    +
    +      procedure maybe_finish_tryexcept;
    +        var
    +          trycatchblock : ptrycatchblock;
    +        begin
    +          if trycatchblocks_wip.count>0 then
    +            begin
    +              { if we have an except block with filled endlabels
    +                then we can finish that block }
    +              trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +              if (trycatchblock^.kind=bk_try) and assigned(trycatchblock^.tryend) then
    +                internalerror(2019102205)
    +              else if (trycatchblock^.kind=bk_finally) and assigned(trycatchblock^.finallyend) then
    +                internalerror(2019102206)
    +              else if trycatchblock^.kind=bk_except then
    +                begin
    +                  if not assigned(trycatchblock^.excepts) then
    +                    internalerror(2019102207);
    +                  if assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
    +                    begin
    +                      trycatchblocks_wip.extract(trycatchblock);
    +                      trycatchblocks_done.add(trycatchblock);
    +                    end;
    +                end;
    +            end;
    +        end;
    +
           var
             procendlabel   : tasmlabel;
             procentry,s    : string;
    @@ -2284,6 +2335,9 @@ implementation
             st             : tsymtable;
             vmtoffset      : pint;
             in_currentunit : boolean;
    +        ai : tai;
    +        trycatchblock : ptrycatchblock;
    +        i,j : sizeint;
           begin
             { only write debug info for procedures defined in the current module,
               except in case of methods (gcc-compatible)
    @@ -2438,6 +2492,8 @@ implementation
             }
             finish_entry;
     
    +        current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('ParaSyms')));
    +
             if assigned(def.parast) then
               begin
                 { First insert self, because gdb uses the fact whether or not the
    @@ -2452,14 +2508,17 @@ implementation
               end;
             { local type defs and vars should not be written
               inside the main proc }
    +          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('LocalSyms')));
             if in_currentunit and
                assigned(def.localst) and
                (def.localst.symtabletype=localsymtable) then
               write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],def.localst);
     
    +          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('ParaDefs')));
             { last write the types from this procdef }
             if assigned(def.parast) then
               write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.parast);
    +          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('LocalDefs')));
             { only try to write the localst if the routine is implemented here }
             if in_currentunit and
                assigned(def.localst) and
    @@ -2472,6 +2531,169 @@ implementation
                 // write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],def.localst);
               end;
     
    +        { we don't know how the C++ compatible exception blocks are done, so we
    +          only generate this for Pascal DWARF }
    +        if in_currentunit and not (ds_dwarf_cpp in current_settings.debugswitches) then
    +          begin
    +            trycatchblocks_wip:=tfplist.create;
    +            trycatchblocks_done:=tfplist.create;
    +            ai:=def.procstarttai;
    +            while assigned(ai) and (ai<>def.procendtai) do
    +              begin
    +                if ai.typ=ait_marker then
    +                  begin
    +                    case tai_marker(ai).Kind of
    +                      mark_TryBlockStart:
    +                        begin
    +                          maybe_finish_tryexcept;
    +                          new(trycatchblock);
    +                          trycatchblock^.kind:=bk_try;
    +                          trycatchblock^.trystart:=tai_marker(ai).AsmLbl;
    +                          trycatchblock^.tryend:=nil;
    +                          trycatchblock^.finallystart:=nil;
    +                          trycatchblock^.finallyend:=nil;
    +                          trycatchblocks_wip.Add(trycatchblock);
    +                        end;
    +                      mark_TryBlockEnd:
    +                        begin
    +                          maybe_finish_tryexcept;
    +                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_try) then
    +                            internalerror(2019102101);
    +                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                          trycatchblock^.tryend:=tai_marker(ai).AsmLbl;
    +                        end;
    +                      mark_TryFinallyStart:
    +                        begin
    +                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_try) then
    +                            internalerror(2019102202);
    +                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                          trycatchblock^.kind:=bk_finally;
    +                          trycatchblock^.finallystart:=tai_marker(ai).AsmLbl;
    +                        end;
    +                      mark_TryFinallyEnd:
    +                        begin
    +                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_finally) then
    +                            internalerror(2019102203);
    +                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                          trycatchblock^.finallyend:=tai_marker(ai).AsmLbl;
    +                          { we can't have any other block once we got a finally,
    +                            so the whole thing is finished }
    +                          trycatchblocks_wip.extract(trycatchblock);
    +                          trycatchblocks_done.add(trycatchblock);
    +                        end;
    +                      mark_TryExceptStart:
    +                        begin
    +                          if (trycatchblocks_wip.count=0) or not (ptrycatchblock(trycatchblocks_wip.last)^.kind in [bk_try,bk_except]) then
    +                            internalerror(2019102204);
    +                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                          trycatchblock^.kind:=bk_except;
    +                          if assigned(trycatchblock^.excepts) and not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
    +                            internalerror(2019102208);
    +                          setlength(trycatchblock^.excepts,Length(trycatchblock^.excepts)+1);
    +                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptstart:=tai_marker(ai).AsmLbl;
    +                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptvar:=tai_marker(ai).ExceptVar;
    +                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptdef:=tai_marker(ai).ExceptDef;
    +                        end;
    +                      mark_TryExceptEnd:
    +                        begin
    +                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_except) then
    +                            internalerror(2019102209);
    +                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                          if not assigned(trycatchblock^.excepts) or assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
    +                            internalerror(2019102210);
    +                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend:=tai_marker(ai).AsmLbl;
    +                        end;
    +                      else
    +                        { we ignore all other marks }
    +                        ;
    +                    end;
    +                  end;
    +                ai:=tai(ai.next);
    +              end;
    +
    +            while trycatchblocks_wip.count>0 do
    +              begin
    +                { the WIP list should only contain except blocks now }
    +                trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
    +                if trycatchblock^.kind in [bk_try,bk_finally] then
    +                  internalerror(2019102211);
    +                if not assigned(trycatchblock^.excepts) or
    +                    not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptstart) or
    +                    not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
    +                  internalerror(2019102212);
    +                trycatchblocks_wip.extract(trycatchblock);
    +                trycatchblocks_done.add(trycatchblock);
    +              end;
    +
    +            trycatchblocks_wip.free;
    +
    +            for i:=0 to trycatchblocks_done.count-1 do
    +              begin
    +                trycatchblock:=ptrycatchblock(trycatchblocks_done[i]);
    +
    +                { the try block }
    +
    +                if trycatchblock^.kind=bk_finally then
    +                  current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Try Finally Block')))
    +                else
    +                  current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Try Except Block')));
    +
    +                append_entry(DW_TAG_try_block,false,[]);
    +
    +                append_labelentry(DW_AT_low_pc,trycatchblock^.trystart);
    +                append_labelentry(DW_AT_high_pc,trycatchblock^.tryend);
    +
    +                finish_entry;
    +
    +                case trycatchblock^.kind of
    +                  bk_try:
    +                    internalerror(2019102213);
    +                  bk_finally:
    +                    begin
    +                      { DWARF does not specifically specify a finally block,
    +                        so we use a catch block without any parameter... }
    +                      append_entry(DW_TAG_catch_block,false,[]);
    +
    +                      append_labelentry(DW_AT_low_pc,trycatchblock^.finallystart);
    +                      append_labelentry(DW_AT_high_pc,trycatchblock^.finallyend);
    +
    +                      finish_entry;
    +                    end;
    +                  bk_except:
    +                    begin
    +                      for j:=0 to high(trycatchblock^.excepts) do
    +                        begin
    +                          append_entry(DW_TAG_catch_block,true,[]);
    +
    +                          append_labelentry(DW_AT_low_pc,trycatchblock^.excepts[j].exceptstart);
    +                          append_labelentry(DW_AT_high_pc,trycatchblock^.excepts[j].exceptend);
    +
    +                          finish_entry;
    +
    +                          if assigned(trycatchblock^.excepts[j].exceptdef) then
    +                            begin
    +                              append_entry(DW_TAG_formal_parameter,false,[
    +                                DW_AT_name,DW_FORM_string,trycatchblock^.excepts[j].exceptvar+#0
    +                              ]);
    +                              append_labelentry_ref(DW_AT_type,def_dwarf_lab(trycatchblock^.excepts[j].exceptdef));
    +                              finish_entry;
    +                            end
    +                          else
    +                            begin
    +                              append_entry(DW_TAG_unspecified_parameters,false,[]);
    +                              finish_entry;
    +                            end;
    +
    +                          finish_children;
    +                        end;
    +                    end;
    +                end;
    +
    +                dispose(trycatchblock);
    +              end;
    +            trycatchblocks_done.free;
    +          end;
    +
             finish_children;
           end;
     
    diff --git a/compiler/i386/n386flw.pas b/compiler/i386/n386flw.pas
    index ab3c1921..69a75ba2 100644
    --- a/compiler/i386/n386flw.pas
    +++ b/compiler/i386/n386flw.pas
    @@ -272,6 +272,7 @@ procedure emit_scope_end;
     
     procedure ti386tryfinallynode.pass_generate_code;
       var
    +    marklabel,
         finallylabel,
         exceptlabel,
         safecalllabel,
    @@ -352,6 +353,10 @@ procedure ti386tryfinallynode.pass_generate_code;
             current_asmdata.RefAsmSymbol(finalizepi.procdef.mangledname,AT_FUNCTION)
           );
     
    +    current_asmdata.getlabel(marklabel,alt_addr);
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
    +    cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
         { try code }
         if assigned(left) then
           begin
    @@ -361,6 +366,10 @@ procedure ti386tryfinallynode.pass_generate_code;
               exit;
           end;
     
    +    current_asmdata.getlabel(marklabel,alt_addr);
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
    +    cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
         { don't generate line info for internal cleanup }
         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
     
    @@ -391,6 +400,9 @@ procedure ti386tryfinallynode.pass_generate_code;
         { right is a call to finalizer procedure }
         secondpass(right);
     
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,finallylabel));
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,endfinallylabel));
    +
         { goto is allowed if it stays inside the finally block,
           this is checked using the exception block number }
         if (flowcontrol-[fc_gotolabel])<>[fc_inflowcontrol] then
    @@ -445,6 +457,7 @@ procedure ti386tryfinallynode.pass_generate_code;
     
     procedure ti386tryexceptnode.pass_generate_code;
       var
    +    marklabel,
         exceptlabel,oldendexceptlabel,
         lastonlabel,
         exitexceptlabel,
    @@ -463,6 +476,7 @@ procedure ti386tryexceptnode.pass_generate_code;
         hnode : tnode;
         hlist : tasmlist;
         onnodecount : tai_const;
    +    marker : tai_marker;
       label
         errorexit;
       begin
    @@ -536,11 +550,19 @@ procedure ti386tryexceptnode.pass_generate_code;
             current_procinfo.CurrBreakLabel:=breaktrylabel;
           end;
     
    +    current_asmdata.getlabel(marklabel,alt_addr);
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
    +    cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
         secondpass(left);
         tryflowcontrol:=flowcontrol;
         if codegenerror then
           goto errorexit;
     
    +    current_asmdata.getlabel(marklabel,alt_addr);
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
    +    cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
         emit_scope_end;
         { jump over except handlers }
         cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
    @@ -596,7 +618,21 @@ procedure ti386tryexceptnode.pass_generate_code;
                 hlist.concat(tai_const.create_sym(current_asmdata.RefAsmSymbol(tonnode(hnode).excepttype.vmt_mangledname,AT_DATA)));
                 hlist.concat(tai_const.create_sym(onlabel));
                 cg.a_label(current_asmdata.CurrAsmList,onlabel);
    +
    +            marker:=tai_marker.create(mark_TryExceptStart,onlabel);
    +            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
    +            marker.ExceptDef:=tonnode(hnode).excepttype;
    +            current_asmdata.CurrAsmList.concat(marker);
    +
                 secondpass(hnode);
    +
    +            current_asmdata.getlabel(marklabel,alt_addr);
    +            marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
    +            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
    +            marker.ExceptDef:=tonnode(hnode).excepttype;
    +            current_asmdata.CurrAsmList.concat(marker);
    +            cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
                 inc(onnodecount.value);
                 hnode:=tonnode(hnode).left;
               end;
    @@ -617,7 +653,16 @@ procedure ti386tryexceptnode.pass_generate_code;
           begin
             { here we don't have to reset flowcontrol           }
             { the default and on flowcontrols are handled equal }
    +        current_asmdata.getlabel(marklabel,alt_addr);
    +        current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptStart,marklabel));
    +        cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
             secondpass(t1);
    +
    +        current_asmdata.getlabel(marklabel,alt_addr);
    +        current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptEnd,marklabel));
    +        cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
             cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
             if (flowcontrol*[fc_exit,fc_break,fc_continue]<>[]) then
               cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
    diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas
    index a16abcae..706da4fc 100644
    --- a/compiler/ncgflw.pas
    +++ b/compiler/ncgflw.pas
    @@ -545,6 +545,7 @@ implementation
         procedure tcgtryexceptnode.pass_generate_code;
     
           var
    +         marklabel,
              oldendexceptlabel,
              lastonlabel,
              exitexceptlabel,
    @@ -609,10 +610,18 @@ implementation
                 current_procinfo.CurrBreakLabel:=breaktrylabel;
               end;
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              secondpass(left);
              if codegenerror then
                goto errorexit;
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              { don't generate line info for internal cleanup }
              current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
     
    @@ -675,8 +684,16 @@ implementation
                      { except block needs line info }
                      current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
     
    +                 current_asmdata.getlabel(marklabel,alt_addr);
    +                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptStart,marklabel));
    +                 hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
                      secondpass(t1);
     
    +                 current_asmdata.getlabel(marklabel,alt_addr);
    +                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptEnd,marklabel));
    +                 hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
                      cexceptionstatehandler.handle_nested_exception(current_asmdata.CurrAsmList,destroytemps,doobjectdestroyandreraisestate);
     
                      cexceptionstatehandler.unget_exception_temps(current_asmdata.CurrAsmList,destroytemps);
    @@ -685,6 +702,10 @@ implementation
                    end
                  else
                    begin
    +                 current_asmdata.getlabel(marklabel,alt_addr);
    +                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptStart,marklabel));
    +                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptEnd,marklabel));
    +                 hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
                      doobjectdestroyandreraisestate.newflowcontrol:=afteronflowcontrol;
                      cexceptionstatehandler.cleanupobjectstack(current_asmdata.CurrAsmList);
                      cexceptionstatehandler.catch_all_end(current_asmdata.CurrAsmList);
    @@ -741,6 +762,7 @@ implementation
     
         procedure tcgonnode.pass_generate_code;
           var
    +         marklabel,
              nextonlabel,
              exitonlabel,
              continueonlabel,
    @@ -753,6 +775,7 @@ implementation
              exceptvarsym : tlocalvarsym;
              exceptlocdef: tdef;
              exceptlocreg: tregister;
    +         marker : tai_marker;
           begin
              location_reset(location,LOC_VOID,OS_NO);
              oldCurrExitLabel:=nil;
    @@ -799,7 +822,21 @@ implementation
                      current_procinfo.CurrBreakLabel:=breakonlabel;
                    end;
     
    +              current_asmdata.getlabel(marklabel,alt_addr);
    +              marker:=tai_marker.create(mark_TryExceptStart,marklabel);
    +              marker.ExceptVar:=exceptvar.name;
    +              marker.ExceptDef:=excepttype;
    +              current_asmdata.CurrAsmList.concat(marker);
    +              hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
                   secondpass(right);
    +
    +              current_asmdata.getlabel(marklabel,alt_addr);
    +              marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
    +              marker.ExceptVar:=exceptvar.name;
    +              marker.ExceptDef:=excepttype;
    +              current_asmdata.CurrAsmList.concat(marker);
    +              hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
                end;
     
              cexceptionstatehandler.handle_nested_exception(current_asmdata.CurrAsmList,excepttemps,doobjectdestroyandreraisestate);
    @@ -906,6 +943,7 @@ implementation
     
         procedure tcgtryfinallynode.pass_generate_code;
           var
    +         marklabel,
              endfinallylabel,
              exitfinallylabel,
              continuefinallylabel,
    @@ -976,6 +1014,10 @@ implementation
                 current_procinfo.CurrBreakLabel:=breakfinallylabel;
               end;
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              { try code }
              if assigned(left) then
                begin
    @@ -984,6 +1026,10 @@ implementation
                     exit;
                end;
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              { don't generate line info for internal cleanup }
              current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
     
    @@ -1022,6 +1068,10 @@ implementation
              { end cleanup }
              current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              { finally code (don't unconditionally set fc_inflowcontrol, since the
                finally code is unconditionally executed; we do have to filter out
                flags regarding break/contrinue/etc. because we have to give an
    @@ -1035,6 +1085,10 @@ implementation
              if codegenerror then
                exit;
     
    +         current_asmdata.getlabel(marklabel,alt_addr);
    +         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,marklabel));
    +         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
    +
              { don't generate line info for internal cleanup }
              current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
     
    diff --git a/compiler/nflw.pas b/compiler/nflw.pas
    index 2d85b997..5a01c086 100644
    --- a/compiler/nflw.pas
    +++ b/compiler/nflw.pas
    @@ -254,6 +254,7 @@ interface
               function pass_1 : tnode;override;
               function dogetcopy : tnode;override;
               function docompare(p: tnode): boolean; override;
    +          function exceptvar:tsym;
            end;
            tonnodeclass = class of tonnode;
     
    @@ -2600,4 +2601,12 @@ implementation
             docompare := false;
           end;
     
    +
    +    function tonnode.exceptvar:tsym;
    +      begin
    +        if exceptsymtable.symlist.count<>1 then
    +          internalerror(2019102401);
    +        result:=tsym(exceptsymtable.symlist[0]);
    +      end;
    +
     end.
    diff --git a/compiler/x86_64/nx64flw.pas b/compiler/x86_64/nx64flw.pas
    index b391d359..f889e3f0 100644
    --- a/compiler/x86_64/nx64flw.pas
    +++ b/compiler/x86_64/nx64flw.pas
    @@ -276,6 +276,7 @@ procedure tx64tryfinallynode.pass_generate_code;
     
         emit_nop;
         cg.a_label(current_asmdata.CurrAsmList,trylabel);
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,trylabel));
     
         { try code }
         if assigned(left) then
    @@ -321,6 +322,10 @@ procedure tx64tryfinallynode.pass_generate_code;
             cg.a_label(current_asmdata.CurrAsmList,endtrylabel);
           end;
     
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,endtrylabel));
    +
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,finallylabel));
    +
         flowcontrol:=[fc_inflowcontrol];
         { generate finally code as a separate procedure }
         if not implicitframe then
    @@ -337,6 +342,8 @@ procedure tx64tryfinallynode.pass_generate_code;
     
         cg.a_label(current_asmdata.CurrAsmList,endfinallylabel);
     
    +    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,endfinallylabel));
    +
         { generate the scope record in .xdata }
         tcpuprocinfo(current_procinfo).add_finally_scope(trylabel,endtrylabel,
           current_asmdata.RefAsmSymbol(finalizepi.procdef.mangledname,AT_FUNCTION),catch_frame);
    @@ -359,6 +366,7 @@ procedure tx64tryexceptnode.pass_generate_code;
         oldCurrExitLabel,
         oldContinueLabel,
         oldBreakLabel : tasmlabel;
    +    marklabel,
         onlabel,
         filterlabel: tasmlabel;
         oldflowcontrol,tryflowcontrol,
    @@ -366,6 +374,7 @@ procedure tx64tryexceptnode.pass_generate_code;
         hnode : tnode;
         hlist : tasmlist;
         onnodecount : tai_const;
    +    marker : tai_marker;
       label
         errorexit;
       begin
    @@ -407,6 +416,7 @@ procedure tx64tryexceptnode.pass_generate_code;
         current_asmdata.getjumplabel(trylabel);
         emit_nop;
         cg.a_label(current_asmdata.CurrAsmList,trylabel);
    +    current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryBlockStart,trylabel));
     
         { control flow in try block needs no special handling,
           just make sure that target labels are outside the scope }
    @@ -421,6 +431,8 @@ procedure tx64tryexceptnode.pass_generate_code;
         { end of scope }
         cg.a_label(current_asmdata.CurrAsmList,exceptlabel);
     
    +    current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryBlockEnd,exceptlabel));
    +
         { set control flow labels for the except block }
         { and the on statements                        }
         current_procinfo.CurrExitLabel:=exitexceptlabel;
    @@ -451,7 +463,17 @@ procedure tx64tryexceptnode.pass_generate_code;
                 hlist.concat(tai_const.create_rva_sym(current_asmdata.RefAsmSymbol(tonnode(hnode).excepttype.vmt_mangledname,AT_DATA)));
                 hlist.concat(tai_const.create_rva_sym(onlabel));
                 cg.a_label(current_asmdata.CurrAsmList,onlabel);
    +            marker:=tai_marker.create(mark_TryExceptStart,onlabel);
    +            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
    +            marker.ExceptDef:=tonnode(hnode).excepttype;
    +            current_asmdata.CurrAsmList.Concat(marker);
                 secondpass(hnode);
    +            current_asmdata.getjumplabel(marklabel);
    +            cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +            marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
    +            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
    +            marker.ExceptDef:=tonnode(hnode).excepttype;
    +            current_asmdata.CurrAsmList.Concat(marker);
                 inc(onnodecount.value);
                 hnode:=tonnode(hnode).left;
               end;
    @@ -472,7 +494,11 @@ procedure tx64tryexceptnode.pass_generate_code;
           begin
             { here we don't have to reset flowcontrol           }
             { the default and on flowcontrols are handled equal }
    +        current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryExceptStart,lastonlabel));
             secondpass(t1);
    +        current_asmdata.getjumplabel(marklabel);
    +        cg.a_label(current_asmdata.CurrAsmList,marklabel);
    +        current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryExceptEnd,marklabel));
             cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
             if (flowcontrol*[fc_exit,fc_break,fc_continue]<>[]) then
               cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
    

Relationships

related to 0034502 assignedMartin Friebe Lazarus Lazarus WIN32_SEH debugging with F8 

Activities

Sven Barth

2019-10-25 22:19

manager   ~0118813

I've attached a proof-of-concept patch against current trunk (revision 43299) that uses the DWARF tags DW_TAG_try_block and DW_TAG_catch_block. I've not precisely followed the specification as Pascal has a try-finally unlike C++. So the implementation is like this:
All exception related blocks are contained inside the DW_TAG_subprogram entry. The try..X part of the block is represented by a DW_TAG_try_block of which the low and high addresses point to the first and last instruction of the block respectively. Then there is a sibling of type DW_TAG_catch_block either for the finally-block or for each except-on-block as well as the else-handler. The DW_TAG_catch_block for the finally-block does not have any further children. For an except-on-block there is a DW_TAG_formal_parameter containing both the name and type of the exception variable as DW_AT_name and DW_AT_type respectively. The else branch of an try-except-block does have a DW_TAG_unspecified_parameters child. In all cases the low and high attributes of the DW_TAG_catch_block point to the first and last instruction of the corresponding block.

The generation of this debug information is implemented for all four exception schemes that FPC supports:
- generic, cross platform mechanism
- Win64 SEH
- Win32 SEH
- PSABIEH
As this is not really compatible with the specification for C++ none of the debug information will be generated if the C++ compatible DWARF debug information is to be generated.

I don't know how to query GDB for specific debug information, so I don't know whether it would handle this correctly. Also neither GCC nor Clang generate this debug information, only ICC is said to do so and I honestly had no interest to download it.

I'm not yet perfectly happy with the patch (especially the part in dbgdwarf), but you can experiment with it and tell me whether this would be a suitable way to go.

Possible improvements:
- mark "raise" sites with debug information as well (DW_TAG_thrown_type?)
- for nested exception blocks the debug information might be nested as well (currently they are *all* siblings)
(- this could in the future be extended to DW_TAG_with_stmt as well, though that's unrelated to exceptions)
- provide the debug information also for the C++ compatible DWARF mode (what to do about try-finally however?)

dwarf-except-debuginfo.patch (32,105 bytes)
diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas
index 7d662323..2c816211 100644
--- a/compiler/aasmtai.pas
+++ b/compiler/aasmtai.pas
@@ -351,8 +351,12 @@ interface
       TAsmMarker = (
         mark_NoPropInfoStart,mark_NoPropInfoEnd,
         mark_AsmBlockStart,mark_AsmBlockEnd,
-        mark_NoLineInfoStart,mark_NoLineInfoEnd,mark_BlockStart,
-        mark_Position
+        mark_NoLineInfoStart,mark_NoLineInfoEnd,
+        mark_TryBlockStart,mark_TryBlockEnd,
+        mark_TryFinallyStart,mark_TryFinallyEnd,
+        mark_TryExceptStart,mark_TryExceptEnd,
+        mark_Raise,
+        mark_BlockStart,mark_Position
       );
 
       TRegAllocType = (ra_alloc,ra_dealloc,ra_sync,ra_resize,ra_markused);
@@ -789,9 +793,16 @@ interface
        { Insert a marker for assembler and inline blocks }
        tai_marker = class(tai)
           Kind: TAsmMarker;
+          AsmLbl : TAsmSymbol;
+          ExceptVar : tsymstr;
+          ExceptDef : tdef;
+          ExceptDefDeref : tderef;
           Constructor Create(_Kind: TAsmMarker);
+          constructor Create(_kind:tasmmarker;_asmlbl:tasmsymbol);
           constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
+          procedure derefimpl; override;
+          procedure buildderefimpl; override;
        end;
 
        tai_tempalloc = class(tai)
@@ -2545,7 +2556,7 @@ implementation
                              Tai_Marker
  ****************************************************************************}
 
-    constructor Tai_Marker.Create(_Kind: TAsmMarker);
+    constructor tai_marker.Create(_Kind: TAsmMarker);
       begin
         Inherited Create;
         typ := ait_marker;
@@ -2553,17 +2564,54 @@ implementation
       end;
 
 
-    constructor Tai_Marker.ppuload(t:taitype;ppufile:tcompilerppufile);
+    constructor tai_marker.Create(_kind: tasmmarker; _asmlbl: tasmsymbol);
+      begin
+        Inherited Create;
+        typ:=ait_marker;
+        Kind:=_kind;
+        AsmLbl:=_asmlbl;
+      end;
+
+
+    constructor tai_marker.ppuload(t: taitype; ppufile: tcompilerppufile);
       begin
         inherited ppuload(t,ppufile);
         kind:=TAsmMarker(ppufile.getbyte);
+        AsmLbl:=ppufile.getasmsymbol;
+        ppufile.getderef(ExceptDefDeref);
+{$ifdef symansistr}
+        ExceptVar:=ppufile.getansistring
+{$else symansistr}
+        ExceptVar:=ppufile.getstring;
+{$endif symansistr}
       end;
 
 
-    procedure Tai_Marker.ppuwrite(ppufile:tcompilerppufile);
+    procedure tai_marker.ppuwrite(ppufile: tcompilerppufile);
       begin
         inherited ppuwrite(ppufile);
         ppufile.putbyte(byte(kind));
+        ppufile.putasmsymbol(AsmLbl);
+        ppufile.putderef(ExceptDefDeref);
+{$ifdef symansistr}
+        ppufile.putansistring(ExceptVar);
+{$else symansistr}
+        ppufile.putstring(ExceptVar);
+{$endif symansistr}
+      end;
+
+
+    procedure tai_marker.derefimpl;
+      begin
+        ExceptDef:=tdef(ExceptDefDeref.resolve);
+        inherited derefimpl;
+      end;
+
+
+    procedure tai_marker.buildderefimpl;
+      begin
+        ExceptDefDeref.build(ExceptDef);
+        inherited buildderefimpl;
       end;
 
 
diff --git a/compiler/dbgdwarf.pas b/compiler/dbgdwarf.pas
index 4bc522dd..0c0668ba 100644
--- a/compiler/dbgdwarf.pas
+++ b/compiler/dbgdwarf.pas
@@ -2277,6 +2277,26 @@ implementation
           end
         end;
 
+      type
+        tblockkind = (bk_try, bk_finally, bk_except);
+
+        texceptinfo = record
+          exceptvar : TSymStr;
+          exceptdef : tdef;
+          exceptstart : tasmsymbol;
+          exceptend : tasmsymbol;
+        end;
+
+        ttrycatchblock = record
+          kind : tblockkind;
+          trystart,
+          tryend: tasmsymbol;
+          finallystart,
+          finallyend: tasmsymbol;
+          excepts : array of texceptinfo;
+        end;
+        ptrycatchblock = ^ttrycatchblock;
+
       var
         procendlabel   : tasmlabel;
         procentry,s    : string;
@@ -2284,6 +2304,11 @@ implementation
         st             : tsymtable;
         vmtoffset      : pint;
         in_currentunit : boolean;
+        ai : tai;
+        trycatchblocks_wip,
+        trycatchblocks_done : tfplist;
+        trycatchblock : ptrycatchblock;
+        i,j : sizeint;
       begin
         { only write debug info for procedures defined in the current module,
           except in case of methods (gcc-compatible)
@@ -2438,6 +2463,8 @@ implementation
         }
         finish_entry;
 
+        current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('ParaSyms')));
+
         if assigned(def.parast) then
           begin
             { First insert self, because gdb uses the fact whether or not the
@@ -2452,14 +2479,17 @@ implementation
           end;
         { local type defs and vars should not be written
           inside the main proc }
+          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('LocalSyms')));
         if in_currentunit and
            assigned(def.localst) and
            (def.localst.symtabletype=localsymtable) then
           write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],def.localst);
 
+          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('ParaDefs')));
         { last write the types from this procdef }
         if assigned(def.parast) then
           write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.parast);
+          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('LocalDefs')));
         { only try to write the localst if the routine is implemented here }
         if in_currentunit and
            assigned(def.localst) and
@@ -2472,6 +2502,187 @@ implementation
             // write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],def.localst);
           end;
 
+        { we don't know how the C++ compatible exception blocks are done, so we
+          only generate this for Pascal DWARF }
+        if in_currentunit and not (ds_dwarf_cpp in current_settings.debugswitches) then
+          begin
+            trycatchblocks_wip:=tfplist.create;
+            trycatchblocks_done:=tfplist.create;
+            ai:=def.procstarttai;
+            while assigned(ai) and (ai<>def.procendtai) do
+              begin
+                if ai.typ=ait_marker then
+                  begin
+                    case tai_marker(ai).Kind of
+                      mark_TryBlockStart:
+                        begin
+                          if trycatchblocks_wip.count>0 then
+                            begin
+                              { if we have an except block with filled endlabels
+                                then we can finish that block }
+                              trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                              if (trycatchblock^.kind=bk_try) and assigned(trycatchblock^.tryend) then
+                                internalerror(2019102205)
+                              else if (trycatchblock^.kind=bk_finally) and assigned(trycatchblock^.finallyend) then
+                                internalerror(2019102206)
+                              else if trycatchblock^.kind=bk_except then
+                                begin
+                                  if not assigned(trycatchblock^.excepts) then
+                                    internalerror(2019102207);
+                                  if assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
+                                    begin
+                                      trycatchblocks_wip.extract(trycatchblock);
+                                      trycatchblocks_done.add(trycatchblock);
+                                    end;
+                                end;
+                            end;
+                          new(trycatchblock);
+                          trycatchblock^.kind:=bk_try;
+                          trycatchblock^.trystart:=tai_marker(ai).AsmLbl;
+                          trycatchblock^.tryend:=nil;
+                          trycatchblock^.finallystart:=nil;
+                          trycatchblock^.finallyend:=nil;
+                          trycatchblocks_wip.Add(trycatchblock);
+                        end;
+                      mark_TryBlockEnd:
+                        begin
+                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_try) then
+                            internalerror(2019102101);
+                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                          trycatchblock^.tryend:=tai_marker(ai).AsmLbl;
+                        end;
+                      mark_TryFinallyStart:
+                        begin
+                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_try) then
+                            internalerror(2019102202);
+                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                          trycatchblock^.kind:=bk_finally;
+                          trycatchblock^.finallystart:=tai_marker(ai).AsmLbl;
+                        end;
+                      mark_TryFinallyEnd:
+                        begin
+                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_finally) then
+                            internalerror(2019102203);
+                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                          trycatchblock^.finallyend:=tai_marker(ai).AsmLbl;
+                          { we can't have any other block once we got a finally,
+                            so the whole thing is finished }
+                          trycatchblocks_wip.extract(trycatchblock);
+                          trycatchblocks_done.add(trycatchblock);
+                        end;
+                      mark_TryExceptStart:
+                        begin
+                          if (trycatchblocks_wip.count=0) or not (ptrycatchblock(trycatchblocks_wip.last)^.kind in [bk_try,bk_except]) then
+                            internalerror(2019102204);
+                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                          trycatchblock^.kind:=bk_except;
+                          if assigned(trycatchblock^.excepts) and not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
+                            internalerror(2019102208);
+                          setlength(trycatchblock^.excepts,Length(trycatchblock^.excepts)+1);
+                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptstart:=tai_marker(ai).AsmLbl;
+                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptvar:=tai_marker(ai).ExceptVar;
+                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptdef:=tai_marker(ai).ExceptDef;
+                        end;
+                      mark_TryExceptEnd:
+                        begin
+                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_except) then
+                            internalerror(2019102209);
+                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                          if not assigned(trycatchblock^.excepts) or assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
+                            internalerror(2019102210);
+                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend:=tai_marker(ai).AsmLbl;
+                        end;
+                      else
+                        { we ignore all other marks }
+                        ;
+                    end;
+                  end;
+                ai:=tai(ai.next);
+              end;
+
+            while trycatchblocks_wip.count>0 do
+              begin
+                { the WIP list should only contain except blocks now }
+                trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                if trycatchblock^.kind in [bk_try,bk_finally] then
+                  internalerror(2019102211);
+                if not assigned(trycatchblock^.excepts) or
+                    not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptstart) or
+                    not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
+                  internalerror(2019102212);
+                trycatchblocks_wip.extract(trycatchblock);
+                trycatchblocks_done.add(trycatchblock);
+              end;
+
+            trycatchblocks_wip.free;
+
+            for i:=0 to trycatchblocks_done.count-1 do
+              begin
+                trycatchblock:=ptrycatchblock(trycatchblocks_done[i]);
+
+                { the try block }
+
+                if trycatchblock^.kind=bk_finally then
+                  current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Try Finally Block')))
+                else
+                  current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Try Except Block')));
+
+                append_entry(DW_TAG_try_block,false,[]);
+
+                append_labelentry(DW_AT_low_pc,trycatchblock^.trystart);
+                append_labelentry(DW_AT_high_pc,trycatchblock^.tryend);
+
+                finish_entry;
+
+                case trycatchblock^.kind of
+                  bk_try:
+                    internalerror(2019102213);
+                  bk_finally:
+                    begin
+                      { DWARF does not specifically specify a finally block,
+                        so we use a catch block without any parameter... }
+                      append_entry(DW_TAG_catch_block,false,[]);
+
+                      append_labelentry(DW_AT_low_pc,trycatchblock^.finallystart);
+                      append_labelentry(DW_AT_high_pc,trycatchblock^.finallyend);
+
+                      finish_entry;
+                    end;
+                  bk_except:
+                    begin
+                      for j:=0 to high(trycatchblock^.excepts) do
+                        begin
+                          append_entry(DW_TAG_catch_block,true,[]);
+
+                          append_labelentry(DW_AT_low_pc,trycatchblock^.excepts[j].exceptstart);
+                          append_labelentry(DW_AT_high_pc,trycatchblock^.excepts[j].exceptend);
+
+                          finish_entry;
+
+                          if assigned(trycatchblock^.excepts[j].exceptdef) then
+                            begin
+                              append_entry(DW_TAG_formal_parameter,false,[
+                                DW_AT_name,DW_FORM_string,trycatchblock^.excepts[j].exceptvar+#0
+                              ]);
+                              append_labelentry_ref(DW_AT_type,def_dwarf_lab(trycatchblock^.excepts[j].exceptdef));
+                              finish_entry;
+                            end
+                          else
+                            begin
+                              append_entry(DW_TAG_unspecified_parameters,false,[]);
+                              finish_entry;
+                            end;
+
+                          finish_children;
+                        end;
+                    end;
+                end;
+
+                dispose(trycatchblock);
+              end;
+            trycatchblocks_done.free;
+          end;
+
         finish_children;
       end;
 
diff --git a/compiler/i386/n386flw.pas b/compiler/i386/n386flw.pas
index ab3c1921..69a75ba2 100644
--- a/compiler/i386/n386flw.pas
+++ b/compiler/i386/n386flw.pas
@@ -272,6 +272,7 @@ procedure emit_scope_end;
 
 procedure ti386tryfinallynode.pass_generate_code;
   var
+    marklabel,
     finallylabel,
     exceptlabel,
     safecalllabel,
@@ -352,6 +353,10 @@ procedure ti386tryfinallynode.pass_generate_code;
         current_asmdata.RefAsmSymbol(finalizepi.procdef.mangledname,AT_FUNCTION)
       );
 
+    current_asmdata.getlabel(marklabel,alt_addr);
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
+    cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
     { try code }
     if assigned(left) then
       begin
@@ -361,6 +366,10 @@ procedure ti386tryfinallynode.pass_generate_code;
           exit;
       end;
 
+    current_asmdata.getlabel(marklabel,alt_addr);
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
+    cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
     { don't generate line info for internal cleanup }
     current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
 
@@ -391,6 +400,9 @@ procedure ti386tryfinallynode.pass_generate_code;
     { right is a call to finalizer procedure }
     secondpass(right);
 
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,finallylabel));
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,endfinallylabel));
+
     { goto is allowed if it stays inside the finally block,
       this is checked using the exception block number }
     if (flowcontrol-[fc_gotolabel])<>[fc_inflowcontrol] then
@@ -445,6 +457,7 @@ procedure ti386tryfinallynode.pass_generate_code;
 
 procedure ti386tryexceptnode.pass_generate_code;
   var
+    marklabel,
     exceptlabel,oldendexceptlabel,
     lastonlabel,
     exitexceptlabel,
@@ -463,6 +476,7 @@ procedure ti386tryexceptnode.pass_generate_code;
     hnode : tnode;
     hlist : tasmlist;
     onnodecount : tai_const;
+    marker : tai_marker;
   label
     errorexit;
   begin
@@ -536,11 +550,19 @@ procedure ti386tryexceptnode.pass_generate_code;
         current_procinfo.CurrBreakLabel:=breaktrylabel;
       end;
 
+    current_asmdata.getlabel(marklabel,alt_addr);
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
+    cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
     secondpass(left);
     tryflowcontrol:=flowcontrol;
     if codegenerror then
       goto errorexit;
 
+    current_asmdata.getlabel(marklabel,alt_addr);
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
+    cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
     emit_scope_end;
     { jump over except handlers }
     cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
@@ -596,7 +618,21 @@ procedure ti386tryexceptnode.pass_generate_code;
             hlist.concat(tai_const.create_sym(current_asmdata.RefAsmSymbol(tonnode(hnode).excepttype.vmt_mangledname,AT_DATA)));
             hlist.concat(tai_const.create_sym(onlabel));
             cg.a_label(current_asmdata.CurrAsmList,onlabel);
+
+            marker:=tai_marker.create(mark_TryExceptStart,onlabel);
+            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
+            marker.ExceptDef:=tonnode(hnode).excepttype;
+            current_asmdata.CurrAsmList.concat(marker);
+
             secondpass(hnode);
+
+            current_asmdata.getlabel(marklabel,alt_addr);
+            marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
+            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
+            marker.ExceptDef:=tonnode(hnode).excepttype;
+            current_asmdata.CurrAsmList.concat(marker);
+            cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
             inc(onnodecount.value);
             hnode:=tonnode(hnode).left;
           end;
@@ -617,7 +653,16 @@ procedure ti386tryexceptnode.pass_generate_code;
       begin
         { here we don't have to reset flowcontrol           }
         { the default and on flowcontrols are handled equal }
+        current_asmdata.getlabel(marklabel,alt_addr);
+        current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptStart,marklabel));
+        cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
         secondpass(t1);
+
+        current_asmdata.getlabel(marklabel,alt_addr);
+        current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptEnd,marklabel));
+        cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
         cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
         if (flowcontrol*[fc_exit,fc_break,fc_continue]<>[]) then
           cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas
index a16abcae..9e2d1cb9 100644
--- a/compiler/ncgflw.pas
+++ b/compiler/ncgflw.pas
@@ -545,6 +545,7 @@ implementation
     procedure tcgtryexceptnode.pass_generate_code;
 
       var
+         marklabel,
          oldendexceptlabel,
          lastonlabel,
          exitexceptlabel,
@@ -609,10 +610,18 @@ implementation
             current_procinfo.CurrBreakLabel:=breaktrylabel;
           end;
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          secondpass(left);
          if codegenerror then
            goto errorexit;
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          { don't generate line info for internal cleanup }
          current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
 
@@ -675,8 +684,16 @@ implementation
                  { except block needs line info }
                  current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
 
+                 current_asmdata.getlabel(marklabel,alt_addr);
+                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptStart,marklabel));
+                 hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
                  secondpass(t1);
 
+                 current_asmdata.getlabel(marklabel,alt_addr);
+                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptEnd,marklabel));
+                 hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
                  cexceptionstatehandler.handle_nested_exception(current_asmdata.CurrAsmList,destroytemps,doobjectdestroyandreraisestate);
 
                  cexceptionstatehandler.unget_exception_temps(current_asmdata.CurrAsmList,destroytemps);
@@ -741,6 +758,7 @@ implementation
 
     procedure tcgonnode.pass_generate_code;
       var
+         marklabel,
          nextonlabel,
          exitonlabel,
          continueonlabel,
@@ -753,6 +771,7 @@ implementation
          exceptvarsym : tlocalvarsym;
          exceptlocdef: tdef;
          exceptlocreg: tregister;
+         marker : tai_marker;
       begin
          location_reset(location,LOC_VOID,OS_NO);
          oldCurrExitLabel:=nil;
@@ -799,7 +818,21 @@ implementation
                  current_procinfo.CurrBreakLabel:=breakonlabel;
                end;
 
+              current_asmdata.getlabel(marklabel,alt_addr);
+              marker:=tai_marker.create(mark_TryExceptStart,marklabel);
+              marker.ExceptVar:=exceptvar.name;
+              marker.ExceptDef:=excepttype;
+              current_asmdata.CurrAsmList.concat(marker);
+              hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
               secondpass(right);
+
+              current_asmdata.getlabel(marklabel,alt_addr);
+              marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
+              marker.ExceptVar:=exceptvar.name;
+              marker.ExceptDef:=excepttype;
+              current_asmdata.CurrAsmList.concat(marker);
+              hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
            end;
 
          cexceptionstatehandler.handle_nested_exception(current_asmdata.CurrAsmList,excepttemps,doobjectdestroyandreraisestate);
@@ -906,6 +939,7 @@ implementation
 
     procedure tcgtryfinallynode.pass_generate_code;
       var
+         marklabel,
          endfinallylabel,
          exitfinallylabel,
          continuefinallylabel,
@@ -976,6 +1010,10 @@ implementation
             current_procinfo.CurrBreakLabel:=breakfinallylabel;
           end;
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          { try code }
          if assigned(left) then
            begin
@@ -984,6 +1022,10 @@ implementation
                 exit;
            end;
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          { don't generate line info for internal cleanup }
          current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
 
@@ -1022,6 +1064,10 @@ implementation
          { end cleanup }
          current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          { finally code (don't unconditionally set fc_inflowcontrol, since the
            finally code is unconditionally executed; we do have to filter out
            flags regarding break/contrinue/etc. because we have to give an
@@ -1035,6 +1081,10 @@ implementation
          if codegenerror then
            exit;
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          { don't generate line info for internal cleanup }
          current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
 
diff --git a/compiler/nflw.pas b/compiler/nflw.pas
index 2d85b997..5a01c086 100644
--- a/compiler/nflw.pas
+++ b/compiler/nflw.pas
@@ -254,6 +254,7 @@ interface
           function pass_1 : tnode;override;
           function dogetcopy : tnode;override;
           function docompare(p: tnode): boolean; override;
+          function exceptvar:tsym;
        end;
        tonnodeclass = class of tonnode;
 
@@ -2600,4 +2601,12 @@ implementation
         docompare := false;
       end;
 
+
+    function tonnode.exceptvar:tsym;
+      begin
+        if exceptsymtable.symlist.count<>1 then
+          internalerror(2019102401);
+        result:=tsym(exceptsymtable.symlist[0]);
+      end;
+
 end.
diff --git a/compiler/x86_64/nx64flw.pas b/compiler/x86_64/nx64flw.pas
index b391d359..f889e3f0 100644
--- a/compiler/x86_64/nx64flw.pas
+++ b/compiler/x86_64/nx64flw.pas
@@ -276,6 +276,7 @@ procedure tx64tryfinallynode.pass_generate_code;
 
     emit_nop;
     cg.a_label(current_asmdata.CurrAsmList,trylabel);
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,trylabel));
 
     { try code }
     if assigned(left) then
@@ -321,6 +322,10 @@ procedure tx64tryfinallynode.pass_generate_code;
         cg.a_label(current_asmdata.CurrAsmList,endtrylabel);
       end;
 
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,endtrylabel));
+
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,finallylabel));
+
     flowcontrol:=[fc_inflowcontrol];
     { generate finally code as a separate procedure }
     if not implicitframe then
@@ -337,6 +342,8 @@ procedure tx64tryfinallynode.pass_generate_code;
 
     cg.a_label(current_asmdata.CurrAsmList,endfinallylabel);
 
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,endfinallylabel));
+
     { generate the scope record in .xdata }
     tcpuprocinfo(current_procinfo).add_finally_scope(trylabel,endtrylabel,
       current_asmdata.RefAsmSymbol(finalizepi.procdef.mangledname,AT_FUNCTION),catch_frame);
@@ -359,6 +366,7 @@ procedure tx64tryexceptnode.pass_generate_code;
     oldCurrExitLabel,
     oldContinueLabel,
     oldBreakLabel : tasmlabel;
+    marklabel,
     onlabel,
     filterlabel: tasmlabel;
     oldflowcontrol,tryflowcontrol,
@@ -366,6 +374,7 @@ procedure tx64tryexceptnode.pass_generate_code;
     hnode : tnode;
     hlist : tasmlist;
     onnodecount : tai_const;
+    marker : tai_marker;
   label
     errorexit;
   begin
@@ -407,6 +416,7 @@ procedure tx64tryexceptnode.pass_generate_code;
     current_asmdata.getjumplabel(trylabel);
     emit_nop;
     cg.a_label(current_asmdata.CurrAsmList,trylabel);
+    current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryBlockStart,trylabel));
 
     { control flow in try block needs no special handling,
       just make sure that target labels are outside the scope }
@@ -421,6 +431,8 @@ procedure tx64tryexceptnode.pass_generate_code;
     { end of scope }
     cg.a_label(current_asmdata.CurrAsmList,exceptlabel);
 
+    current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryBlockEnd,exceptlabel));
+
     { set control flow labels for the except block }
     { and the on statements                        }
     current_procinfo.CurrExitLabel:=exitexceptlabel;
@@ -451,7 +463,17 @@ procedure tx64tryexceptnode.pass_generate_code;
             hlist.concat(tai_const.create_rva_sym(current_asmdata.RefAsmSymbol(tonnode(hnode).excepttype.vmt_mangledname,AT_DATA)));
             hlist.concat(tai_const.create_rva_sym(onlabel));
             cg.a_label(current_asmdata.CurrAsmList,onlabel);
+            marker:=tai_marker.create(mark_TryExceptStart,onlabel);
+            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
+            marker.ExceptDef:=tonnode(hnode).excepttype;
+            current_asmdata.CurrAsmList.Concat(marker);
             secondpass(hnode);
+            current_asmdata.getjumplabel(marklabel);
+            cg.a_label(current_asmdata.CurrAsmList,marklabel);
+            marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
+            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
+            marker.ExceptDef:=tonnode(hnode).excepttype;
+            current_asmdata.CurrAsmList.Concat(marker);
             inc(onnodecount.value);
             hnode:=tonnode(hnode).left;
           end;
@@ -472,7 +494,11 @@ procedure tx64tryexceptnode.pass_generate_code;
       begin
         { here we don't have to reset flowcontrol           }
         { the default and on flowcontrols are handled equal }
+        current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryExceptStart,lastonlabel));
         secondpass(t1);
+        current_asmdata.getjumplabel(marklabel);
+        cg.a_label(current_asmdata.CurrAsmList,marklabel);
+        current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryExceptEnd,marklabel));
         cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
         if (flowcontrol*[fc_exit,fc_break,fc_continue]<>[]) then
           cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);

Cyrax

2019-10-26 23:04

reporter   ~0118863

Last edited: 2019-10-26 23:06

View 2 revisions

After applying the patch, I get this error during build process:

/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/ppc1 -Ur -XX -CX -Ur -Xs -O2 -n -Fi../inc -Fi../i386 -Fi../unix -Fii386 -FE. -FU/mnt/shares/ohjelmointi2/fpc/source/git_source/rtl/units/i386-linux -gw2 -godwarfsets -godwarfmethodclassprefix -gl -O- -Xs- -Si- -vbq -Sew- -XX- -CX- -dEXTDEBUG -vh- -vn- -vw- -dDEBUG_NODE_XML -Fl/lib -Fl/usr/lib -Fl/usr/lib/gcc/i686-pc-linux-gnu/9.2.0 -dTEST_WIN32_SEH -Cit -gt -gv -Cg -di386 -dRELEASE  -Us -Sg system.pp
/mnt/shares/ohjelmointi2/fpc/source/git_source/rtl/linux/system.pp(663,1) Fatal: Internal error 2019102211
  $0833BAB1
  $0817FA3D
  $0833FADC
  $08299753
  $08299093
  $08192FA2
  $0807E3C6
  $080493B9
  $F7D57F29
Fatal: (1018) Compilation aborted
make[7]: *** [Makefile:3943: system.ppu] Error 1
make[7]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/rtl/linux'
make[6]: *** [Makefile:2067: linux_all] Error 2
make[6]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/rtl'
make[5]: *** [Makefile:4688: rtl] Error 2
make[5]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[4]: *** [Makefile:4530: next] Error 2
make[4]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[3]: *** [Makefile:4540: ppc2] Error 2
make[3]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[2]: *** [Makefile:4552: cycle] Error 2
make[2]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[1]: *** [Makefile:2853: compiler_cycle] Error 2
make[1]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source'
make: *** [Makefile:2885: build-stamp.i386-linux] Error 2


EDIT : FPC trunk r43312

Sven Barth

2019-10-28 23:09

manager   ~0118899

Updated patch. Please try again.

dwarf-except-debuginfo-2.patch (32,749 bytes)
diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas
index 7d662323..2c816211 100644
--- a/compiler/aasmtai.pas
+++ b/compiler/aasmtai.pas
@@ -351,8 +351,12 @@ interface
       TAsmMarker = (
         mark_NoPropInfoStart,mark_NoPropInfoEnd,
         mark_AsmBlockStart,mark_AsmBlockEnd,
-        mark_NoLineInfoStart,mark_NoLineInfoEnd,mark_BlockStart,
-        mark_Position
+        mark_NoLineInfoStart,mark_NoLineInfoEnd,
+        mark_TryBlockStart,mark_TryBlockEnd,
+        mark_TryFinallyStart,mark_TryFinallyEnd,
+        mark_TryExceptStart,mark_TryExceptEnd,
+        mark_Raise,
+        mark_BlockStart,mark_Position
       );
 
       TRegAllocType = (ra_alloc,ra_dealloc,ra_sync,ra_resize,ra_markused);
@@ -789,9 +793,16 @@ interface
        { Insert a marker for assembler and inline blocks }
        tai_marker = class(tai)
           Kind: TAsmMarker;
+          AsmLbl : TAsmSymbol;
+          ExceptVar : tsymstr;
+          ExceptDef : tdef;
+          ExceptDefDeref : tderef;
           Constructor Create(_Kind: TAsmMarker);
+          constructor Create(_kind:tasmmarker;_asmlbl:tasmsymbol);
           constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
+          procedure derefimpl; override;
+          procedure buildderefimpl; override;
        end;
 
        tai_tempalloc = class(tai)
@@ -2545,7 +2556,7 @@ implementation
                              Tai_Marker
  ****************************************************************************}
 
-    constructor Tai_Marker.Create(_Kind: TAsmMarker);
+    constructor tai_marker.Create(_Kind: TAsmMarker);
       begin
         Inherited Create;
         typ := ait_marker;
@@ -2553,17 +2564,54 @@ implementation
       end;
 
 
-    constructor Tai_Marker.ppuload(t:taitype;ppufile:tcompilerppufile);
+    constructor tai_marker.Create(_kind: tasmmarker; _asmlbl: tasmsymbol);
+      begin
+        Inherited Create;
+        typ:=ait_marker;
+        Kind:=_kind;
+        AsmLbl:=_asmlbl;
+      end;
+
+
+    constructor tai_marker.ppuload(t: taitype; ppufile: tcompilerppufile);
       begin
         inherited ppuload(t,ppufile);
         kind:=TAsmMarker(ppufile.getbyte);
+        AsmLbl:=ppufile.getasmsymbol;
+        ppufile.getderef(ExceptDefDeref);
+{$ifdef symansistr}
+        ExceptVar:=ppufile.getansistring
+{$else symansistr}
+        ExceptVar:=ppufile.getstring;
+{$endif symansistr}
       end;
 
 
-    procedure Tai_Marker.ppuwrite(ppufile:tcompilerppufile);
+    procedure tai_marker.ppuwrite(ppufile: tcompilerppufile);
       begin
         inherited ppuwrite(ppufile);
         ppufile.putbyte(byte(kind));
+        ppufile.putasmsymbol(AsmLbl);
+        ppufile.putderef(ExceptDefDeref);
+{$ifdef symansistr}
+        ppufile.putansistring(ExceptVar);
+{$else symansistr}
+        ppufile.putstring(ExceptVar);
+{$endif symansistr}
+      end;
+
+
+    procedure tai_marker.derefimpl;
+      begin
+        ExceptDef:=tdef(ExceptDefDeref.resolve);
+        inherited derefimpl;
+      end;
+
+
+    procedure tai_marker.buildderefimpl;
+      begin
+        ExceptDefDeref.build(ExceptDef);
+        inherited buildderefimpl;
       end;
 
 
diff --git a/compiler/dbgdwarf.pas b/compiler/dbgdwarf.pas
index 4bc522dd..512b2009 100644
--- a/compiler/dbgdwarf.pas
+++ b/compiler/dbgdwarf.pas
@@ -2277,6 +2277,57 @@ implementation
           end
         end;
 
+      type
+        tblockkind = (bk_try, bk_finally, bk_except);
+
+        texceptinfo = record
+          exceptvar : TSymStr;
+          exceptdef : tdef;
+          exceptstart : tasmsymbol;
+          exceptend : tasmsymbol;
+        end;
+
+        ttrycatchblock = record
+          kind : tblockkind;
+          trystart,
+          tryend: tasmsymbol;
+          finallystart,
+          finallyend: tasmsymbol;
+          excepts : array of texceptinfo;
+        end;
+        ptrycatchblock = ^ttrycatchblock;
+
+      var
+        trycatchblocks_wip,
+        trycatchblocks_done : tfplist;
+
+
+      procedure maybe_finish_tryexcept;
+        var
+          trycatchblock : ptrycatchblock;
+        begin
+          if trycatchblocks_wip.count>0 then
+            begin
+              { if we have an except block with filled endlabels
+                then we can finish that block }
+              trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+              if (trycatchblock^.kind=bk_try) and assigned(trycatchblock^.tryend) then
+                internalerror(2019102205)
+              else if (trycatchblock^.kind=bk_finally) and assigned(trycatchblock^.finallyend) then
+                internalerror(2019102206)
+              else if trycatchblock^.kind=bk_except then
+                begin
+                  if not assigned(trycatchblock^.excepts) then
+                    internalerror(2019102207);
+                  if assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
+                    begin
+                      trycatchblocks_wip.extract(trycatchblock);
+                      trycatchblocks_done.add(trycatchblock);
+                    end;
+                end;
+            end;
+        end;
+
       var
         procendlabel   : tasmlabel;
         procentry,s    : string;
@@ -2284,6 +2335,9 @@ implementation
         st             : tsymtable;
         vmtoffset      : pint;
         in_currentunit : boolean;
+        ai : tai;
+        trycatchblock : ptrycatchblock;
+        i,j : sizeint;
       begin
         { only write debug info for procedures defined in the current module,
           except in case of methods (gcc-compatible)
@@ -2438,6 +2492,8 @@ implementation
         }
         finish_entry;
 
+        current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('ParaSyms')));
+
         if assigned(def.parast) then
           begin
             { First insert self, because gdb uses the fact whether or not the
@@ -2452,14 +2508,17 @@ implementation
           end;
         { local type defs and vars should not be written
           inside the main proc }
+          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('LocalSyms')));
         if in_currentunit and
            assigned(def.localst) and
            (def.localst.symtabletype=localsymtable) then
           write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],def.localst);
 
+          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('ParaDefs')));
         { last write the types from this procdef }
         if assigned(def.parast) then
           write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.parast);
+          current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('LocalDefs')));
         { only try to write the localst if the routine is implemented here }
         if in_currentunit and
            assigned(def.localst) and
@@ -2472,6 +2531,169 @@ implementation
             // write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],def.localst);
           end;
 
+        { we don't know how the C++ compatible exception blocks are done, so we
+          only generate this for Pascal DWARF }
+        if in_currentunit and not (ds_dwarf_cpp in current_settings.debugswitches) then
+          begin
+            trycatchblocks_wip:=tfplist.create;
+            trycatchblocks_done:=tfplist.create;
+            ai:=def.procstarttai;
+            while assigned(ai) and (ai<>def.procendtai) do
+              begin
+                if ai.typ=ait_marker then
+                  begin
+                    case tai_marker(ai).Kind of
+                      mark_TryBlockStart:
+                        begin
+                          maybe_finish_tryexcept;
+                          new(trycatchblock);
+                          trycatchblock^.kind:=bk_try;
+                          trycatchblock^.trystart:=tai_marker(ai).AsmLbl;
+                          trycatchblock^.tryend:=nil;
+                          trycatchblock^.finallystart:=nil;
+                          trycatchblock^.finallyend:=nil;
+                          trycatchblocks_wip.Add(trycatchblock);
+                        end;
+                      mark_TryBlockEnd:
+                        begin
+                          maybe_finish_tryexcept;
+                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_try) then
+                            internalerror(2019102101);
+                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                          trycatchblock^.tryend:=tai_marker(ai).AsmLbl;
+                        end;
+                      mark_TryFinallyStart:
+                        begin
+                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_try) then
+                            internalerror(2019102202);
+                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                          trycatchblock^.kind:=bk_finally;
+                          trycatchblock^.finallystart:=tai_marker(ai).AsmLbl;
+                        end;
+                      mark_TryFinallyEnd:
+                        begin
+                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_finally) then
+                            internalerror(2019102203);
+                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                          trycatchblock^.finallyend:=tai_marker(ai).AsmLbl;
+                          { we can't have any other block once we got a finally,
+                            so the whole thing is finished }
+                          trycatchblocks_wip.extract(trycatchblock);
+                          trycatchblocks_done.add(trycatchblock);
+                        end;
+                      mark_TryExceptStart:
+                        begin
+                          if (trycatchblocks_wip.count=0) or not (ptrycatchblock(trycatchblocks_wip.last)^.kind in [bk_try,bk_except]) then
+                            internalerror(2019102204);
+                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                          trycatchblock^.kind:=bk_except;
+                          if assigned(trycatchblock^.excepts) and not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
+                            internalerror(2019102208);
+                          setlength(trycatchblock^.excepts,Length(trycatchblock^.excepts)+1);
+                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptstart:=tai_marker(ai).AsmLbl;
+                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptvar:=tai_marker(ai).ExceptVar;
+                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptdef:=tai_marker(ai).ExceptDef;
+                        end;
+                      mark_TryExceptEnd:
+                        begin
+                          if (trycatchblocks_wip.count=0) or (ptrycatchblock(trycatchblocks_wip.last)^.kind<>bk_except) then
+                            internalerror(2019102209);
+                          trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                          if not assigned(trycatchblock^.excepts) or assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
+                            internalerror(2019102210);
+                          trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend:=tai_marker(ai).AsmLbl;
+                        end;
+                      else
+                        { we ignore all other marks }
+                        ;
+                    end;
+                  end;
+                ai:=tai(ai.next);
+              end;
+
+            while trycatchblocks_wip.count>0 do
+              begin
+                { the WIP list should only contain except blocks now }
+                trycatchblock:=ptrycatchblock(trycatchblocks_wip.last);
+                if trycatchblock^.kind in [bk_try,bk_finally] then
+                  internalerror(2019102211);
+                if not assigned(trycatchblock^.excepts) or
+                    not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptstart) or
+                    not assigned(trycatchblock^.excepts[High(trycatchblock^.excepts)].exceptend) then
+                  internalerror(2019102212);
+                trycatchblocks_wip.extract(trycatchblock);
+                trycatchblocks_done.add(trycatchblock);
+              end;
+
+            trycatchblocks_wip.free;
+
+            for i:=0 to trycatchblocks_done.count-1 do
+              begin
+                trycatchblock:=ptrycatchblock(trycatchblocks_done[i]);
+
+                { the try block }
+
+                if trycatchblock^.kind=bk_finally then
+                  current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Try Finally Block')))
+                else
+                  current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Try Except Block')));
+
+                append_entry(DW_TAG_try_block,false,[]);
+
+                append_labelentry(DW_AT_low_pc,trycatchblock^.trystart);
+                append_labelentry(DW_AT_high_pc,trycatchblock^.tryend);
+
+                finish_entry;
+
+                case trycatchblock^.kind of
+                  bk_try:
+                    internalerror(2019102213);
+                  bk_finally:
+                    begin
+                      { DWARF does not specifically specify a finally block,
+                        so we use a catch block without any parameter... }
+                      append_entry(DW_TAG_catch_block,false,[]);
+
+                      append_labelentry(DW_AT_low_pc,trycatchblock^.finallystart);
+                      append_labelentry(DW_AT_high_pc,trycatchblock^.finallyend);
+
+                      finish_entry;
+                    end;
+                  bk_except:
+                    begin
+                      for j:=0 to high(trycatchblock^.excepts) do
+                        begin
+                          append_entry(DW_TAG_catch_block,true,[]);
+
+                          append_labelentry(DW_AT_low_pc,trycatchblock^.excepts[j].exceptstart);
+                          append_labelentry(DW_AT_high_pc,trycatchblock^.excepts[j].exceptend);
+
+                          finish_entry;
+
+                          if assigned(trycatchblock^.excepts[j].exceptdef) then
+                            begin
+                              append_entry(DW_TAG_formal_parameter,false,[
+                                DW_AT_name,DW_FORM_string,trycatchblock^.excepts[j].exceptvar+#0
+                              ]);
+                              append_labelentry_ref(DW_AT_type,def_dwarf_lab(trycatchblock^.excepts[j].exceptdef));
+                              finish_entry;
+                            end
+                          else
+                            begin
+                              append_entry(DW_TAG_unspecified_parameters,false,[]);
+                              finish_entry;
+                            end;
+
+                          finish_children;
+                        end;
+                    end;
+                end;
+
+                dispose(trycatchblock);
+              end;
+            trycatchblocks_done.free;
+          end;
+
         finish_children;
       end;
 
diff --git a/compiler/i386/n386flw.pas b/compiler/i386/n386flw.pas
index ab3c1921..69a75ba2 100644
--- a/compiler/i386/n386flw.pas
+++ b/compiler/i386/n386flw.pas
@@ -272,6 +272,7 @@ procedure emit_scope_end;
 
 procedure ti386tryfinallynode.pass_generate_code;
   var
+    marklabel,
     finallylabel,
     exceptlabel,
     safecalllabel,
@@ -352,6 +353,10 @@ procedure ti386tryfinallynode.pass_generate_code;
         current_asmdata.RefAsmSymbol(finalizepi.procdef.mangledname,AT_FUNCTION)
       );
 
+    current_asmdata.getlabel(marklabel,alt_addr);
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
+    cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
     { try code }
     if assigned(left) then
       begin
@@ -361,6 +366,10 @@ procedure ti386tryfinallynode.pass_generate_code;
           exit;
       end;
 
+    current_asmdata.getlabel(marklabel,alt_addr);
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
+    cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
     { don't generate line info for internal cleanup }
     current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
 
@@ -391,6 +400,9 @@ procedure ti386tryfinallynode.pass_generate_code;
     { right is a call to finalizer procedure }
     secondpass(right);
 
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,finallylabel));
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,endfinallylabel));
+
     { goto is allowed if it stays inside the finally block,
       this is checked using the exception block number }
     if (flowcontrol-[fc_gotolabel])<>[fc_inflowcontrol] then
@@ -445,6 +457,7 @@ procedure ti386tryfinallynode.pass_generate_code;
 
 procedure ti386tryexceptnode.pass_generate_code;
   var
+    marklabel,
     exceptlabel,oldendexceptlabel,
     lastonlabel,
     exitexceptlabel,
@@ -463,6 +476,7 @@ procedure ti386tryexceptnode.pass_generate_code;
     hnode : tnode;
     hlist : tasmlist;
     onnodecount : tai_const;
+    marker : tai_marker;
   label
     errorexit;
   begin
@@ -536,11 +550,19 @@ procedure ti386tryexceptnode.pass_generate_code;
         current_procinfo.CurrBreakLabel:=breaktrylabel;
       end;
 
+    current_asmdata.getlabel(marklabel,alt_addr);
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
+    cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
     secondpass(left);
     tryflowcontrol:=flowcontrol;
     if codegenerror then
       goto errorexit;
 
+    current_asmdata.getlabel(marklabel,alt_addr);
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
+    cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
     emit_scope_end;
     { jump over except handlers }
     cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
@@ -596,7 +618,21 @@ procedure ti386tryexceptnode.pass_generate_code;
             hlist.concat(tai_const.create_sym(current_asmdata.RefAsmSymbol(tonnode(hnode).excepttype.vmt_mangledname,AT_DATA)));
             hlist.concat(tai_const.create_sym(onlabel));
             cg.a_label(current_asmdata.CurrAsmList,onlabel);
+
+            marker:=tai_marker.create(mark_TryExceptStart,onlabel);
+            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
+            marker.ExceptDef:=tonnode(hnode).excepttype;
+            current_asmdata.CurrAsmList.concat(marker);
+
             secondpass(hnode);
+
+            current_asmdata.getlabel(marklabel,alt_addr);
+            marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
+            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
+            marker.ExceptDef:=tonnode(hnode).excepttype;
+            current_asmdata.CurrAsmList.concat(marker);
+            cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
             inc(onnodecount.value);
             hnode:=tonnode(hnode).left;
           end;
@@ -617,7 +653,16 @@ procedure ti386tryexceptnode.pass_generate_code;
       begin
         { here we don't have to reset flowcontrol           }
         { the default and on flowcontrols are handled equal }
+        current_asmdata.getlabel(marklabel,alt_addr);
+        current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptStart,marklabel));
+        cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
         secondpass(t1);
+
+        current_asmdata.getlabel(marklabel,alt_addr);
+        current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptEnd,marklabel));
+        cg.a_label(current_asmdata.CurrAsmList,marklabel);
+
         cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
         if (flowcontrol*[fc_exit,fc_break,fc_continue]<>[]) then
           cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas
index a16abcae..706da4fc 100644
--- a/compiler/ncgflw.pas
+++ b/compiler/ncgflw.pas
@@ -545,6 +545,7 @@ implementation
     procedure tcgtryexceptnode.pass_generate_code;
 
       var
+         marklabel,
          oldendexceptlabel,
          lastonlabel,
          exitexceptlabel,
@@ -609,10 +610,18 @@ implementation
             current_procinfo.CurrBreakLabel:=breaktrylabel;
           end;
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          secondpass(left);
          if codegenerror then
            goto errorexit;
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          { don't generate line info for internal cleanup }
          current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
 
@@ -675,8 +684,16 @@ implementation
                  { except block needs line info }
                  current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
 
+                 current_asmdata.getlabel(marklabel,alt_addr);
+                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptStart,marklabel));
+                 hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
                  secondpass(t1);
 
+                 current_asmdata.getlabel(marklabel,alt_addr);
+                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptEnd,marklabel));
+                 hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
                  cexceptionstatehandler.handle_nested_exception(current_asmdata.CurrAsmList,destroytemps,doobjectdestroyandreraisestate);
 
                  cexceptionstatehandler.unget_exception_temps(current_asmdata.CurrAsmList,destroytemps);
@@ -685,6 +702,10 @@ implementation
                end
              else
                begin
+                 current_asmdata.getlabel(marklabel,alt_addr);
+                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptStart,marklabel));
+                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryExceptEnd,marklabel));
+                 hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
                  doobjectdestroyandreraisestate.newflowcontrol:=afteronflowcontrol;
                  cexceptionstatehandler.cleanupobjectstack(current_asmdata.CurrAsmList);
                  cexceptionstatehandler.catch_all_end(current_asmdata.CurrAsmList);
@@ -741,6 +762,7 @@ implementation
 
     procedure tcgonnode.pass_generate_code;
       var
+         marklabel,
          nextonlabel,
          exitonlabel,
          continueonlabel,
@@ -753,6 +775,7 @@ implementation
          exceptvarsym : tlocalvarsym;
          exceptlocdef: tdef;
          exceptlocreg: tregister;
+         marker : tai_marker;
       begin
          location_reset(location,LOC_VOID,OS_NO);
          oldCurrExitLabel:=nil;
@@ -799,7 +822,21 @@ implementation
                  current_procinfo.CurrBreakLabel:=breakonlabel;
                end;
 
+              current_asmdata.getlabel(marklabel,alt_addr);
+              marker:=tai_marker.create(mark_TryExceptStart,marklabel);
+              marker.ExceptVar:=exceptvar.name;
+              marker.ExceptDef:=excepttype;
+              current_asmdata.CurrAsmList.concat(marker);
+              hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
               secondpass(right);
+
+              current_asmdata.getlabel(marklabel,alt_addr);
+              marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
+              marker.ExceptVar:=exceptvar.name;
+              marker.ExceptDef:=excepttype;
+              current_asmdata.CurrAsmList.concat(marker);
+              hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
            end;
 
          cexceptionstatehandler.handle_nested_exception(current_asmdata.CurrAsmList,excepttemps,doobjectdestroyandreraisestate);
@@ -906,6 +943,7 @@ implementation
 
     procedure tcgtryfinallynode.pass_generate_code;
       var
+         marklabel,
          endfinallylabel,
          exitfinallylabel,
          continuefinallylabel,
@@ -976,6 +1014,10 @@ implementation
             current_procinfo.CurrBreakLabel:=breakfinallylabel;
           end;
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          { try code }
          if assigned(left) then
            begin
@@ -984,6 +1026,10 @@ implementation
                 exit;
            end;
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          { don't generate line info for internal cleanup }
          current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
 
@@ -1022,6 +1068,10 @@ implementation
          { end cleanup }
          current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          { finally code (don't unconditionally set fc_inflowcontrol, since the
            finally code is unconditionally executed; we do have to filter out
            flags regarding break/contrinue/etc. because we have to give an
@@ -1035,6 +1085,10 @@ implementation
          if codegenerror then
            exit;
 
+         current_asmdata.getlabel(marklabel,alt_addr);
+         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,marklabel));
+         hlcg.a_label(current_asmdata.CurrAsmList,marklabel);
+
          { don't generate line info for internal cleanup }
          current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
 
diff --git a/compiler/nflw.pas b/compiler/nflw.pas
index 2d85b997..5a01c086 100644
--- a/compiler/nflw.pas
+++ b/compiler/nflw.pas
@@ -254,6 +254,7 @@ interface
           function pass_1 : tnode;override;
           function dogetcopy : tnode;override;
           function docompare(p: tnode): boolean; override;
+          function exceptvar:tsym;
        end;
        tonnodeclass = class of tonnode;
 
@@ -2600,4 +2601,12 @@ implementation
         docompare := false;
       end;
 
+
+    function tonnode.exceptvar:tsym;
+      begin
+        if exceptsymtable.symlist.count<>1 then
+          internalerror(2019102401);
+        result:=tsym(exceptsymtable.symlist[0]);
+      end;
+
 end.
diff --git a/compiler/x86_64/nx64flw.pas b/compiler/x86_64/nx64flw.pas
index b391d359..f889e3f0 100644
--- a/compiler/x86_64/nx64flw.pas
+++ b/compiler/x86_64/nx64flw.pas
@@ -276,6 +276,7 @@ procedure tx64tryfinallynode.pass_generate_code;
 
     emit_nop;
     cg.a_label(current_asmdata.CurrAsmList,trylabel);
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockStart,trylabel));
 
     { try code }
     if assigned(left) then
@@ -321,6 +322,10 @@ procedure tx64tryfinallynode.pass_generate_code;
         cg.a_label(current_asmdata.CurrAsmList,endtrylabel);
       end;
 
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryBlockEnd,endtrylabel));
+
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyStart,finallylabel));
+
     flowcontrol:=[fc_inflowcontrol];
     { generate finally code as a separate procedure }
     if not implicitframe then
@@ -337,6 +342,8 @@ procedure tx64tryfinallynode.pass_generate_code;
 
     cg.a_label(current_asmdata.CurrAsmList,endfinallylabel);
 
+    current_asmdata.CurrAsmList.concat(tai_marker.create(mark_TryFinallyEnd,endfinallylabel));
+
     { generate the scope record in .xdata }
     tcpuprocinfo(current_procinfo).add_finally_scope(trylabel,endtrylabel,
       current_asmdata.RefAsmSymbol(finalizepi.procdef.mangledname,AT_FUNCTION),catch_frame);
@@ -359,6 +366,7 @@ procedure tx64tryexceptnode.pass_generate_code;
     oldCurrExitLabel,
     oldContinueLabel,
     oldBreakLabel : tasmlabel;
+    marklabel,
     onlabel,
     filterlabel: tasmlabel;
     oldflowcontrol,tryflowcontrol,
@@ -366,6 +374,7 @@ procedure tx64tryexceptnode.pass_generate_code;
     hnode : tnode;
     hlist : tasmlist;
     onnodecount : tai_const;
+    marker : tai_marker;
   label
     errorexit;
   begin
@@ -407,6 +416,7 @@ procedure tx64tryexceptnode.pass_generate_code;
     current_asmdata.getjumplabel(trylabel);
     emit_nop;
     cg.a_label(current_asmdata.CurrAsmList,trylabel);
+    current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryBlockStart,trylabel));
 
     { control flow in try block needs no special handling,
       just make sure that target labels are outside the scope }
@@ -421,6 +431,8 @@ procedure tx64tryexceptnode.pass_generate_code;
     { end of scope }
     cg.a_label(current_asmdata.CurrAsmList,exceptlabel);
 
+    current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryBlockEnd,exceptlabel));
+
     { set control flow labels for the except block }
     { and the on statements                        }
     current_procinfo.CurrExitLabel:=exitexceptlabel;
@@ -451,7 +463,17 @@ procedure tx64tryexceptnode.pass_generate_code;
             hlist.concat(tai_const.create_rva_sym(current_asmdata.RefAsmSymbol(tonnode(hnode).excepttype.vmt_mangledname,AT_DATA)));
             hlist.concat(tai_const.create_rva_sym(onlabel));
             cg.a_label(current_asmdata.CurrAsmList,onlabel);
+            marker:=tai_marker.create(mark_TryExceptStart,onlabel);
+            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
+            marker.ExceptDef:=tonnode(hnode).excepttype;
+            current_asmdata.CurrAsmList.Concat(marker);
             secondpass(hnode);
+            current_asmdata.getjumplabel(marklabel);
+            cg.a_label(current_asmdata.CurrAsmList,marklabel);
+            marker:=tai_marker.create(mark_TryExceptEnd,marklabel);
+            marker.ExceptVar:=tonnode(hnode).exceptvar.name;
+            marker.ExceptDef:=tonnode(hnode).excepttype;
+            current_asmdata.CurrAsmList.Concat(marker);
             inc(onnodecount.value);
             hnode:=tonnode(hnode).left;
           end;
@@ -472,7 +494,11 @@ procedure tx64tryexceptnode.pass_generate_code;
       begin
         { here we don't have to reset flowcontrol           }
         { the default and on flowcontrols are handled equal }
+        current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryExceptStart,lastonlabel));
         secondpass(t1);
+        current_asmdata.getjumplabel(marklabel);
+        cg.a_label(current_asmdata.CurrAsmList,marklabel);
+        current_asmdata.CurrAsmList.Concat(tai_marker.create(mark_TryExceptEnd,marklabel));
         cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
         if (flowcontrol*[fc_exit,fc_break,fc_continue]<>[]) then
           cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);

Cyrax

2019-10-29 04:17

reporter   ~0118903

FPC trunk r43323.

After applying the newest patch (dwarf-except-debuginfo-2.patch) , I get this :
make compiler
make[5]: Entering directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
/usr/bin/mkdir -p i386/units/i386-linux
/usr/bin/mkdir -p i386/bin/i386-linux
/usr/bin/echo "'43323'" > revision.inc
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/ppc1 -XX -CX -Ur -Xs -O2 -n -Fui386 -Fusystems -Fu/mnt/shares/ohjelmointi2/fpc/source/git_source/rtl/units/i386-linux -Fii386 -FEi386/bin/i386-linux -FUi386/units/i386-linux -dRELEASE -gw2 -godwarfsets -godwarfmethodclassprefix -gl -O- -Xs- -Si- -vbq -Sew- -XX- -CX- -dEXTDEBUG -vh- -vn- -vw- -dDEBUG_NODE_XML  -Fl/lib -Fl/usr/lib -Fl/usr/lib/gcc/i686-pc-linux-gnu/9.2.0 -dTEST_WIN32_SEH -Cit -gt -gv -Cg    -dREVINC -di386 -dGDB -dBROWSERLOG -Fux86 version.pas
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/ppc1 -XX -CX -Ur -Xs -O2 -n -Fui386 -Fusystems -Fu/mnt/shares/ohjelmointi2/fpc/source/git_source/rtl/units/i386-linux -Fii386 -FEi386/bin/i386-linux -FUi386/units/i386-linux -dRELEASE -gw2 -godwarfsets -godwarfmethodclassprefix -gl -O- -Xs- -Si- -vbq -Sew- -XX- -CX- -dEXTDEBUG -vh- -vn- -vw- -dDEBUG_NODE_XML  -Fl/lib -Fl/usr/lib -Fl/usr/lib/gcc/i686-pc-linux-gnu/9.2.0 -dTEST_WIN32_SEH -Cit -gt -gv -Cg    -dREVINC -di386 -dGDB -dBROWSERLOG -Fux86 pp.pas
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1151,14) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1060,57) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1060,57) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1060,58) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1071,47) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1071,47) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1071,48) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1080,73) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1081,21) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1086,16) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1086,73) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1086,37) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1091,106) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1099,61) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1100,62) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1103,54) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1109,48) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1110,26) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1113,47) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1168,30) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1184,30) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1188,35) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1202,26) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1233,83) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1295,29) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1296,49) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1372,32) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1367,7) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1437,34) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1432,9) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1492,21) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1546,24) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1570,21) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1570,21) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1570,25) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1569,13) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1572,21) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1572,17) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1583,77) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/./i386/cpupara.pas(789,34) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3799,6) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3801,41) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3809,9) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3815,26) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3866,40) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3866,40) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3891,6) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3901,33) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3904,9) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3913,26) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3949,16) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3957,44) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3958,44) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3959,34) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3959,35) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3961,34) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3961,62) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3961,73) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3962,51) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3963,39) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3963,67) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3963,75) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3964,51) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3967,42) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3967,70) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3967,76) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3968,51) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3972,6) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3986,3) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3992,27) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4001,46) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4008,34) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4019,19) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4020,40) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4023,55) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4024,13) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4025,75) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4030,12) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4032,57) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4032,57) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4033,53) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4035,47) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4050,33) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4050,33) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4053,64) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4053,64) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4053,64) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4055,66) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4055,66) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4055,66) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4059,73) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4059,66) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4059,73) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4061,75) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4061,68) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4061,75) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4066,6) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4085,81) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4085,98) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4087,54) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4093,50) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4400,3) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4410,3) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4555,123) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4572,58) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4570,5) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4611,23) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/compiler.pas(152,1) Fatal: Internal error 2019102210
  $0833B9E9
  $0817FA9D
  $0833FB7C
  $08299833
  $08299173
  $08193002
  $08185674
  $08297736
  $0829B5A3
  $0819304E
  $0807E3C6
  $080493B9
  $F7D86F29
Fatal: (1018) Compilation aborted
make[5]: *** [Makefile:4479: ppc386] Error 1
make[5]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[4]: *** [Makefile:4532: next] Error 2
make[4]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[3]: *** [Makefile:4540: ppc2] Error 2
make[3]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[2]: *** [Makefile:4552: cycle] Error 2
make[2]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[1]: *** [Makefile:2853: compiler_cycle] Error 2
make[1]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source'
make: *** [Makefile:2885: build-stamp.i386-linux] Error 2

Cyrax

2019-11-09 05:17

reporter   ~0119170

FPC trunk r43420.

make compiler
make[5]: Entering directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
/usr/bin/mkdir -p i386/units/i386-linux
/usr/bin/mkdir -p i386/bin/i386-linux
/usr/bin/echo "'43420'" > revision.inc
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/ppc1 -XX -CX -Ur -Xs -O2 -n -Fui386 -Fusystems -Fu/mnt/shares/ohjelmointi2/fpc/source/git_source/rtl/units/i386-linux -Fii386 -FEi386/bin/i386-linux -FUi386/units/i386-linux -dRELEASE -gw2 -godwarfsets -godwarfmethodclassprefix -gl -O- -Xs- -Si- -vbq -Sew- -XX- -CX- -dEXTDEBUG -vh- -vn- -vw- -dDEBUG_NODE_XML  -Fl/lib -Fl/usr/lib -Fl/usr/lib/gcc/i686-pc-linux-gnu/9.2.0 -dTEST_WIN32_SEH -Cit -gt -gv -Cg    -dREVINC -di386 -dGDB -dBROWSERLOG -Fux86 version.pas
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/ppc1 -XX -CX -Ur -Xs -O2 -n -Fui386 -Fusystems -Fu/mnt/shares/ohjelmointi2/fpc/source/git_source/rtl/units/i386-linux -Fii386 -FEi386/bin/i386-linux -FUi386/units/i386-linux -dRELEASE -gw2 -godwarfsets -godwarfmethodclassprefix -gl -O- -Xs- -Si- -vbq -Sew- -XX- -CX- -dEXTDEBUG -vh- -vn- -vw- -dDEBUG_NODE_XML  -Fl/lib -Fl/usr/lib -Fl/usr/lib/gcc/i686-pc-linux-gnu/9.2.0 -dTEST_WIN32_SEH -Cit -gt -gv -Cg    -dREVINC -di386 -dGDB -dBROWSERLOG -Fux86 pp.pas
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1151,14) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1060,57) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1060,57) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1060,58) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1071,47) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1071,47) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1071,48) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1080,73) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1081,21) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1086,16) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1086,73) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1086,37) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1091,106) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1099,61) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1100,62) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1103,54) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1109,48) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1110,26) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1113,47) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1168,30) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1184,30) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1188,35) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1202,26) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1233,83) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1295,29) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1296,49) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1372,32) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1367,7) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1437,34) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1432,9) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1492,21) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1546,24) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1570,21) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1570,21) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1570,25) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1569,13) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1572,21) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1572,17) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/cfileutl.pas(1583,77) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/./i386/cpupara.pas(789,34) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3792,6) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3794,41) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3802,9) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3808,26) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3859,40) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3859,40) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3884,6) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3894,33) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3897,9) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3906,26) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3942,16) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3950,44) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3951,44) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3952,34) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3952,35) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3954,34) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3954,62) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3954,73) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3955,51) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3956,39) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3956,67) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3956,75) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3957,51) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3960,42) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3960,70) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3960,76) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3961,51) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3965,6) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3979,3) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3985,27) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(3994,46) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4001,34) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4012,19) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4013,40) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4016,55) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4017,13) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4018,75) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4023,12) Warning: Expectloc is not set in firstpass: equaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4025,57) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4025,57) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4026,53) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4028,47) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4043,33) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4043,33) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4046,64) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4046,64) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4046,64) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4048,66) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4048,66) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4048,66) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4052,73) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4052,66) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4052,73) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4054,75) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4054,68) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4054,75) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4059,6) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4078,81) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4078,98) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4080,54) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4086,50) Warning: Expectloc is not set in firstpass: calln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4395,3) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4405,3) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4550,123) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4567,58) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4565,5) Warning: Expectloc is not set in firstpass: blockn
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/options.pas(4606,23) Warning: Expectloc is not set in firstpass: unequaln
/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler/compiler.pas(152,1) Fatal: Internal error 2019102210
  $08334395
  $0817F84D
  $08338503
  $08293F53
  $08293893
  $08192C86
  $08185434
  $08291E76
  $08295CBF
  $08192CD2
  $0807E386
  $080493B9
  $F7DB6F29
Fatal: (1018) Compilation aborted
make[5]: *** [Makefile:4478: ppc386] Error 1
make[5]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[4]: *** [Makefile:4531: next] Error 2
make[4]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[3]: *** [Makefile:4539: ppc2] Error 2
make[3]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[2]: *** [Makefile:4551: cycle] Error 2
make[2]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source/compiler'
make[1]: *** [Makefile:2853: compiler_cycle] Error 2
make[1]: Leaving directory '/mnt/shares/ohjelmointi2/fpc/source/git_source'
make: *** [Makefile:2885: build-stamp.i386-linux] Error 2

Issue History

Date Modified Username Field Change
2019-01-16 13:34 Martin Friebe New Issue
2019-01-16 13:41 Martin Friebe Relationship added related to 0034502
2019-10-25 22:19 Sven Barth File Added: dwarf-except-debuginfo.patch
2019-10-25 22:19 Sven Barth Note Added: 0118813
2019-10-25 22:20 Sven Barth Assigned To => Sven Barth
2019-10-25 22:20 Sven Barth Status new => feedback
2019-10-25 22:20 Sven Barth FPCTarget => -
2019-10-26 23:04 Cyrax Note Added: 0118863
2019-10-26 23:06 Cyrax Note Edited: 0118863 View Revisions
2019-10-28 23:09 Sven Barth File Added: dwarf-except-debuginfo-2.patch
2019-10-28 23:09 Sven Barth Note Added: 0118899
2019-10-29 04:17 Cyrax Note Added: 0118903
2019-11-09 05:17 Cyrax Note Added: 0119170