Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
a0c5a06
teach std.debug to convert addresses to ELF symbols
leroycep Nov 20, 2024
fc4debf
teach `debug.ElfSymTab` to read unwind info in `.eh_frame` sections
leroycep Nov 28, 2024
c30055f
add unwindFrame to `debug.SelfInfo.Module` when targeting Apple OSes
leroycep Nov 28, 2024
d022185
merge `debug.SelfInfo.Elf` into `SelfInfo.Module`
leroycep Nov 28, 2024
975eefd
revert change that removed `error.InvalidDebugInfo` from `readDebugIn…
leroycep Nov 28, 2024
c2c6461
add debug format test cases
leroycep Dec 4, 2024
d28fbd1
exclude macos and windows from symbols debug format stack trace tests
leroycep Dec 4, 2024
055e913
debug format stack trace test: strip compile unit extensions
leroycep Dec 4, 2024
f497573
check that debug formats work in multiple optimize modes
leroycep Dec 4, 2024
cdec909
make `-fstrip` accept parameter; `none`, `debuginfo`, or `all`
leroycep Nov 25, 2024
3ce1901
use the `std.builtin.Strip` enum in `std.Build`
leroycep Nov 27, 2024
cbaa274
update CMakeLists.txt to use `-Dstrip=[none|debuginfo]`
leroycep Nov 28, 2024
c3bf0d2
fix some defaults that changed to the wrong thing
leroycep Nov 28, 2024
473cd98
replace `-fstrip` and `-gdwarf` options with `-fdebuginfo=`
leroycep Nov 30, 2024
24a0cd2
move DebugFormat to `std.builtin`, update `std.Build` to use `-fdebug…
leroycep Dec 1, 2024
ed96cf8
update debug format stack trace tests to use `std.builtin.DebugFormat`
leroycep Dec 4, 2024
f15a52b
fix: make `ReleaseSafe` use DWARF debug info by default for most outp…
leroycep Dec 9, 2024
4d1ac61
test-debug-format-stack-traces: test against multiple target OSes
leroycep Dec 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -941,9 +941,9 @@ endif()
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
list(APPEND ZIG_BUILD_ARGS -Doptimize=Debug)
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseFast)
list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseFast -Ddebuginfo=dwarf32)
else()
list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseFast -Dstrip)
list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseFast -Ddebuginfo=symbols)
endif()

