Skip to content

Add -gu compiler flag to enforce unwind table generation (including for -betterC)#22818

Open
IDONTUSEGH wants to merge 5 commits intodlang:masterfrom
IDONTUSEGH:gu
Open

Add -gu compiler flag to enforce unwind table generation (including for -betterC)#22818
IDONTUSEGH wants to merge 5 commits intodlang:masterfrom
IDONTUSEGH:gu

Conversation

@IDONTUSEGH
Copy link
Copy Markdown
Contributor

Adds a new compiler flag -gu (generate unwind tables) that enables stack backtracing in betterC.

The motive of the PR was working on a client's project that uses -betterC for deployment scenarios with a tweaked D runtime. When debugging crashes, I couldn't generate meaningful backtraces with DMD, the backtrace() function would only return a single frame. Switching to LDC worked around the issue, and disabling -betterC was not an option due to the runtime requirements of the target environment.

This flag allows DMD to emit the necessary unwind tables that backtrace() needs to walk the stack, matching LDC's behavior (and C compilers).

@IDONTUSEGH IDONTUSEGH requested a review from ibuclaw as a code owner March 26, 2026 13:11
@dlang-bot
Copy link
Copy Markdown
Contributor

Thanks for your pull request and interest in making D better, @IDONTUSEGH! 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.

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#22818"

@dkorpel
Copy link
Copy Markdown
Contributor

dkorpel commented Mar 26, 2026

I had to remove -nothrow before to make backtraces work again, so such a fix is certainly welcome, but to quote Walter, 'command line flags are bugs'. It would be nice if we could find a solution without a new toggle.

matching LDC's behavior

I don't see a -gu or 'unwind' flag in ldc2 --help, so does it still emit these tables by default? dmd can probably do the same then.

disabling -betterC was not an option due to the runtime requirements of the target environment

What is the error when removing that flag? If you're already linking a custom -betterC compatible druntime then removing -betterC should be fine, maybe there's an issue to be fixed there.

@IDONTUSEGH
Copy link
Copy Markdown
Contributor Author

It would be nice if we could find a solution without a new toggle.

I agree that avoiding a new flag is ideal. Initially, I considered enabling this by default for debug builds, but I wanted to avoid changing existing behavior/assumptions for users.

I don't see a -gu or 'unwind' flag in ldc2 --help, so does it still emit these tables in by default? dmd can probably do the same then.

I may have confused it with Clang's -funwind-tables. By default, LDC emits these tables unless -fno-exceptions is passed even with -betterC.

Since C doesn't support EH, and -betterC was added with C in mind, I believe having an explicit flag is the better approach.

What is the error when removing that flag? If you're already linking a custom -betterC compatible druntime then removing -betterC should be fine, maybe there's an issue to be fixed there.

We've tried removing the flag, but there are too many assumptions baked into the codebase. Since this project is a shared environment with C and strictly embedded constraints, it isn't feasible to resolve every errors without -betterC.

@dkorpel
Copy link
Copy Markdown
Contributor

dkorpel commented Mar 26, 2026

Since C doesn't support EH, and -betterC was added with C in mind, I believe having an explicit flag is the better approach.

But .eh_frame is not only used for throwing Exceptions, and C compilers emit it by default just like LDC. I don't think users will mind when dmd becomes consistent with them.

We've tried removing the flag, but there are too many assumptions baked into the codebase. Since this project is a shared environment with C and strictly embedded constraints, it isn't feasible to resolve every errors without -betterC.

But which kind of errors, can you post one of them? -betterC is supposed to enforce a subset, so if a codebase compiles under those restrictions, and then you lift the restriction, then that's not supposed to generate new errors.

@IDONTUSEGH
Copy link
Copy Markdown
Contributor Author

C compilers do not emit .eh_frame by default on all platforms. For instance, my testing on Alpine Linux (musl) confirms they are omitted by default.

I believe maintaining the current default behavior is valuable to avoid upsetting existing users or regressing on binary size.

Regarding the errors: I cannot share specific project details due to confidentiality. However, the issue is that removing -betterC introduces issues that the target environment isn't configured to handle. I am currently working on a PR for dmd to help address a few of them.

@dkorpel
Copy link
Copy Markdown
Contributor

dkorpel commented Mar 26, 2026

C compilers do not emit .eh_frame by default on all platforms

Okay, but they still can because it's useful. I interpreted your argument as "users of -betterC only want features useful with C codebases" but .eh_info clearly is among those, or you wouldn't have a reason to open this PR in the first place.

I believe maintaining the current default behavior is valuable to avoid upsetting existing users or regressing on binary size.

Don't worry, users don't expect dmd to generate optimized or small executables, that's what ldc and gdc get used for. (And LDC incidentally still emits .eh_info so unless there's people complaining about that it should be fine)

@ibuclaw
Copy link
Copy Markdown
Member

ibuclaw commented Mar 26, 2026

matching LDC's behavior

I don't see a -gu or 'unwind' flag in ldc2 --help, so does it still emit these tables by default? dmd can probably do the same then.

GDC has -funwind-tables - though admittedly it's a common GCC option for all languages so no special support required.

"""
Similar to -fexceptions, except that it just generates any needed static data, but does not affect the generated code in any other way. You normally do not need to enable this option; instead, a language processor that needs this handling enables it on your behalf.
"""

@rikkimax
Copy link
Copy Markdown
Contributor

To remind everyone, the -betterC switch should be split into its constituent parts to match gdc.

So instead of saying I want unwinding tables, you say I don't want TypeInfo/ModuleInfo, druntime linked, exceptions.

@ibuclaw
Copy link
Copy Markdown
Member

ibuclaw commented Mar 27, 2026

To remind everyone, the -betterC switch should be split into its constituent parts to match gdc.

So instead of saying I want unwinding tables, you say I don't want TypeInfo/ModuleInfo, druntime linked, exceptions.

-funwind-tables is default off unless target needs it. And even then the generation is typically controlled by -fexceptions (default on/off depending on the language).

What this PR is asking for is -fno-exceptions -funwind-tables. Though I suspect you should be able to get away with turning everything off except exceptions too.

else if (arg == "-gs") // https://dlang.org/dmd.html#switch-gs
driverParams.alwaysframe = true;
else if (arg == "-gu") // generate unwind tables for stack tracing
else if (arg == "-gu") // https://dlang.org/dmd.html#switch-gu
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

BTW that needs an update to src/dmd/cli.d

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.

6 participants