Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DWARF] Inheritance DW_TAGs dropped by GC #9828

Closed
SingleAccretion opened this issue Dec 15, 2024 · 0 comments · Fixed by #9829
Closed

[DWARF] Inheritance DW_TAGs dropped by GC #9828

SingleAccretion opened this issue Dec 15, 2024 · 0 comments · Fixed by #9829

Comments

@SingleAccretion
Copy link
Contributor

SingleAccretion commented Dec 15, 2024

Reproduction:
1) Compile the following C++ to WASM with -g:

struct Base { int BaseValue; };
struct Derived : public Base { int DerivedValue; };

int main()
{
    Derived x;
    x.BaseValue = 2;
    x.DerivedValue = 1;
    return 0;
}

2) Run under wasmtime+LLDB:

> lldb wasmtime -Ddebug-info -Oopt-level=0 main.wasm
> (lldb) b main
> (lldb) ...
> (lldb) v x.BaseValue

Expected result:

(int) x.BaseValue = 1

Actual result:

error: "BaseValue" is not a member of "(Derived) x"

Cause: DI GC drops correctness-bearing DW_TAG_inheritance DIEs.

Fix incoming...

@SingleAccretion SingleAccretion changed the title [DWARF] Inhertiance DW_TAGs dropped by GC [DWARF] Inheritance DW_TAGs dropped by GC Dec 15, 2024
SingleAccretion added a commit to SingleAccretion/runtimelab that referenced this issue Dec 16, 2024
So far, we have been emitting type definitions into each compile unit
where they were 'used'. This proved problematic (wrong) as the debugger
does not "unify" types across compile units - they are expected to be
the same, due to ODR.

To solve this fundamental issue, this change introduces a more elaborate
emission scheme, where during compilation only type forwards are emitted,
which will later get satisfied by types defined in one big DI module.

While the fundamental idea is sound, the implementation is constrained
by the lack of direct support for DW_FORM_ref_addr references in LLVM.
Ideally, we would use those to refer to types in the debug module directly,
however, in the absence of this, forward declarations have to do.

One problem with forward declarations that had to be worked around was
wasmtime's DI GC, which only resolves DWARF's 'reference's. Thus, our
types need manual 'rooting', which is accomplished in this change by
emitting a dummy retained subroutine that references all of them.

