authorgravatar for gereeter+code@gmail.comJonathan S <gereeter+code@gmail.com> 2020-03-27 15:13:26-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-29 18:27:39-04:00
logab3931fa9581776ef3654b9b55ff447ad91e7949
tree33660c4cbb8a6f8a35dbd3f08f08da0a537359bd
parent631633b25253201968b97cf129d986def37eed4a

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.

3 files changed, 29 insertions(+), 27 deletions(-)

lib/std/debug.zig+24-22
...@@ -670,10 +670,11 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {...@@ -670,10 +670,11 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) anyerror!DebugInfo {
670 }670 }
671}671}
672672
673/// This takes ownership of coff_file: users of this function should not close
674/// it themselves, even on error.
673/// TODO resources https://github.com/ziglang/zig/issues/4353675/// TODO resources https://github.com/ziglang/zig/issues/4353
674fn openCoffDebugInfo(allocator: *mem.Allocator, coff_file_path: [:0]const u16) !ModuleDebugInfo {676fn readCoffDebugInfo(allocator: *mem.Allocator, coff_file: File) !ModuleDebugInfo {
675 nosuspend {677 nosuspend {
676 const coff_file = try std.fs.openFileAbsoluteW(coff_file_path, .{ .intended_io_mode = .blocking });
677 errdefer coff_file.close();678 errdefer coff_file.close();
678679
679 const coff_obj = try allocator.create(coff.Coff);680 const coff_obj = try allocator.create(coff.Coff);
...@@ -851,10 +852,12 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {...@@ -851,10 +852,12 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 {
851 return ptr[start..end];852 return ptr[start..end];
852}853}
853854
855/// This takes ownership of elf_file: users of this function should not close
856/// it themselves, even on error.
854/// TODO resources https://github.com/ziglang/zig/issues/4353857/// TODO resources https://github.com/ziglang/zig/issues/4353
855pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !ModuleDebugInfo {858pub fn readElfDebugInfo(allocator: *mem.Allocator, elf_file: File) !ModuleDebugInfo {
856 nosuspend {859 nosuspend {
857 const mapped_mem = try mapWholeFile(elf_file_path);860 const mapped_mem = try mapWholeFile(elf_file);
858 const hdr = @ptrCast(*const elf.Ehdr, &mapped_mem[0]);861 const hdr = @ptrCast(*const elf.Ehdr, &mapped_mem[0]);
859 if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic;862 if (!mem.eql(u8, hdr.e_ident[0..4], "\x7fELF")) return error.InvalidElfMagic;
860 if (hdr.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion;863 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...@@ -921,8 +924,10 @@ pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !M
921}924}
922925
923/// TODO resources https://github.com/ziglang/zig/issues/4353926/// TODO resources https://github.com/ziglang/zig/issues/4353
924fn openMachODebugInfo(allocator: *mem.Allocator, macho_file_path: []const u8) !ModuleDebugInfo {927/// This takes ownership of coff_file: users of this function should not close
925 const mapped_mem = try mapWholeFile(macho_file_path);928/// it themselves, even on error.
929fn readMachODebugInfo(allocator: *mem.Allocator, macho_file: File) !ModuleDebugInfo {
930 const mapped_mem = try mapWholeFile(macho_file);
926931
927 const hdr = @ptrCast(932 const hdr = @ptrCast(
928 *const macho.mach_header_64,933 *const macho.mach_header_64,
...@@ -1055,9 +1060,8 @@ const MachoSymbol = struct {...@@ -1055,9 +1060,8 @@ const MachoSymbol = struct {
1055 }1060 }
1056};1061};
10571062
1058fn mapWholeFile(path: []const u8) ![]align(mem.page_size) const u8 {1063fn mapWholeFile(file: File) ![]align(mem.page_size) const u8 {
1059 nosuspend {1064 nosuspend {
1060 const file = try fs.cwd().openFile(path, .{ .intended_io_mode = .blocking });
1061 defer file.close();1065 defer file.close();
10621066
1063 const file_len = try math.cast(usize, try file.getEndPos());1067 const file_len = try math.cast(usize, try file.getEndPos());
...@@ -1140,10 +1144,11 @@ pub const DebugInfo = struct {...@@ -1140,10 +1144,11 @@ pub const DebugInfo = struct {
1140 errdefer self.allocator.destroy(obj_di);1144 errdefer self.allocator.destroy(obj_di);
11411145
1142 const macho_path = mem.spanZ(std.c._dyld_get_image_name(i));1146 const macho_path = mem.spanZ(std.c._dyld_get_image_name(i));
1143 obj_di.* = openMachODebugInfo(self.allocator, macho_path) catch |err| switch (err) {1147 const macho_file = fs.cwd().openFile(macho_path, .{ .always_blocking = true }) catch |err| switch (err) {
1144 error.FileNotFound => return error.MissingDebugInfo,1148 error.FileNotFound => return error.MissingDebugInfo,
1145 else => return err,1149 else => return err,
1146 };1150 };
1151 obj_di.* = try readMachODebugInfo(self.allocator, macho_file);
1147 obj_di.base_address = base_address;1152 obj_di.base_address = base_address;
11481153
1149 try self.address_map.putNoClobber(base_address, obj_di);1154 try self.address_map.putNoClobber(base_address, obj_di);
...@@ -1221,10 +1226,11 @@ pub const DebugInfo = struct {...@@ -1221,10 +1226,11 @@ pub const DebugInfo = struct {
1221 const obj_di = try self.allocator.create(ModuleDebugInfo);1226 const obj_di = try self.allocator.create(ModuleDebugInfo);
1222 errdefer self.allocator.destroy(obj_di);1227 errdefer self.allocator.destroy(obj_di);
12231228
1224 obj_di.* = openCoffDebugInfo(self.allocator, name_buffer[0 .. len + 4 :0]) catch |err| switch (err) {1229 const coff_file = fs.openFileAbsoluteW(name_buffer[0 .. len + 4 :0], .{}) catch |err| switch (err) {
1225 error.FileNotFound => return error.MissingDebugInfo,1230 error.FileNotFound => return error.MissingDebugInfo,
1226 else => return err,1231 else => return err,
1227 };1232 };
1233 obj_di.* = try readCoffDebugInfo(self.allocator, coff_file);
1228 obj_di.base_address = seg_start;1234 obj_di.base_address = seg_start;
12291235
1230 try self.address_map.putNoClobber(seg_start, obj_di);1236 try self.address_map.putNoClobber(seg_start, obj_di);
...@@ -1280,23 +1286,18 @@ pub const DebugInfo = struct {...@@ -1280,23 +1286,18 @@ pub const DebugInfo = struct {
1280 return obj_di;1286 return obj_di;
1281 }1287 }
12821288
1283 const elf_path = if (ctx.name.len > 0)
1284 ctx.name
1285 else blk: {
1286 // Use of MAX_PATH_BYTES here is valid as the resulting path is immediately
1287 // opened with no modification. TODO: Use openSelfExe instead to avoid path
1288 // length limitations
1289 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
1290 break :blk try fs.selfExePath(&buf);
1291 };
1292
1293 const obj_di = try self.allocator.create(ModuleDebugInfo);1289 const obj_di = try self.allocator.create(ModuleDebugInfo);
1294 errdefer self.allocator.destroy(obj_di);1290 errdefer self.allocator.destroy(obj_di);
12951291
1296 obj_di.* = openElfDebugInfo(self.allocator, elf_path) catch |err| switch (err) {1292 const elf_file = (if (ctx.name.len > 0)
1293 fs.cwd().openFile(ctx.name, .{ .always_blocking = true })
1294 else
1295 fs.openSelfExe(.{ .always_blocking = true })) catch |err| switch (err) {
1297 error.FileNotFound => return error.MissingDebugInfo,1296 error.FileNotFound => return error.MissingDebugInfo,
1298 else => return err,1297 else => return err,
1299 };1298 };
1299
1300 obj_di.* = try readElfDebugInfo(self.allocator, elf_file);
1300 obj_di.base_address = ctx.base_address;1301 obj_di.base_address = ctx.base_address;
13011302
1302 try self.address_map.putNoClobber(ctx.base_address, obj_di);1303 try self.address_map.putNoClobber(ctx.base_address, obj_di);
...@@ -1332,7 +1333,8 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {...@@ -1332,7 +1333,8 @@ pub const ModuleDebugInfo = switch (builtin.os.tag) {
1332 }1333 }
13331334
1334 fn loadOFile(self: *@This(), o_file_path: []const u8) !DW.DwarfInfo {1335 fn loadOFile(self: *@This(), o_file_path: []const u8) !DW.DwarfInfo {
1335 const mapped_mem = try mapWholeFile(o_file_path);1336 const o_file = try fs.cwd().openFile(o_file_path, .{ .always_blocking = true });
1337 const mapped_mem = try mapWholeFile(o_file);
13361338
1337 const hdr = @ptrCast(1339 const hdr = @ptrCast(
1338 *const macho.mach_header_64,1340 *const macho.mach_header_64,
lib/std/fs.zig+4-4
...@@ -1778,21 +1778,21 @@ pub fn walkPath(allocator: *Allocator, dir_path: []const u8) !Walker {...@@ -1778,21 +1778,21 @@ pub fn walkPath(allocator: *Allocator, dir_path: []const u8) !Walker {
17781778
1779pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfExePathError || os.FlockError;1779pub const OpenSelfExeError = os.OpenError || os.windows.CreateFileError || SelfExePathError || os.FlockError;
17801780
1781pub fn openSelfExe() OpenSelfExeError!File {1781pub fn openSelfExe(flags: File.OpenFlags) OpenSelfExeError!File {
1782 if (builtin.os.tag == .linux) {1782 if (builtin.os.tag == .linux) {
1783 return openFileAbsoluteZ("/proc/self/exe", .{});1783 return openFileAbsoluteZ("/proc/self/exe", flags);
1784 }1784 }
1785 if (builtin.os.tag == .windows) {1785 if (builtin.os.tag == .windows) {
1786 const wide_slice = selfExePathW();1786 const wide_slice = selfExePathW();
1787 const prefixed_path_w = try os.windows.wToPrefixedFileW(wide_slice);1787 const prefixed_path_w = try os.windows.wToPrefixedFileW(wide_slice);
1788 return cwd().openFileW(prefixed_path_w.span(), .{});1788 return cwd().openFileW(prefix_path_w.span(), flags);
1789 }1789 }
1790 // Use of MAX_PATH_BYTES here is valid as the resulting path is immediately1790 // Use of MAX_PATH_BYTES here is valid as the resulting path is immediately
1791 // opened with no modification.1791 // opened with no modification.
1792 var buf: [MAX_PATH_BYTES]u8 = undefined;1792 var buf: [MAX_PATH_BYTES]u8 = undefined;
1793 const self_exe_path = try selfExePath(&buf);1793 const self_exe_path = try selfExePath(&buf);
1794 buf[self_exe_path.len] = 0;1794 buf[self_exe_path.len] = 0;
1795 return openFileAbsoluteZ(buf[0..self_exe_path.len :0].ptr, .{});1795 return openFileAbsoluteZ(self_exe_path[0..self_exe_path.len :0].ptr, flags);
1796}1796}
17971797
1798pub const SelfExePathError = os.ReadLinkError || os.SysCtlError;1798pub const SelfExePathError = os.ReadLinkError || os.SysCtlError;
lib/std/fs/test.zig+1-1
...@@ -6,7 +6,7 @@ const File = std.fs.File;...@@ -6,7 +6,7 @@ const File = std.fs.File;
6test "openSelfExe" {6test "openSelfExe" {
7 if (builtin.os.tag == .wasi) return error.SkipZigTest;7 if (builtin.os.tag == .wasi) return error.SkipZigTest;
88
9 const self_exe_file = try std.fs.openSelfExe();9 const self_exe_file = try std.fs.openSelfExe(.{});
10 self_exe_file.close();10 self_exe_file.close();
11}11}
1212