Stream: git-wasmtime

Topic: wasmtime / issue #3884 Debugging module with lldb shows l...


view this post on Zulip Wasmtime GitHub notifications bot (Mar 04 2022 at 23:27):

jeffcharles opened issue #3884:

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

Anything else you'd like to add?

view this post on Zulip Wasmtime GitHub notifications bot (Mar 04 2022 at 23:27):

jeffcharles labeled issue #3884:

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

Anything else you'd like to add?

view this post on Zulip Wasmtime GitHub notifications bot (Mar 04 2022 at 23:31):

jeffcharles edited issue #3884:

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

Anything else you'd like to add?

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

view this post on Zulip Wasmtime GitHub notifications bot (Mar 04 2022 at 23:34):

jeffcharles edited issue #3884:

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

view this post on Zulip Wasmtime GitHub notifications bot (Mar 04 2022 at 23:41):

cfallin commented on issue #3884:

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)?

view this post on Zulip Wasmtime GitHub notifications bot (Mar 07 2022 at 16:02):

alexcrichton labeled issue #3884:

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

view this post on Zulip Wasmtime GitHub notifications bot (Mar 08 2022 at 14:31):

yurydelendik commented on issue #3884:

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.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 14 2022 at 22:20):

ianks commented on issue #3884:

Getting the same issue on lldb 12.0.1

view this post on Zulip Wasmtime GitHub notifications bot (Oct 21 2022 at 07:28):

YoungWenMing commented on issue #3884:

Any updates about this issue?

view this post on Zulip Wasmtime GitHub notifications bot (Oct 21 2022 at 07:54):

bjorn3 commented on issue #3884:

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...

view this post on Zulip Wasmtime GitHub notifications bot (Aug 31 2023 at 17:39):

SingleAccretion commented on issue #3884:

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 +88)
                    DW_AT_name  ("simpleStruct")
                    DW_AT_type  (0x0011c72d "WasmDebugging_SimpleStruct")

0x0011c71b:       DW_TAG_variable
                    DW_AT_location  (DW_OP_fbreg +4, 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_d
[message truncated]

view this post on Zulip Wasmtime GitHub notifications bot (Aug 31 2023 at 17:40):

SingleAccretion edited a comment on issue #3884:

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 +88)
                    DW_AT_name  ("simpleStruct")
                    DW_AT_type  (0x0011c72d "WasmDebugging_SimpleStruct")

0x0011c71b:       DW_TAG_variable
                    DW_AT_location  (DW_OP_fbreg +4, 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,
[message truncated]

view this post on Zulip Wasmtime GitHub notifications bot (Aug 31 2023 at 17:41):

SingleAccretion edited a comment on issue #3884:

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 +9
[message truncated]

view this post on Zulip Wasmtime GitHub notifications bot (Aug 31 2023 at 22:04):

SingleAccretion commented on issue #3884:

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.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 05 2023 at 21:58):

alexcrichton closed issue #3884:

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


Last updated: Oct 23 2024 at 20:03 UTC