if(ZIG_STATIC AND NOT MSVC)
Expand Down
11 changes: 6 additions & 5 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -172,21 +172,21 @@ pub fn build(b: *std.Build) !void {
const force_gpa = b.option(bool, "force-gpa", "Force the compiler to use GeneralPurposeAllocator") orelse false;
const link_libc = b.option(bool, "force-link-libc", "Force self-hosted compiler to link libc") orelse (enable_llvm or only_c);
const sanitize_thread = b.option(bool, "sanitize-thread", "Enable thread-sanitization") orelse false;
const strip = b.option(bool, "strip", "Omit debug information");
const debuginfo = b.option(std.builtin.DebugFormat, "debuginfo", "Format to use for debuginfo");
const valgrind = b.option(bool, "valgrind", "Enable valgrind integration");
const pie = b.option(bool, "pie", "Produce a Position Independent Executable");
const value_tracing = b.option(bool, "value-tracing", "Enable extra state tracking to help troubleshoot bugs in the compiler (using the std.debug.Trace API)") orelse false;

const mem_leak_frames: u32 = b.option(u32, "mem-leak-frames", "How many stack frames to print when a memory leak occurs. Tests get 2x this amount.") orelse blk: {
if (strip == true) break :blk @as(u32, 0);
if (debuginfo != null and debuginfo.? == .none) break :blk @as(u32, 0);
if (optimize != .Debug) break :blk 0;
break :blk 4;
};

const exe = addCompilerStep(b, .{
.optimize = optimize,
.target = target,
.strip = strip,
.debuginfo = debuginfo,
.valgrind = valgrind,
.sanitize_thread = sanitize_thread,
.single_threaded = single_threaded,
Expand Down Expand Up @@ -539,6 +539,7 @@ pub fn build(b: *std.Build) !void {
}));
test_step.dependOn(tests.addLinkTests(b, enable_macos_sdk, enable_ios_sdk, enable_symlinks_windows));
test_step.dependOn(tests.addStackTraceTests(b, test_filters, optimization_modes));
test_step.dependOn(tests.addDebugFormatStackTraceTests(b, optimization_modes, skip_non_native));
test_step.dependOn(tests.addCliTests(b));
test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filters, optimization_modes));
if (tests.addDebuggerTests(b, .{
Expand Down Expand Up @@ -629,7 +630,7 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
const AddCompilerStepOptions = struct {
optimize: std.builtin.OptimizeMode,
target: std.Build.ResolvedTarget,
strip: ?bool = null,
debuginfo: ?std.builtin.DebugFormat = null,
valgrind: ?bool = null,
sanitize_thread: ?bool = null,
single_threaded: ?bool = null,
Expand All @@ -642,7 +643,7 @@ fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.St
.target = options.target,
.optimize = options.optimize,
.max_rss = 7_800_000_000,
.strip = options.strip,
.debuginfo = options.debuginfo,
.sanitize_thread = options.sanitize_thread,
.single_threaded = options.single_threaded,
.code_model = switch (options.target.result.cpu.arch) {
Expand Down
20 changes: 10 additions & 10 deletions lib/std/Build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ pub const ExecutableOptions = struct {
link_libc: ?bool = null,
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
debuginfo: ?std.builtin.DebugFormat = null,
unwind_tables: ?std.builtin.UnwindTables = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
Expand All @@ -731,7 +731,7 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile {
.link_libc = options.link_libc,
.single_threaded = options.single_threaded,
.pic = options.pic,
.strip = options.strip,
.debuginfo = options.debuginfo,
.unwind_tables = options.unwind_tables,
.omit_frame_pointer = options.omit_frame_pointer,
.sanitize_thread = options.sanitize_thread,
Expand Down Expand Up @@ -761,7 +761,7 @@ pub const ObjectOptions = struct {
link_libc: ?bool = null,
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
debuginfo: ?std.builtin.DebugFormat = null,
unwind_tables: ?std.builtin.UnwindTables = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
Expand All @@ -781,7 +781,7 @@ pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile {
.link_libc = options.link_libc,
.single_threaded = options.single_threaded,
.pic = options.pic,
.strip = options.strip,
.debuginfo = options.debuginfo,
.unwind_tables = options.unwind_tables,
.omit_frame_pointer = options.omit_frame_pointer,
.sanitize_thread = options.sanitize_thread,
Expand Down Expand Up @@ -809,7 +809,7 @@ pub const SharedLibraryOptions = struct {
link_libc: ?bool = null,
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
debuginfo: ?std.builtin.DebugFormat = null,
unwind_tables: ?std.builtin.UnwindTables = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
Expand All @@ -835,7 +835,7 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile
.link_libc = options.link_libc,
.single_threaded = options.single_threaded,
.pic = options.pic,
.strip = options.strip,
.debuginfo = options.debuginfo,
.unwind_tables = options.unwind_tables,
.omit_frame_pointer = options.omit_frame_pointer,
.sanitize_thread = options.sanitize_thread,
Expand Down Expand Up @@ -866,7 +866,7 @@ pub const StaticLibraryOptions = struct {
link_libc: ?bool = null,
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
debuginfo: ?std.builtin.DebugFormat = null,
unwind_tables: ?std.builtin.UnwindTables = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
Expand All @@ -886,7 +886,7 @@ pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile
.link_libc = options.link_libc,
.single_threaded = options.single_threaded,
.pic = options.pic,
.strip = options.strip,
.debuginfo = options.debuginfo,
.unwind_tables = options.unwind_tables,
.omit_frame_pointer = options.omit_frame_pointer,
.sanitize_thread = options.sanitize_thread,
Expand Down Expand Up @@ -918,7 +918,7 @@ pub const TestOptions = struct {
link_libcpp: ?bool = null,
single_threaded: ?bool = null,
pic: ?bool = null,
strip: ?bool = null,
debuginfo: ?std.builtin.DebugFormat = null,
unwind_tables: ?std.builtin.UnwindTables = null,
omit_frame_pointer: ?bool = null,
sanitize_thread: ?bool = null,
Expand Down Expand Up @@ -948,7 +948,7 @@ pub fn addTest(b: *Build, options: TestOptions) *Step.Compile {
.link_libcpp = options.link_libcpp,
.single_threaded = options.single_threaded,
.pic = options.pic,
.strip = options.strip,
.debuginfo = options.debuginfo,
.unwind_tables = options.unwind_tables,
.omit_frame_pointer = options.omit_frame_pointer,
.sanitize_thread = options.sanitize_thread,
Expand Down
20 changes: 10 additions & 10 deletions lib/std/Build/Module.zig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import_table: std.StringArrayHashMapUnmanaged(*Module),

resolved_target: ?std.Build.ResolvedTarget = null,
optimize: ?std.builtin.OptimizeMode = null,
dwarf_format: ?std.dwarf.Format,

c_macros: std.ArrayListUnmanaged([]const u8),
include_dirs: std.ArrayListUnmanaged(IncludeDir),
Expand All @@ -21,7 +20,7 @@ rpaths: std.ArrayListUnmanaged(RPath),
frameworks: std.StringArrayHashMapUnmanaged(LinkFrameworkOptions),
link_objects: std.ArrayListUnmanaged(LinkObject),

strip: ?bool,
debuginfo: ?std.builtin.DebugFormat,
unwind_tables: ?std.builtin.UnwindTables,
single_threaded: ?bool,
stack_protector: ?bool,
Expand Down Expand Up @@ -217,7 +216,7 @@ pub const CreateOptions = struct {
/// `null` neither requires nor prevents libc++ from being linked.
link_libcpp: ?bool = null,
single_threaded: ?bool = null,
strip: ?bool = null,
debuginfo: ?std.builtin.DebugFormat = null,
unwind_tables: ?std.builtin.UnwindTables = null,
dwarf_format: ?std.dwarf.Format = null,
code_model: std.builtin.CodeModel = .default,
Expand Down Expand Up @@ -254,14 +253,13 @@ pub fn init(m: *Module, owner: *std.Build, options: CreateOptions, compile: ?*St
.optimize = options.optimize,
.link_libc = options.link_libc,
.link_libcpp = options.link_libcpp,
.dwarf_format = options.dwarf_format,
.c_macros = .{},
.include_dirs = .{},
.lib_paths = .{},
.rpaths = .{},
.frameworks = .{},
.link_objects = .{},
.strip = options.strip,
.debuginfo = options.debuginfo,
.unwind_tables = options.unwind_tables,
.single_threaded = options.single_threaded,
.stack_protector = options.stack_protector,
Expand Down Expand Up @@ -674,7 +672,6 @@ pub fn appendZigProcessFlags(
) !void {
const b = m.owner;

try addFlag(zig_args, m.strip, "-fstrip", "-fno-strip");
try addFlag(zig_args, m.single_threaded, "-fsingle-threaded", "-fno-single-threaded");
try addFlag(zig_args, m.stack_check, "-fstack-check", "-fno-stack-check");
try addFlag(zig_args, m.stack_protector, "-fstack-protector", "-fno-stack-protector");
Expand All @@ -687,10 +684,13 @@ pub fn appendZigProcessFlags(
try addFlag(zig_args, m.pic, "-fPIC", "-fno-PIC");
try addFlag(zig_args, m.red_zone, "-mred-zone", "-mno-red-zone");

if (m.dwarf_format) |dwarf_format| {
try zig_args.append(switch (dwarf_format) {
.@"32" => "-gdwarf32",
.@"64" => "-gdwarf64",
if (m.debuginfo) |debuginfo| {
try zig_args.append(switch (debuginfo) {
.none => "-fdebuginfo=none",
.symbols => "-fdebuginfo=symbols",
.dwarf32 => "-fdebuginfo=dwarf32",
.dwarf64 => "-fdebuginfo=dwarf64",
.code_view => "-fdebuginfo=code_view",
});
}

Expand Down
4 changes: 2 additions & 2 deletions lib/std/Build/Step/Compile.zig
Original file line number Diff line number Diff line change
Expand Up @@ -655,8 +655,8 @@ pub fn producesPdbFile(compile: *Compile) bool {
else => return false,
}
if (target.ofmt == .c) return false;
if (compile.root_module.strip == true or
(compile.root_module.strip == null and compile.root_module.optimize == .ReleaseSmall))
if (compile.root_module.debuginfo == .none or
(compile.root_module.debuginfo == null and compile.root_module.optimize == .ReleaseSmall))
{
return false;
}
Expand Down
10 changes: 10 additions & 0 deletions lib/std/builtin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,16 @@ pub const AtomicRmwOp = enum {
Min,
};

/// This data structure is used by the Zig language code generation and
/// therefore must be kept in sync with the compiler implementation.
pub const DebugFormat = enum {
none,
symbols,
dwarf32,
dwarf64,
code_view,
};

/// The code model puts constraints on the location of symbols and the size of code and data.
/// The selection of a code model is a trade off on speed and restrictions that needs to be selected on a per application basis to meet its requirements.
/// A slightly more detailed explanation can be found in (for example) the [System V Application Binary Interface (x86_64)](https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf) 3.5.1.
Expand Down
26 changes: 2 additions & 24 deletions lib/std/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const native_endian = native_arch.endian();
pub const MemoryAccessor = @import("debug/MemoryAccessor.zig");
pub const FixedBufferReader = @import("debug/FixedBufferReader.zig");
pub const Dwarf = @import("debug/Dwarf.zig");
pub const ElfSymTab = @import("debug/ElfSymTab.zig");
pub const Pdb = @import("debug/Pdb.zig");
pub const SelfInfo = @import("debug/SelfInfo.zig");
pub const Info = @import("debug/Info.zig");
Expand Down Expand Up @@ -732,30 +733,7 @@ pub const StackIterator = struct {
fn next_unwind(it: *StackIterator) !usize {
const unwind_state = &it.unwind_state.?;
const module = try unwind_state.debug_info.getModuleForAddress(unwind_state.dwarf_context.pc);
switch (native_os) {
.macos, .ios, .watchos, .tvos, .visionos => {
// __unwind_info is a requirement for unwinding on Darwin. It may fall back to DWARF, but unwinding
// via DWARF before attempting to use the compact unwind info will produce incorrect results.
if (module.unwind_info) |unwind_info| {
if (SelfInfo.unwindFrameMachO(
&unwind_state.dwarf_context,
&it.ma,
unwind_info,
module.eh_frame,
module.base_address,
)) |return_address| {
return return_address;
} else |err| {
if (err != error.RequiresDWARFUnwind) return err;
}
} else return error.MissingUnwindInfo;
},
else => {},
}

if (try module.getDwarfInfoForAddress(unwind_state.debug_info.allocator, unwind_state.dwarf_context.pc)) |di| {
return SelfInfo.unwindFrameDwarf(di, &unwind_state.dwarf_context, &it.ma, null);
} else return error.MissingDebugInfo;
return module.unwindFrame(&unwind_state.dwarf_context, &it.ma) catch return error.MissingDebugInfo;
}

fn next_internal(it: *StackIterator) ?usize {
Expand Down
2 changes: 1 addition & 1 deletion lib/std/debug/Dwarf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2040,7 +2040,7 @@ const EhPointerContext = struct {
text_rel_base: ?u64 = null,
function_rel_base: ?u64 = null,
};
fn readEhPointer(fbr: *FixedBufferReader, enc: u8, addr_size_bytes: u8, ctx: EhPointerContext) !?u64 {
pub fn readEhPointer(fbr: *FixedBufferReader, enc: u8, addr_size_bytes: u8, ctx: EhPointerContext) !?u64 {
if (enc == EH.PE.omit) return null;

const value: union(enum) {
Expand Down
Loading
Loading