Skip to content

Conversation

@Adityazzzzz
Copy link
Contributor

@Adityazzzzz Adityazzzzz commented Dec 24, 2025

What this PR does / why we need it: This PR fixes a DWARF debug info corruption issue when compiling variables or parameters of type noreturn.

Previously, the compiler treated noreturn types (which have a type index of 0) like normal types. It generated a DWARF abbreviation containing DW_AT_type and wrote a 0 value for it. However, tools like objdump interpret a type index of 0 as invalid or missing context in this specific scenario, causing them to lose synchronization with the DWARF stream and report corruption errors like: objdump: Warning: Unable to find entry for abbreviation [number]

The Fix: I modified dwarf_outsym in backend/dwarfdbginf.d to handle noreturn types specially:

  • Definitions: Created a new abbreviation suffix (formal_var_abbrev_suffix_notype) that explicitly omits the DW_AT_type attribute.
  • Logic: Updated the abbreviation generation logic for Globals, Parameters, and Local Variables. If the type index is 0 (noreturn), it now uses the "Type-less" abbreviation.
  • Writing: Updated the value-writing loop to skip writing the 4-byte type index when tidx == 0, ensuring the binary data matches the new abbreviation structure.

Verification: Using the reproduction case from the issue:

module repro;
noreturn global_var;
void test(noreturn param) {
    noreturn local_var;
}

Before: objdump --dwarf=info reported: Warning: Unable to find entry for abbreviation... and displayed corrupted tags.
After: objdump output is clean. noreturn variables appear correctly without a DW_AT_type field:

<2><e0>: Abbrev Number: 6 (DW_TAG_formal_parameter)
    <e1>    DW_AT_name        : param
    <eb>    DW_AT_artificial  : 0
    ...

Ref: #22251

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @Adityazzzzz! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

⚠️⚠️⚠️ Warnings ⚠️⚠️⚠️

  • In preparation for migrating from Bugzilla to GitHub Issues, the issue reference syntax has changed. Please add the word "Bugzilla" to issue references. For example, Fix Bugzilla Issue 12345 or Fix Bugzilla 12345.(Reminder: the edit needs to be done in the Git commit message, not the GitHub pull request.)

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#22302"

if (tidx == 0) // FIX: If noreturn use NOTYPE array
{
dwarfabbrev.append(DW_TAG_formal_parameter, DW_CHILDREN_no);
formalcode = dwarfabbrev.awrite!formal_var_abbrev_suffix_notype;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll want to set this in another variable other than formalcode, otherwise you'll get corrupt dwarf for the opposite reason - abbreviation has no TYPE, but data contains one.

if (tidx == 0) // FIX: If noreturn use NOTYPE array
{
dwarfabbrev.append(DW_TAG_variable, DW_CHILDREN_no);
variablecode = dwarfabbrev.awrite!formal_var_abbrev_suffix_notype;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise here for variablecode.

@ibuclaw
Copy link
Member

ibuclaw commented Dec 24, 2025

I can see handling void/noreturn symbols being done for globals, locals, and parameters. But not for field members.

cast(void)dwarf_typidx(sa.Stype);
if (!formalcode)
uint tidx = cast(uint)dwarf_typidx(sa.Stype);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trailing whitespace

cast(void)dwarf_typidx(sa.Stype);
if (!variablecode)
uint tidx = cast(uint)dwarf_typidx(sa.Stype);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

debug_info.buf.write32(tidx); // DW_AT_type
debug_info.buf.writeByte(sa.Sflags & SFLartifical ? 1 : 0); // DW_FORM_tag
debug_info.buf.writeStringz(getSymName(sa)); // DW_AT_name

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Variables with noreturn type (type index 0) were causing corrupt DWARF output because the compiler was writing a type index of 0 into abbreviations that expected a valid type reference.
This patch adds a check to generate specific abbreviations without DW_AT_type for variables, parameters, and globals when the type index is 0.
@Adityazzzzz Adityazzzzz force-pushed the fix/noreturn-debug-info branch from 97d7201 to 1afb8fa Compare December 25, 2025 08:48
@Adityazzzzz
Copy link
Contributor Author

@ibuclaw @thewilsonator Please Review

@WalterBright
Copy link
Member

Maybe it would be better to simply omit emitting debug info for noreturn-typed symbols. I don't know if debuggers can even handle a "bottom type".

@WalterBright
Copy link
Member

Or disallow creating variables of type noreturn.

@WalterBright
Copy link
Member

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 this pull request may close these issues.

5 participants