WebAssembly / binaryen

Optimizer and compiler/toolchain library for WebAssembly
Apache License 2.0
7.43k stars 736 forks source link

Impossible address ranges in DWARF debug info #6406

Open martiancatboy opened 6 months ago

martiancatboy commented 6 months ago

I've been working on a tool that parses DWARF debug info embedded in WebAssembly binaries. The files I'm examining are optimized for size using wasm-opt -Oz -g. I've run into an issue where the address ranges of inlined subroutines will occasionally be impossibly large. Specifically, I'll find a DW_TAG_inlined_subroutine entry with a reasonable DW_AT_low_pc paired with a DW_AT_high_pc with a value of precisely 0x100000000. (Needless to say, the subroutine in question is not actually four gigabytes large.)

I encountered the issue on a bigger codebase, but I've narrowed it down to this simple program that reproduces the issue:

static void increment(int* array, int length) {
    for (int i = 0; i < length; i++) {
        array[i]++;
    }
}

void _start(void) {
    int array[2] = {0, 0};
    increment(array, 2);
}

Compile and optimize like so:

$ clang bug.c -o bug.wasm -Oz -g --target=wasm32 -nostdlib
$ wasm-opt bug.wasm -o bug.wasm -Oz -g

The bug can be confirmed using llvm-dwarfdump:

$ llvm-dwarfdump bug.wasm --name increment
bug.wasm:   file format WASM

0x00000022: DW_TAG_subprogram
              DW_AT_name    ("increment")
              DW_AT_decl_file   ("bug.c")
              DW_AT_decl_line   (1)
              DW_AT_prototyped  (true)
              DW_AT_inline  (DW_INL_inlined)

0x0000007c: DW_TAG_inlined_subroutine
              DW_AT_abstract_origin (0x00000022 "increment")
              DW_AT_low_pc  (0x0000001a)
              DW_AT_high_pc (0x100000000)
              DW_AT_call_file   ("bug.c")
              DW_AT_call_line   (9)
              DW_AT_call_column (0x05)

I don't know the specific cause, but it only happens to code optimized by wasm-opt; clang's output is unaffected. It also only seems to affect DW_TAG_inlined_subroutine DIEs, from what I can tell.

kripken commented 6 months ago

Our DWARF support is not very robust at this time, so this is likely hitting some limitation there. In general I'd recommend using source maps for tracking debug info, as our support for that is very stable. However, if you or someone else is interested to investigate and fix issues like this, that would be welcome of course.