authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-09 12:40:53+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-09 14:16:44+01:00
logbda5180b2ccfed22da04dd0b7a48d60beda03538
tree560aa602784b1fc88d6f18a69cae4d40c7727eb2
parentd88eb75a69d27ef50635f9aa1caf2a7177d99ead

llvm: resolve all relative paths when creating DIFiles

This will make stack traces and debugging experience more consistent in the sense that the presence of source lines in stack traces will not be dependent on the current working directory of the running process.

1 files changed, 25 insertions(+), 19 deletions(-)

src/codegen/llvm.zig+25-19
......@@ -443,20 +443,19 @@ pub const Object = struct {
443443 });
444444 defer gpa.free(producer);
445445
446 // For macOS stack traces, we want to avoid having to parse the compilation unit debug
447 // info. As long as each debug info file has a path independent of the compilation unit
448 // directory (DW_AT_comp_dir), then we never have to look at the compilation unit debug
449 // info. If we provide an absolute path to LLVM here for the compilation unit debug
450 // info, LLVM will emit DWARF info that depends on DW_AT_comp_dir. To avoid this, we
451 // pass "." for the compilation unit directory. This forces each debug file to have a
452 // directory rather than be relative to DW_AT_comp_dir. According to DWARF 5, debug
453 // files will no longer reference DW_AT_comp_dir, for the purpose of being able to
454 // support the common practice of stripping all but the line number sections from an
455 // executable.
456 const compile_unit_dir = d: {
457 if (options.target.isDarwin()) break :d ".";
458 const mod = options.module orelse break :d ".";
459 break :d mod.root_pkg.root_src_directory.path orelse ".";
446 // We fully resolve all paths at this point to avoid lack of source line info in stack
447 // traces or lack of debugging information which, if relative paths were used, would
448 // be very location dependent.
449 // TODO: the only concern I have with this is WASI as either host or target, should
450 // we leave the paths as relative then?
451 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
452 const compile_unit_dir = blk: {
453 const path = d: {
454 const mod = options.module orelse break :d ".";
455 break :d mod.root_pkg.root_src_directory.path orelse ".";
456 };
457 if (std.fs.path.isAbsolute(path)) break :blk path;
458 break :blk std.os.realpath(path, &buf) catch path; // If realpath fails, fallback to whatever path was
460459 };
461460 const compile_unit_dir_z = try gpa.dupeZ(u8, compile_unit_dir);
462461 defer gpa.free(compile_unit_dir_z);
......@@ -1389,13 +1388,20 @@ pub const Object = struct {
13891388 if (gop.found_existing) {
13901389 return @ptrCast(*llvm.DIFile, gop.value_ptr.*);
13911390 }
1392 const dir_path = file.pkg.root_src_directory.path orelse ".";
1391 const dir_path_z = d: {
1392 var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
1393 const dir_path = file.pkg.root_src_directory.path orelse ".";
1394 const resolved_dir_path = if (std.fs.path.isAbsolute(dir_path))
1395 dir_path
1396 else
1397 std.os.realpath(dir_path, &buffer) catch dir_path; // If realpath fails, fallback to whatever dir_path was
1398 break :d try std.fs.path.joinZ(gpa, &.{
1399 resolved_dir_path, std.fs.path.dirname(file.sub_file_path) orelse "",
1400 });
1401 };
1402 defer gpa.free(dir_path_z);
13931403 const sub_file_path_z = try gpa.dupeZ(u8, std.fs.path.basename(file.sub_file_path));
13941404 defer gpa.free(sub_file_path_z);
1395 const dir_path_z = try std.fs.path.joinZ(gpa, &.{
1396 dir_path, std.fs.path.dirname(file.sub_file_path) orelse "",
1397 });
1398 defer gpa.free(dir_path_z);
13991405 const di_file = o.di_builder.?.createFile(sub_file_path_z, dir_path_z);
14001406 gop.value_ptr.* = di_file.toNode();
14011407 return di_file;