[PATCH] D74781: Wasm-ld emits invalid .debug_ranges entries for non-live symbols

David Blaikie via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 26 13:02:47 PDT 2020


dblaikie added a comment.

In D74781#1940564 <https://reviews.llvm.org/D74781#1940564>, @paolosev wrote:

> In D74781#1939787 <https://reviews.llvm.org/D74781#1939787>, @dblaikie wrote:
>
> > In D74781#1938336 <https://reviews.llvm.org/D74781#1938336>, @paolosev wrote:
> >
> > > @sbc100  Adding a test.
> > >
> > > @dblaikie Strangely, I can't find a way to generate a **.debug_loc** section for Wasm.
> >
> >
> > Maybe it's not applicable to wasm, I don't know much about it - but if it optimizes variables into registers (or out of them), then it shuold be producible.
> >
> > Here's a simple test case I use for debug_loc in C++ on a silicon target:
> >
> >   void f1();
> >   int main() {
> >     int i = 3;
> >     f1();
> >     i = 7;
> >     f1();
> >   }
> >
> >
> > Compiled with optimizations enabled, the storage for 'i' will be eliminated and a DWARF location list will be used to describe 'i' as having the value 3 over the first call instruction, and the value 7 over the second call instruction.
>
>
> Yes, I managed to get a .debug_loc section also for Wasm with similar code, and debug_loc does not seem to present the same problems with GC'd functions.


Even without your patch? If without your patch you were getting range list entries of zero/zero, I'd expect you to get debug_loc entries with zero/zero too. Any ideas why it doesn't? They should be a similar pair of relocations (though it looks like your fix should work for debug_loc too, which is good).

