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

Add -fdebuginfo option #22197

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from
Draft

Add -fdebuginfo option #22197

wants to merge 18 commits into from

Conversation

leroycep
Copy link
Contributor

@leroycep leroycep commented Dec 9, 2024

Builds on pull request #22077, adding a convenient way to get symbol based stack traces to the Zig compiler and build system.

  • Adds -fdebuginfo= option (to?)
  • Removes -fstrip option (from?)
  • Removes -gdwarf32 and gdwarf64
  • use -g<debug stuff> or --debug <debug stuff> instead of -fdebuginfo to match with clang and gcc?
  • check that -fdebuginfo reports useful errors if an option isn't supported for the target platform?
  • Rewrite commits to make better individual changes?

See also #18520

This work is licensed on the same terms as the Zig project.

Copyright © 2024 TigerBeetle, Inc.

This code was written under contract for TigerBeetle. As a work made for hire, authorship and copyright goes to TigerBeetle.

Author certificate

LeRoyce Pearson <opensource@geemili.xyz> [TigerBeetle, Inc.]

This work is licensed on the same terms as this project (Zig).

Comment on lines +518 to +528
\\ -fdebuginfo=[format] Set strip level
\\ none Don't emit any debug info
\\ symbols Emit symbol table
\\ dwarf32 Emit dwarf32 debug info
\\ dwarf64 Emit dwarf32 debug info
\\ code_view (Windows) Emit code_view debug info
Copy link
Member

Choose a reason for hiding this comment

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

cc @andrewrk

I'd personally like to see something like:

Suggested change
\\ -fdebuginfo=[format] Set strip level
\\ none Don't emit any debug info
\\ symbols Emit symbol table
\\ dwarf32 Emit dwarf32 debug info
\\ dwarf64 Emit dwarf32 debug info
\\ code_view (Windows) Emit code_view debug info
\\ -g Emit debug info
\\ -g0 Don't emit debug info
\\ -g[format] Override target debug format
\\ symbols Only use the object format's symbol table
\\ dwarf32 Use 32-bit DWARF
\\ dwarf64 Use 64-bit DWARF
\\ codeview (Windows) Use CodeView

-g would pick whatever format is native to the target, so 32-bit DWARF for most targets and CodeView for Windows. -g<format> should imply -g.

If no option is given, I suggest the defaults should be:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with this. In the initial implementation I was a bit too focused on putting everything into DebugFormat. User facing we need a bit more information than that, especially if later on Zig gains support for generating partial debug info.

Another consideration: some debug formats are not mutually exclusive. DWARF is already a superset of symbols, and CTF can live alongside DWARF. So a set of independent values may make more sense than the enum I introduced here.

Perhaps something like:

 -g          Emit debug info
 -g0         Don't emit debug info
 -gsymbols   Emit symbol table
 -gsymbols0  Don't emit symbol table
 -gdwarf     Emit DWARF debug info
 -gdwarf0    Don't emit DWARF debug info
 -gcodeview  Emit Code View debug info
 -gcodeview0 Don't emit Code View debug info

Then the user input side data structure would look like:

const DebugSettings = struct {
    emit_debug_info: ?bool,
    emit_debug_format_symbols: ?bool,
    emit_debug_format_dwarf: ?bool,
    emit_debug_format_codeview: ?bool,
};

With defaults resolution like so:

const DebugConfig = struct {
    emit_symbols: bool,
    emit_dwarf: ?DwarfFormat,
    emit_codeview: bool,
};

fn (debug_settings: DebugSettings) DebugConfig {
    if (debug_settings.emit_debug_info) |should_emit| {
        if (!should_emit) DebugConfig{ .emit_symbols = false, .emit_dwarf = null, .emit_codeview = false };
    }
    const debug_format_is_selected = debug_settings.emit_debug_format_symbols != null or debug_settings.emit_debug_format_dwarf != null or debug_settings.emit_debug_format_codeview != null;

    const emit_symbols = blk: {
        if (debug_settings.emit_debug_format_symbols) |should_emit| break :blk should_emit;
        if (debug_format_is_selected) break :blk false;
        // TODO: check release mode, output format, etc.
        break :blk true;
    };

    const emit_dwarf_format = blk: {
        // TODO: look at -gdwarf32 and -gdwarf64 flags
        if (debug_settings.emit_debug_format_dwarf) |should_emit| break :blk if (should_emit) .dwarf32 else null;
        if (debug_format_is_selected) break :blk null;
        // TODO: check release mode, output format, etc.
        break :blk null;
    };

    const emit_codeview = blk: {
        if (debug_settings.emit_debug_format_symbols) |should_emit| break :blk should_emit;
        if (debug_format_is_selected) break :blk false;
        // TODO: check release mode, output format, etc.
        break :blk false;
    };

    return DebugConfig{ .emit_symbols = emit_symbols, .emit_dwarf = emit_dwarf_format, .emit_codeview = emit_codeview };
}

But maybe I'm over complicating this; I'm not sure if Zig wants to support generating multiple debug formats even if it is technically possible.

Copy link
Member

Choose a reason for hiding this comment

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

It seems useful to combine BTF/CTF with DWARF; GCC supports this. I'm not convinced that combining DWARF and CodeView is useful, nor that emitting DWARF/CodeView but omitting the symbol table is useful. But maybe I'm missing some use case here?

Assuming I'm not, then I think we can just add -gctf and -gctf-dwarf32/-gctf-dwarf64 options in the future if we add CTF support.

When reading `std.debug.Dwarf ` fails, `std.debug.SelfInfo` will now try to load
function names from `symtab`.
This makes it possible for executables built with `-fstrip=debuginfo` to unwind
frames. No need to specify `-fno-omit-frame-pointer`! This is only possible
because the `eh_frame` and `eh_frame_hdr` sections are not stripped when
`-fstrip=debuginfo`.
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.

2 participants