wasmtime icon indicating copy to clipboard operation
wasmtime copied to clipboard

Debugging module with lldb shows local variables as not available

Open jeffcharles opened this issue 3 years ago • 5 comments
trafficstars

Test Case

test.wasm.zip

#include <stdio.h>

int main() {
    int i;
    for(i = 0; i < 5; i++) {
        printf("%d\n", i);
    }
    return 0;
}

compiled with: wasi-sdk-14.0/bin/clang -g -O0 test.c -o test.wasm

Steps to Reproduce

> lldb -- wasmtime run -g test.wasm                  
(lldb) target create "wasmtime"
Current executable set to 'wasmtime' (arm64).
(lldb) settings set -- target.run-args  "run" "-g" "test.wasm"
(lldb) settings set plugin.jit-loader.gdb.enable on
(lldb) b test.c:6
Breakpoint 1: no locations (pending).
WARNING:  Unable to resolve breakpoint to any actual locations.
(lldb) run
Process 40146 launched: '/Users/jeffcharles/.cargo/bin/wasmtime' (arm64)
1 location added to breakpoint 1
Process 40146 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100e940e0 JIT(0x1102b0000)`main at test.c:6:24
   3   	int main() {
   4   	    int i;
   5   	    for(i = 0; i < 5; i++) {
-> 6   	        printf("%d\n", i);
   7   	    }
   8   	    return 0;
   9   	}
Target 0: (wasmtime) stopped.
(lldb) fr v
(WasmtimeVMContext *) __vmctx = <variable not available>

(int) i = <no location, value may have been optimized out>

Expected Results

Running fr v in lldb in this context should display:

(int) i = 0

Actual Results

(int) i = <no location, value may have been optimized out>

Versions and Environment

Wasmtime version or commit: 0.34.0

Operating system: MacOS Monterrey (12.2.1)

Architecture: arm64

Extra Info

LLDB version:

> lldb --version
lldb-1300.0.42.3
Swift version 5.5.2-dev

This is what happens when I try to compile and run natively to show what I'm expecting:

> clang -g -O0 test.c -o test
> lldb -- test
(lldb) target create "test"
Current executable set to '/Users/jeffcharles/projects/wasm32-wasi/test-c-app/test' (arm64).
(lldb) b test.c:6
Breakpoint 1: where = test`main + 32 at test.c:6:24, address = 0x0000000100003f6c
(lldb) run
Process 40384 launched: '/Users/jeffcharles/projects/wasm32-wasi/test-c-app/test' (arm64)
Process 40384 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100003f6c test`main at test.c:6:24
   3   	int main() {
   4   	    int i;
   5   	    for(i = 0; i < 5; i++) {
-> 6   	        printf("%d\n", i);
   7   	    }
   8   	    return 0;
   9   	}
Target 0: (test) stopped.
(lldb) fr v
(int) i = 0

jeffcharles avatar Mar 04 '22 23:03 jeffcharles

It looks like the i variable is placed on the in-wasm-heap pseudostack by LLVM:

$ /opt/wasi-sdk/bin/llvm-dwarfdump test.wasm

    [ ... ]

0x0000003e:     DW_TAG_variable
                  DW_AT_location	(DW_OP_fbreg +8)
                  DW_AT_name	("i")
                  DW_AT_decl_file	("/Users/jeffcharles/projects/wasm32-wasi/test-c-app/test.c")
                  DW_AT_decl_line	(4)
                  DW_AT_type	(0x0000004d "int")

(fbreg is the frame-buffer "register".) I'm not sure how well-supported this is; I'm more familiar with the machinery that passes through debug locations for SSA values, which come from Wasm locals. @yurydelendik wrote the original DWARF expression translation code I think -- Yury, any thoughts on this (whether it is expected to work with the existing code, what it would take if not)?

cfallin avatar Mar 04 '22 23:03 cfallin

whether it is expected to work with the existing code, what it would take if not

Based on https://github.com/bytecodealliance/wasmtime/pull/842 it was supported at some time. Missing tests though because format was evolving on LLVM side.

yurydelendik avatar Mar 08 '22 14:03 yurydelendik

Getting the same issue on lldb 12.0.1

ianks avatar Jun 14 '22 22:06 ianks

Any updates about this issue?

YoungWenMing avatar Oct 21 '22 07:10 YoungWenMing

To quote @cfallin from https://github.com/bytecodealliance/wasmtime/issues/4669#issuecomment-1210997950 (which is another debuginfo issue):

We currently don't have anyone on the project who understands our DWARF-handling code well and has time to work on it; so while this is definitely a bug, it's not likely to have a fast resolution. We do have an intent to have someone eventually focus on this, as priorities allow, so we should keep this issue open. Just wanted to give some context on the current situation...

bjorn3 avatar Oct 21 '22 07:10 bjorn3

I have tried the simple C code above the issue and the issue no longer reproduces. However, I have a larger example (not yet in C/C++) that does show bad behavior with local variables.

We start with:

public static int Main()
{
    SimpleStruct simpleStruct = new() { IntField = 1, FloatField = 2.0f };
    SimpleClass simpleClass = new() { IntField = 1, FloatField = 2.0f };

    TestBasicTypesDisplay(true, false, 'a', 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 1.0f, 2.0);
    TestEnumDisplay(DayOfWeek.Monday);
    TestByRefDisplay(ref simpleStruct, ref simpleClass);
    TestPointerDisplay(&simpleStruct);
    TestStringDisplay("Basic string");
    TestBasicArrayDisplay(new int[] { 1, 2, 3 }, new double[] { 1, 2, 3 });
    TestComplexArrayDisplay(new[] { simpleClass }, new[] { simpleStruct });
    TestBasicMultiDimensionalArrayDisplay(new int[,] { { 1, 2, 3 }, { 4, 5, 6 } });
    TestSimpleStructDisplay(simpleStruct);
    TestSimpleClassDisplay(simpleClass);
    TestDerivedClassDisplay(new() { IntField = 1, FloatField = 2.0f, LongField = 3 });
    TestRecursiveClassDisplay(new() { Value = 1, Next = new() { Value = 2 } });

    simpleStruct.TestStructInstanceMethod();
    simpleClass.TestClassInstanceMethod();
    TestVariables(5, simpleStruct, simpleClass);

    return 100;
}

We have this DWARF for the generated WASM:

0x0011c6f2:     DW_TAG_subprogram
                  DW_AT_low_pc	(0x004d9992)
                  DW_AT_high_pc	(0x004daf32)
                  DW_AT_frame_base	(DW_OP_WASM_location 0x0 0x3, DW_OP_stack_value)
                  DW_AT_linkage_name	("WasmDebugging_Program__Main")
                  DW_AT_name	("Main")
                  DW_AT_decl_file	("C:\Users\Accretion\source\dotnet\runtimelab\src\tests\nativeaot\SmokeTests\HelloWasm\WasmDebugging.cs")
                  DW_AT_decl_line	(15)
                  DW_AT_type	(0x000000000010c1b2 "int")

0x0011c70e:       DW_TAG_variable
                    DW_AT_location	(DW_OP_fbreg +0x58)
                    DW_AT_name	("simpleStruct")
                    DW_AT_type	(0x0011c72d "WasmDebugging_SimpleStruct")

0x0011c71b:       DW_TAG_variable
                    DW_AT_location	(DW_OP_fbreg +0x4, DW_OP_deref, DW_OP_plus_uconst 0x0)
                    DW_AT_name	("simpleClass")
                    DW_AT_type	(0x0011c748 "WasmDebugging_SimpleClass &")

Pretty standard/expected.

I compiled this with -g -opt-level 0, and extracted the generated DWARF from the cached compressed ELF object (side note: it is huge, 350MB uncompressed, while the input is ~25MB, with the most output space taken up by debug info).

We get (with offsets for location lists for better legibility):

0x001446e5:     DW_TAG_subprogram
                  DW_AT_low_pc	(0x00000000005b1780)
                  DW_AT_high_pc	(0x00000000005b3200)
                  DW_AT_linkage_name	("WasmDebugging_Program__Main")
                  DW_AT_name	("Main")
                  DW_AT_decl_file	("C:\Users\Accretion\source\dotnet\runtimelab\src\tests\nativeaot\SmokeTests\HelloWasm\WasmDebugging.cs")
                  DW_AT_decl_line	(15)
                  DW_AT_type	(0x000000000012a78c "int")

0x001446fe:       DW_TAG_variable
                    DW_AT_name	("__vmctx")
                    DW_AT_type	(0x001446d6 "WasmtimeVMContext *")
                    DW_AT_location	(0x03785671: 
                       (+75, +722): DW_OP_reg5
                       (+722, +753): DW_OP_reg5
                       (+753, +953): DW_OP_reg14
                       (+955, +1062): DW_OP_reg14
                       (+1064, +1940): DW_OP_reg14
                       (+1942, +2804): DW_OP_reg14
                       (+2806, +3534): DW_OP_reg14
                       (+3536, +3614): DW_OP_reg14
                       (+3616, +4501): DW_OP_reg14
                       (+4503, +5296): DW_OP_reg14
                       (+5298, +5400): DW_OP_reg14
                       (+5402, +5512): DW_OP_reg14
                       (+5514, +5801): DW_OP_reg14
                       (+5803, +6028): DW_OP_reg14
                       (+6030, +6150): DW_OP_reg14
                       (+6158, +6399): DW_OP_reg14
                       (+6401, +6626): DW_OP_reg14
                       (+6678, +6696): DW_OP_reg14)

0x0014470b:       DW_TAG_variable
                    DW_AT_location	(0x037857d7: 
                       (+75, +90): DW_OP_breg10 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+90, +104): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+104, +116): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+116, +128): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+128, +140): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+140, +152): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+152, +164): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+164, +176): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+176, +188): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+188, +200): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+200, +212): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+212, +224): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+224, +236): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+236, +248): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+248, +260): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+260, +272): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+272, +284): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+284, +296): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+296, +308): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+308, +320): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+320, +332): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+332, +344): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+344, +356): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+356, +368): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+368, +380): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+380, +394): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+394, +406): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+406, +420): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+420, +432): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+432, +616): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+616, +628): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+628, +645): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+645, +663): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+663, +675): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+675, +687): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+687, +701): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+701, +715): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+715, +722): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+722, +735): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+1383, +1401): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+1443, +1453): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+3647, +3652): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+3659, +3666): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+3781, +3786): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+3799, +3804): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+3819, +3832): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+4932, +4937): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+4944, +4951): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+4958, +4965): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+4972, +4977): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+4981, +4991): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6261, +6271): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6459, +6464): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6471, +6478): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6485, +6492): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6499, +6504): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6532, +6542): DW_OP_breg0 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6593, +6598): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6610, +6615): DW_OP_breg9 +0, DW_OP_plus_uconst 0x58, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus)
                    DW_AT_name	("simpleStruct")
                    DW_AT_type	(0x00144727 "WasmDebugging_SimpleStruct")

0x00144718:       DW_TAG_variable
                    DW_AT_location	(0x03785fbd: 
                       (+75, +90): DW_OP_breg10 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+90, +104): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+104, +116): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+116, +128): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+128, +140): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+140, +152): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+152, +164): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+164, +176): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+176, +188): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+188, +200): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+200, +212): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+212, +224): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+224, +236): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+236, +248): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+248, +260): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+260, +272): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+272, +284): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+284, +296): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+296, +308): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+308, +320): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+320, +332): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+332, +344): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+344, +356): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+356, +368): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+368, +380): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+380, +394): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+394, +406): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+406, +420): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+420, +432): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+432, +616): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+616, +628): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+628, +645): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+645, +663): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+663, +675): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+675, +687): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+687, +701): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+701, +715): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+715, +722): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+722, +735): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg5 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+1383, +1401): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+1443, +1453): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+3647, +3652): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+3659, +3666): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+3781, +3786): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+3799, +3804): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+3819, +3832): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+4932, +4937): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+4944, +4951): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+4958, +4965): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+4972, +4977): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+4981, +4991): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6261, +6271): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6459, +6464): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6471, +6478): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6485, +6492): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6499, +6504): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6532, +6542): DW_OP_breg0 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6593, +6598): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus
                       (+6610, +6615): DW_OP_breg9 +0, DW_OP_plus_uconst 0x4, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_deref, DW_OP_plus_uconst 0x0, DW_OP_breg14 +928, DW_OP_deref, DW_OP_swap, DW_OP_const4u 0xffffffff, DW_OP_and, DW_OP_plus)
                    DW_AT_name	("simpleClass")
                    DW_AT_type	(0x00144742 "WebAssemblyRefWrapper<WasmDebugging_SimpleClass>")

Observations:

  1. There are a lot of opportunities for range coalescing.
  2. After a certain point (first call), the location ranges get very fragmented, with poor coverage overall. If I check the disassemly, I see that these ranges each cover at most two instructions that look to fetch the data from the underlying variable.

SingleAccretion avatar Aug 31 '23 17:08 SingleAccretion

I think I see what is going here quite clearly now. During DWARF translation, actual as-reported-by-the-code-generator live ranges of "value labels" (side note: quite the confusing name for what are actually simply WASM locals) are intersected with the ranges in the WASM DWARF. So for a composite DW_OP_fbreg-based expression like the above, availability of the final result is limited by the availability of all its constituent locals. Importantly, one of those locals, the WASM LLVM stack pointer, is not always available. This is presumably due to the limitation that only register locations are supported right now. This explains the sparce ranges: in the disassembly, they correspond to spots where the the LLVM stack pointer is reloaded from the native frame for temporary use.

SingleAccretion avatar Aug 31 '23 22:08 SingleAccretion