>    1 void f1(int& n) { n++; }
>    2
>    3 int f2(int& n) {
>    4   int i = 42;
>    5   f1(i);
>    6   i = 21;
>    7   f1(i);
>    8   return i;
>    9  }
>   10
>   11 extern "C" {
>   12 int _start() {
>   13   int i = 3;
>   14   f1(i);
>   15   i = 7;
>   16   f1(i);
>   17   return i;
>   18 }
>   19 }
> 
> 
> compiled with: `clang++ main.cc -o main.wasm --target=wasm32 -nostdlib -gfull -O1`, produce a module with this DWARF data:
> 
>   .debug_info contents:
>   [...]
>   0x0000000b: DW_TAG_compile_unit
>                 DW_AT_producer    ("clang version 11.0.0 (https://github.com/llvm/llvm-project.git f6cf848a2ccc6f63ebce27a52857c291a7ec4eec)")
>                 DW_AT_language    (DW_LANG_C_plus_plus_14)
>                 DW_AT_name        ("main.cc")
>                 DW_AT_stmt_list   (0x00000000)
>                 DW_AT_comp_dir    ("C:\\dev\\llvm-project\\release_x64\\T")
>                 DW_AT_low_pc      (0x0000000000000000)
>                 DW_AT_ranges      (0x00000000
>                    [0x00000002, 0x00000011)
>                    [0x00000000, 0x0000004d)
>                    [0x00000012, 0x0000005f))
>   
>   0x00000026:   DW_TAG_subprogram
>                   DW_AT_low_pc    (0x0000000000000002)
>                   DW_AT_high_pc   (0x0000000000000011)
>                   DW_AT_frame_base        (DW_OP_WASM_location 0x1 +0, DW_OP_stack_value)
>                   DW_AT_GNU_all_call_sites        (true)
>                   DW_AT_linkage_name      ("_Z2f1Ri")
>                   DW_AT_name      ("f1")
>                   DW_AT_decl_file ("C:\dev\llvm-project\release_x64\T\main.cc")
>                   DW_AT_decl_line (1)
>                   DW_AT_external  (true)
>   [...]
>   
>   0x0000004a:   DW_TAG_subprogram
>                   DW_AT_low_pc    (0x0000000000000000)
>                   DW_AT_high_pc   (0x000000000000004d)
>                   DW_AT_frame_base        (DW_OP_WASM_location 0x0 +1, DW_OP_stack_value)
>                   DW_AT_GNU_all_call_sites        (true)
>                   DW_AT_linkage_name      ("_Z2f2Ri")
>                   DW_AT_name      ("f2")
>                   DW_AT_decl_file ("C:\dev\llvm-project\release_x64\T\main.cc")
>                   DW_AT_decl_line (3)
>                   DW_AT_type      (0x000000cd "int")
>                   DW_AT_external  (true)
>   [...]
>   
>   0x00000071:     DW_TAG_variable
>                     DW_AT_location        (0x00000000:
>                        [0x00000014, 0x0000001b): DW_OP_consts +42, DW_OP_stack_value
>                        [0x00000026, 0x0000002d): DW_OP_consts +21, DW_OP_stack_value
>                        [0x0000003f, 0x0000004d): DW_OP_WASM_location 0x0 +2, DW_OP_stack_value)
>                     DW_AT_name    ("i")
>                     DW_AT_decl_file       ("C:\dev\llvm-project\release_x64\T\main.cc")
>                     DW_AT_decl_line       (4)
>                     DW_AT_type    (0x000000cd "int")
>   [...]
>   
>   0x00000093:   DW_TAG_subprogram
>                   DW_AT_low_pc    (0x0000000000000012)
>                   DW_AT_high_pc   (0x000000000000005f)
>                   DW_AT_frame_base        (DW_OP_WASM_location 0x0 +0, DW_OP_stack_value)
>                   DW_AT_GNU_all_call_sites        (true)
>                   DW_AT_name      ("_start")
>                   DW_AT_decl_file ("C:\dev\llvm-project\release_x64\T\main.cc")
>                   DW_AT_decl_line (12)
>                   DW_AT_type      (0x000000cd "int")
>                   DW_AT_external  (true)
>   
>   0x000000ab:     DW_TAG_variable
>                     DW_AT_location        (0x00000038:
>                        [0x00000026, 0x0000002d): DW_OP_consts +3, DW_OP_stack_value
>                        [0x00000038, 0x0000003f): DW_OP_consts +7, DW_OP_stack_value
>                        [0x00000051, 0x0000005f): DW_OP_WASM_location 0x0 +1, DW_OP_stack_value)
>                     DW_AT_name    ("i")
>                     DW_AT_decl_file       ("C:\dev\llvm-project\release_x64\T\main.cc")
>                     DW_AT_decl_line       (13)
>                     DW_AT_type    (0x000000cd "int")
>   [...]
>   
>   .debug_loc contents:
>   0x00000000:
>               [0x00000014, 0x0000001b): DW_OP_consts +42, DW_OP_stack_value
>               [0x00000026, 0x0000002d): DW_OP_consts +21, DW_OP_stack_value
>               [0x0000003f, 0x0000004d): DW_OP_WASM_location 0x0 +2, DW_OP_stack_value
>   
>   0x00000038:
>               [0x00000026, 0x0000002d): DW_OP_consts +3, DW_OP_stack_value
>               [0x00000038, 0x0000003f): DW_OP_consts +7, DW_OP_stack_value
>               [0x00000051, 0x0000005f): DW_OP_WASM_location 0x0 +1, DW_OP_stack_value
>   [...]
>   
>   .debug_line contents:
>   [...]
>   Address            Line   Column File   ISA Discriminator Flags
>   ------------------ ------ ------ ------ --- ------------- -------------
>   0x0000000000000002      1      0      1   0             0  is_stmt
>   0x0000000000000003      1     20      1   0             0  is_stmt prologue_end
>   0x0000000000000010      1     24      1   0             0
>   0x0000000000000011      1     24      1   0             0  end_sequence
>   0x0000000000000000      3      0      1   0             0  is_stmt
>   0x0000000000000014      4      7      1   0             0  is_stmt prologue_end
>   0x000000000000001b      5      3      1   0             0  is_stmt
>   0x0000000000000026      6      5      1   0             0  is_stmt
>   0x000000000000002d      7      3      1   0             0  is_stmt
>   0x0000000000000038      8     10      1   0             0  is_stmt
>   0x000000000000003f      8      3      1   0             0
>   0x000000000000004d      8      3      1   0             0  end_sequence
>   0x0000000000000012     12      0      1   0             0  is_stmt
>   0x0000000000000026     13      7      1   0             0  is_stmt prologue_end
>   0x000000000000002d     14      3      1   0             0  is_stmt
>   0x0000000000000038     15      5      1   0             0  is_stmt
>   0x000000000000003f     16      3      1   0             0  is_stmt
>   0x000000000000004a     17     10      1   0             0  is_stmt
>   0x0000000000000051     17      3      1   0             0
>   0x000000000000005f     17      3      1   0             0  end_sequence
>   [...]
>   
>   .debug_ranges contents:
>   00000000 00000002 00000011
>   00000000 00000000 0000004d
>   00000000 00000012 0000005f
>   00000000 <End of list>
> 
> 
> Function `f2` is not used and removed by the linker. Now .debug_ranges is correct: there is a line 
>  00000000 00000000 0000004d
>  which at least it's not interpreted as a terminator.
> 
> However, in the generated DWARF there is also useless/invalid information for f2 also in all the sections, with invalid code offsets.
>  I suspect that the presence of this data for removed functions could still break debuggers, which don't expect overlapping ranges.
>  It is also an useless waste of space. Would it be difficult to avoid generating DWARF data at all for GC'd functions?

Yes, it's difficult for "Classic" targets like ELF/COFF/etc - the linker isn't DWARF aware (except for a couple of special cases like this relocation application - and in fact binutils ld does a different workaround for debug_ranges (it resolves all of them to 1 for dropped code, so you get a 1/1 entry rather than a 0/0 entry or a 0/N entry (like gold/lld)) & doesn't have a fix for debug_loc, which isn't exactly a problem except for DWARF dumping tools) & it's unclear that DWARF-aware linking is going to be worthwhile - it means linking probably using a lot more memory and processing time to reconstruct a bunch of DWARF (you can't just rip out the DIEs - there are other offsets that would then be invalidated and have to be rewritten, etc).

There is work to add DWARF-aware linking based on Apple dsymutil implementation in LLVM, to lld for ELF DWARF linking - but yeah, unclear it'll be an absolute win in terms of performance - and in terms of correctness, debuggers have been having to live with this "ranges that start at zero are magic/represent dropped code" for a while now & if that was shown to be really unworkable from a correctness standpoint we'd probably want to consider some other magic value, rather than requiring full DWARF rewriting to get correctness.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D74781/new/

https://reviews.llvm.org/D74781





More information about the llvm-commits mailing list