fix(dwarf): non-empty comp_dir so ld keeps the debug map (issue 0058)
A source path with no directory component (`sx build main.sx` from the project dir — what the chess app does) made `diFileFor` emit a `DIFile` with an empty `directory:`, so the compile unit's `DW_AT_comp_dir` was "". Apple's ld then silently drops the *entire* object's debug map (0 N_OSO) and the binary is undebuggable — lldb resolves no sx source. Builds whose path had any directory (`.sx-tmp/x.sx`, `examples/x.sx`) were unaffected, which is why small repros + the stepping smoke passed and only the bundled chess app hit it. Fix: diFileFor falls back to "." (and "/" for a root-level file) when the path has no directory component, so comp_dir is never empty. Verified: chess (`sx build --target macos --emit-obj main.sx`) now links with OSO=1 and lldb resolves `frame at main.sx:82:8`. Regression guard added to the DWARF unit test (asserts `DIFile(... directory: ".")` for a bare filename). Gates: zig build, zig build test, run_examples.sh -> 291 passed, debug-stepping smoke ok.
This commit is contained in:
@@ -989,7 +989,10 @@ test "emit: ERR E3.0 — DWARF debug info (compile unit + subprogram + per-inst
|
||||
try std.testing.expect(std.mem.indexOf(u8, ir_str, "\"Debug Info Version\"") != null);
|
||||
try std.testing.expect(std.mem.indexOf(u8, ir_str, "\"Dwarf Version\"") != null);
|
||||
try std.testing.expect(std.mem.indexOf(u8, ir_str, "DICompileUnit") != null);
|
||||
try std.testing.expect(std.mem.indexOf(u8, ir_str, "DIFile(filename: \"probe.sx\"") != null);
|
||||
// Regression (issue 0058): a bare filename (no directory component) must
|
||||
// still get a NON-EMPTY `directory:` — an empty `DW_AT_comp_dir` makes ld
|
||||
// silently drop the whole debug map, so the binary becomes undebuggable.
|
||||
try std.testing.expect(std.mem.indexOf(u8, ir_str, "DIFile(filename: \"probe.sx\", directory: \".\")") != null);
|
||||
try std.testing.expect(std.mem.indexOf(u8, ir_str, "DISubprogram(name: \"main\"") != null);
|
||||
try std.testing.expect(std.mem.indexOf(u8, ir_str, "DILocation(line: 3") != null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user