With these changes, as well as some fixes in wasmtime (especially
bytecodealliance/wasmtime#9828), the expanded
LLDB (finally) test passes.
SingleAccretion added a commit to SingleAccretion/runtimelab that referenced this issue Dec 16, 2024
So far, we have been emitting type definitions into each compile unit
where they were 'used'. This proved problematic (wrong) as the debugger
does not "unify" types across compile units - they are expected to be
the same, due to ODR.

To solve this fundamental issue, this change introduces a more elaborate
emission scheme, where during compilation only type forwards are emitted,
which will later get satisfied by types defined in one big DI module.

While the fundamental idea is sound, the implementation is constrained
by the lack of direct support for DW_FORM_ref_addr references in LLVM.
Ideally, we would use those to refer to types in the debug module directly,
however, in the absence of this, forward declarations have to do.

One problem with forward declarations that had to be worked around was
wasmtime's DI GC, which only resolves DWARF's 'reference's. Thus, our
types need manual 'rooting', which is accomplished in this change by
emitting a dummy retained subroutine that references all of them.

With these changes, as well as some fixes in wasmtime (especially
bytecodealliance/wasmtime#9828), the expanded
LLDB (finally) test passes.
SingleAccretion added a commit to SingleAccretion/runtimelab that referenced this issue Dec 16, 2024
So far, we have been emitting type definitions into each compile unit
where they were 'used'. This proved problematic (wrong) as the debugger
does not "unify" types across compile units - they are expected to be
the same, due to ODR.

To solve this fundamental issue, this change introduces a more elaborate
emission scheme, where during compilation only type forwards are emitted,
which will later get satisfied by types defined in one big DI module.

While the fundamental idea is sound, the implementation is constrained
by the lack of direct support for DW_FORM_ref_addr references in LLVM.
Ideally, we would use those to refer to types in the debug module directly,
however, in the absence of this, forward declarations have to do.

One problem with forward declarations that had to be worked around was
wasmtime's DI GC, which only resolves DWARF's 'reference's. Thus, our
types need manual 'rooting', which is accomplished in this change by
emitting a dummy retained subroutine that references all of them.

With these changes, as well as some fixes in wasmtime (especially
bytecodealliance/wasmtime#9828), the expanded
LLDB (finally) test passes.
SingleAccretion added a commit to SingleAccretion/runtimelab that referenced this issue Dec 17, 2024
So far, we have been emitting type definitions into each compile unit
where they were 'used'. This proved problematic (wrong) as the debugger
does not "unify" types across compile units - they are expected to be
the same, due to ODR.

To solve this fundamental issue, this change introduces a more elaborate
emission scheme, where during compilation only type forwards are emitted,
which will later get satisfied by types defined in one big DI module.

While the fundamental idea is sound, the implementation is constrained
by the lack of direct support for DW_FORM_ref_addr references in LLVM.
Ideally, we would use those to refer to types in the debug module directly,
however, in the absence of this, forward declarations have to do.

One problem with forward declarations that had to be worked around was
wasmtime's DI GC, which only resolves DWARF's 'reference's. Thus, our
types need manual 'rooting', which is accomplished in this change by
emitting a dummy retained subroutine that references all of them.

With these changes, as well as some fixes in wasmtime (especially
bytecodealliance/wasmtime#9828), the expanded
LLDB (finally) test passes.
SingleAccretion added a commit to SingleAccretion/runtimelab that referenced this issue Dec 18, 2024
So far, we have been emitting type definitions into each compile unit
where they were 'used'. This proved problematic (wrong) as the debugger
does not "unify" types across compile units - they are expected to be
the same, due to ODR.

To solve this fundamental issue, this change introduces a more elaborate
emission scheme, where during compilation only type forwards are emitted,
which will later get satisfied by types defined in one big DI module.

While the fundamental idea is sound, the implementation is constrained
by the lack of direct support for DW_FORM_ref_addr references in LLVM.
Ideally, we would use those to refer to types in the debug module directly,
however, in the absence of this, forward declarations have to do.

One problem with forward declarations that had to be worked around was
wasmtime's DI GC, which only resolves DWARF's 'reference's. Thus, our
types need manual 'rooting', which is accomplished in this change by
emitting a dummy retained subroutine that references all of them.

With these changes, as well as some fixes in wasmtime (especially
bytecodealliance/wasmtime#9828), the expanded
LLDB (finally) test passes.
jkotas pushed a commit to dotnet/runtimelab that referenced this issue Dec 30, 2024
* Fill out the test

* Overhaul debug info generation

So far, we have been emitting type definitions into each compile unit
where they were 'used'. This proved problematic (wrong) as the debugger
does not "unify" types across compile units - they are expected to be
the same, due to ODR.

To solve this fundamental issue, this change introduces a more elaborate
emission scheme, where during compilation only type forwards are emitted,
which will later get satisfied by types defined in one big DI module.

While the fundamental idea is sound, the implementation is constrained
by the lack of direct support for DW_FORM_ref_addr references in LLVM.
Ideally, we would use those to refer to types in the debug module directly,
however, in the absence of this, forward declarations have to do.

One problem with forward declarations that had to be worked around was
wasmtime's DI GC, which only resolves DWARF's 'reference's. Thus, our
types need manual 'rooting', which is accomplished in this change by
emitting a dummy retained subroutine that references all of them.

With these changes, as well as some fixes in wasmtime (especially
bytecodealliance/wasmtime#9828), the expanded
LLDB (finally) test passes.

* Use daily wasmtime
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant