Prefer Files to paths in std.debug. Additionally [breaking] add a flags parameter to openSelfExe and stop exporting openElfDebugInfo.
This should save a call to readlink in openSelfDebugInfo and support executables in overlong paths on Linux.master
parent
631633b252
commit
ab3931fa95
|
@ -670,10 +670,11 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
|
|||
}
|
||||
}
|
||||
|
||||
/// This takes ownership of coff_file: users of this function should not close
|
||||
/// it themselves, even on error.
|
||||
/// TODO resources https://github.com/ziglang/zig/issues/4353
|
||||
fn openCoffDebugInfo(allocator: *mem.Allocator, coff_file_path: [:0]const u16) !ModuleDebugInfo {
|
||||
fn readCoffDebugInfo(allocator: *mem.Allocator, coff_file: File) !ModuleDebugInfo {
|
||||
nosuspend {
|
||||
const coff_file = try std.fs.openFileAbsoluteW(coff_file_path, .{ .intended_io_mode = .blocking });
|
||||
errdefer coff_file.close();
|
||||
|
||||
const coff_obj = try allocator.create(coff.Coff);
|
||||
|
@ -851,10 +852,12 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {
|
|||
return ptr[start..end];
|
||||
}
|
||||
|
||||
/// This takes ownership of elf_file: users of this function should not close
|
||||
/// it themselves, even on error.
|
||||
/// TODO resources https://github.com/ziglang/zig/issues/4353
|
||||
pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !ModuleDebugInfo {
|
||||
pub fn readElfDebugInfo(allocator: *mem.Allocator, elf_file: File) !ModuleDebugInfo {
|
||||
nosuspend {
|
||||
const mapped_mem = try mapWholeFile(elf_file_path);
|
||||
const mapped_mem = try mapWholeFile(elf_file);
|
||||
const hdr = @ptrCast(*const elf.Ehdr, &mapped_mem[0]);
|
||||
if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic;
|
||||
if (hdr.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion;
|
||||
|
@ -921,8 +924,10 @@ pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !M
|
|||
}
|
||||
|
||||
/// TODO resources https://github.com/ziglang/zig/issues/4353
|
||||
fn openMachODebugInfo(allocator: *mem.Allocator, macho_file_path: []const u8) !ModuleDebugInfo {
|
||||
const mapped_mem = try mapWholeFile(macho_file_path);
|
||||
/// This takes ownership of coff_file: users of this function should not close
|
||||
/// it themselves, even on error.
|
||||
fn readMachODebugInfo(allocator: *mem.Allocator, macho_file: File) !ModuleDebugInfo {
|
||||
const mapped_mem = try mapWholeFile(macho_file);
|
||||
|
||||
const hdr = @ptrCast(
|
||||
*const macho.mach_header_64,
|
||||
|
@ -1055,9 +1060,8 @@ const MachoSymbol = struct {
|
|||
}
|
||||
};
|
||||
|
||||
fn mapWholeFile(path: []const u8) ![]align(mem.page_size) const u8 {
|
||||
fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {
|
||||
nosuspend {
|
||||
const file = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking });
|
||||
defer file.close();
|
||||
|
||||
const file_len = try math.cast(usize, try file.getEndPos());
|
||||
|
@ -1140,10 +1144,11 @@ pub const DebugInfo = struct {
|
|||
errdefer self.allocator.destroy(obj_di);
|
||||
|
||||
const macho_path = mem.spanZ(std.c._dyld_get_image_name(i));
|
||||
obj_di.* = openMachODebugInfo(self.allocator, macho_path) catch |err| switch (err) {
|
||||
const macho_file = fs.cwd().openFile(macho_path, .{ .always_blocking = true }) catch |err| switch (err) {
|
||||
error.FileNotFound => return error.MissingDebugInfo,
|
||||
else => return err,
|
||||
};
|
||||
obj_di.* = try readMachODebugInfo(self.allocator, macho_file);
|
||||
obj_di.base_address = base_address;
|
||||
|
||||
try self.address_map.putNoClobber(base_address, obj_di);
|
||||
|
@ -1221,10 +1226,11 @@ pub const DebugInfo = struct {
|
|||
const obj_di = try self.allocator.create(ModuleDebugInfo);
|
||||
errdefer self.allocator.destroy(obj_di);
|
||||
|
||||
obj_di.* = openCoffDebugInfo(self.allocator, name_buffer[0 .. len + 4 :0]) catch |err| switch (err) {
|
||||
const coff_file = fs.openFileAbsoluteW(name_buffer[0 .. len + 4 :0], .{}) catch |err| switch (err) {
|
||||
error.FileNotFound => return error.MissingDebugInfo,
|
||||
else => return err,
|
||||
};
|
||||
obj_di.* = try readCoffDebugInfo(self.allocator, coff_file);
|
||||
obj_di.base_address = seg_start;
|
||||
|
||||
try self.address_map.putNoClobber(seg_start, obj_di);
|
||||
|
@ -1280,23 +1286,18 @@ pub const DebugInfo = struct {
|
|||
return obj_di;
|
||||
}
|
||||
|
||||
const elf_path = if (ctx.name.len > 0)
|
||||
ctx.name
|
||||
else blk: {
|
||||
// Use of MAX_PATH_BYTES here is valid as the resulting path is immediately
|
||||
// opened with no modification. TODO: Use openSelfExe instead to avoid path
|
||||
// length limitations
|
||||
var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
break :blk try fs.selfExePath(&buf);
|
||||
};
|
||||
|
||||
const obj_di = try self.allocator.create(ModuleDebugInfo);
|
||||
errdefer self.allocator.destroy(obj_di);
|
||||
|
||||
obj_di.* = openElfDebugInfo(self.allocator, elf_path) catch |err| switch (err) {
|
||||
const elf_file = (if (ctx.name.len > 0)
|
||||
fs.cwd().openFile(ctx.name, .{ .always_blocking = true })
|
||||
else
|
||||
fs.openSelfExe(.{ .always_blocking = true })) catch |err| switch (err) {
|
||||
error.FileNotFound => return error.MissingDebugInfo,
|
||||
else => return err,
|
||||
};
|
||||
|
||||
obj_di.* = try readElfDebugInfo(self.allocator, elf_file);
|
||||
obj_di.base_address = ctx.base_address;
|
||||
|
||||
try self.address_map.putNoClobber(ctx.base_address, obj_di);
|
||||
|
@ -1332,7 +1333,8 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
|
|||
}
|
||||
|
||||
fn loadOFile(self: *@This(), o_file_path: []const u8) !DW.DwarfInfo {
|
||||
const mapped_mem = try mapWholeFile(o_file_path);
|
||||
const o_file = try fs.cwd().openFile(o_file_path, .{ .always_blocking = true });
|
||||
const mapped_mem = try mapWholeFile(o_file);
|
||||
|
||||
const hdr = @ptrCast(
|
||||
*const macho.mach_header_64,
|
||||
|
|
|
@ -1778,21 +1778,21 @@ pub fn walkPath(allocator: *Allocator, dir_path: []const u8) !Walker {
|
|||
|
||||
pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfExePathError || os.FlockError;
|
||||
|
||||
pub fn openSelfExe() OpenSelfExeError!File {
|
||||
pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File {
|
||||
if (builtin.os.tag == .linux) {
|
||||
return openFileAbsoluteZ("/proc/self/exe", .{});
|
||||
return openFileAbsoluteZ("/proc/self/exe", flags);
|
||||
}
|
||||
if (builtin.os.tag == .windows) {
|
||||
const wide_slice = selfExePathW();
|
||||
const prefixed_path_w = try os.windows.wToPrefixedFileW(wide_slice);
|
||||
return cwd().openFileW(prefixed_path_w.span(), .{});
|
||||
return cwd().openFileW(prefix_path_w.span(), flags);
|
||||
}
|
||||
// Use of MAX_PATH_BYTES here is valid as the resulting path is immediately
|
||||
// opened with no modification.
|
||||
var buf: [MAX_PATH_BYTES]u8 = undefined;
|
||||
const self_exe_path = try selfExePath(&buf);
|
||||
buf[self_exe_path.len] = 0;
|
||||
return openFileAbsoluteZ(buf[0..self_exe_path.len :0].ptr, .{});
|
||||
return openFileAbsoluteZ(self_exe_path[0..self_exe_path.len :0].ptr, flags);
|
||||
}
|
||||
|
||||
pub const SelfExePathError = os.ReadLinkError || os.SysCtlError;
|
||||
|
|
|
@ -6,7 +6,7 @@ const File = std.fs.File;
|
|||
test "openSelfExe" {
|
||||
if (builtin.os.tag == .wasi) return error.SkipZigTest;
|
||||
|
||||
const self_exe_file = try std.fs.openSelfExe();
|
||||
const self_exe_file = try std.fs.openSelfExe(.{});
|
||||
self_exe_file.close();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue