authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-02-14 13:12:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-15 10:48:12-07:00
log8d384722937edcfdcb3c461d316ed97405e6e2ee
treee4a33a5a1d235e84961c2fc0adf3a49af7646d72
parent02381c037221937e941e03c5e7439383dde8a2a1

std.Build: further enhance debug message for bad getPath()

Now it also shows the step stack trace of the step whose make function is being run.

2 files changed, 42 insertions(+), 8 deletions(-)

lib/std/Build.zig+41-7
...@@ -1661,13 +1661,20 @@ pub const FileSource = union(enum) {...@@ -1661,13 +1661,20 @@ pub const FileSource = union(enum) {
16611661
1662 /// Should only be called during make(), returns a path relative to the build root or absolute.1662 /// Should only be called during make(), returns a path relative to the build root or absolute.
1663 pub fn getPath(self: FileSource, src_builder: *Build) []const u8 {1663 pub fn getPath(self: FileSource, src_builder: *Build) []const u8 {
1664 return getPath2(self, src_builder, null);
1665 }
1666
1667 /// Should only be called during make(), returns a path relative to the build root or absolute.
1668 /// asking_step is only used for debugging purposes; it's the step being run that is asking for
1669 /// the path.
1670 pub fn getPath2(self: FileSource, src_builder: *Build, asking_step: ?*Step) []const u8 {
1664 switch (self) {1671 switch (self) {
1665 .path => |p| return src_builder.pathFromRoot(p),1672 .path => |p| return src_builder.pathFromRoot(p),
1666 .generated => |gen| return gen.path orelse {1673 .generated => |gen| return gen.path orelse {
1667 std.debug.getStderrMutex().lock();1674 std.debug.getStderrMutex().lock();
1668 const stderr = std.io.getStdErr();1675 const stderr = std.io.getStdErr();
1669 dumpBadGetPathHelp(gen.step, stderr, src_builder) catch {};1676 dumpBadGetPathHelp(gen.step, stderr, src_builder, asking_step) catch {};
1670 @panic("unable to get path");1677 @panic("misconfigured build script");
1671 },1678 },
1672 }1679 }
1673 }1680 }
...@@ -1681,25 +1688,52 @@ pub const FileSource = union(enum) {...@@ -1681,25 +1688,52 @@ pub const FileSource = union(enum) {
1681 }1688 }
1682};1689};
16831690
1684fn dumpBadGetPathHelp(s: *Step, stderr: fs.File, src_builder: *Build) anyerror!void {1691/// In this function the stderr mutex has already been locked.
1685 try stderr.writer().print(1692fn dumpBadGetPathHelp(
1693 s: *Step,
1694 stderr: fs.File,
1695 src_builder: *Build,
1696 asking_step: ?*Step,
1697) anyerror!void {
1698 const w = stderr.writer();
1699 try w.print(
1686 \\getPath() was called on a GeneratedFile that wasn't built yet.1700 \\getPath() was called on a GeneratedFile that wasn't built yet.
1687 \\ source package path: {s}1701 \\ source package path: {s}
1688 \\ Is there a missing Step dependency on step '{s}'?1702 \\ Is there a missing Step dependency on step '{s}'?
1689 \\ The step was created by this stack trace:
1690 \\1703 \\
1691 , .{1704 , .{
1692 src_builder.build_root.path orelse ".",1705 src_builder.build_root.path orelse ".",
1693 s.name,1706 s.name,
1694 });1707 });
1708
1709 const tty_config = std.debug.detectTTYConfig(stderr);
1710 tty_config.setColor(w, .Red) catch {};
1711 try stderr.writeAll(" The step was created by this stack trace:\n");
1712 tty_config.setColor(w, .Reset) catch {};
1713
1695 const debug_info = std.debug.getSelfDebugInfo() catch |err| {1714 const debug_info = std.debug.getSelfDebugInfo() catch |err| {
1696 try stderr.writer().print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)});1715 try w.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)});
1697 return;1716 return;
1698 };1717 };
1699 std.debug.writeStackTrace(s.getStackTrace(), stderr.writer(), debug_info.allocator, debug_info, std.debug.detectTTYConfig(stderr)) catch |err| {1718 const ally = debug_info.allocator;
1719 std.debug.writeStackTrace(s.getStackTrace(), w, ally, debug_info, tty_config) catch |err| {
1700 try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)});1720 try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)});
1701 return;1721 return;
1702 };1722 };
1723 if (asking_step) |as| {
1724 tty_config.setColor(w, .Red) catch {};
1725 try stderr.writeAll(" The step that is missing a dependency on the above step was created by this stack trace:\n");
1726 tty_config.setColor(w, .Reset) catch {};
1727
1728 std.debug.writeStackTrace(as.getStackTrace(), w, ally, debug_info, tty_config) catch |err| {
1729 try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)});
1730 return;
1731 };
1732 }
1733
1734 tty_config.setColor(w, .Red) catch {};
1735 try stderr.writeAll(" Hope that helps. Proceeding to panic.\n");
1736 tty_config.setColor(w, .Reset) catch {};
1703}1737}
17041738
1705/// Allocates a new string for assigning a value to a named macro.1739/// Allocates a new string for assigning a value to a named macro.
lib/std/Build/InstallFileStep.zig+1-1
...@@ -38,7 +38,7 @@ pub fn init(...@@ -38,7 +38,7 @@ pub fn init(
38fn make(step: *Step) !void {38fn make(step: *Step) !void {
39 const self = @fieldParentPtr(InstallFileStep, "step", step);39 const self = @fieldParentPtr(InstallFileStep, "step", step);
40 const src_builder = self.override_source_builder orelse self.builder;40 const src_builder = self.override_source_builder orelse self.builder;
41 const full_src_path = self.source.getPath(src_builder);41 const full_src_path = self.source.getPath2(src_builder, step);
42 const full_dest_path = self.builder.getInstallPath(self.dir, self.dest_rel_path);42 const full_dest_path = self.builder.getInstallPath(self.dir, self.dest_rel_path);
43 try self.builder.updateFile(full_src_path, full_dest_path);43 try self.builder.updateFile(full_src_path, full_dest_path);
44}44}