ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
33.77k stars 2.47k forks source link

Error traces in custom steps no longer print in zig build #15014

Open RossComputerGuy opened 1 year ago

RossComputerGuy commented 1 year ago

Zig Version

0.11.0-dev.2160+49d37e2d1

Steps to Reproduce and Observed Behavior

With the introduction of #14647, I've noticed that custom steps made in build.zig will no longer show an error trace. Because of this, it is difficult to debug certain issues even with -freference-trace set.

Example:

expidus-neutron-git+dirty> LLVM Emit Object... Semantic Analysis [2847] log... Semantic Analysis [3111] builtin... Semantic Analysis [3290] getArg... Semantic Analysis [3631] addOneAssumeCapacity... Semantic Analysis [3656] insertAllEntriesIntoNewHeaderGeneric... Semantic Analysis [3795] usize_bits... Semantic Analysis [4256] arm966e_s... Semantic Analysis [4639] assert... Semantic Analysis [4762] access... Semantic Analysis [4831] addOne... Semantic Analysis [4992] keys... Semantic Analysis [5062] ensureTotalCapacity... Semantic Analysis [5127] fetchRemoveByKey... Semantic Analysis [5164] growIfNeeded... Semantic Analysis [5192] swapRemove... Semantic Analysis [5229] format... compiler_rt... Semantic Analysis [1213] divc3... LLVM Emit Object... LLVM Emit Object... LLVM Emit Object... LLVM Emit Object... LLD Link... warning: Encountered error: FileNotFound, falling back to default ABI and dynamic linker.
expidus-neutron-git+dirty> steps [8/26] zig build-lib expat Debug x86_64-linux.5.15.83...5.15.83-gnu.2.35... LLVM Emit Obje... steps [8/26] zig build-lib expat Debug x86_64-linux.5.15.83...5.15.83-gnu.2.35... Comp... steps [8/26] zig build-lib expat Debug x86_64-linux.5.15.83...5.15.83-gnu.2.35... Compi... steps [8/26] zig build-lib expat Debug x86_64-linux.5.15.83...5.15.83-gnu.2.35... Compi... steps [8/26] zig build-lib ffi Debug x86_64-linux-gnu... LLVM Emit Object... zig build-lib expat Debug x86_64-linux.5.15.83...5.15.83-gnu.2.35: error: warning: zig cannot build new glibc version 2.35; providing instead 2.34
expidus-neutron-git+dirty> steps [11/26] Scan Protocols: error: FileNotFound
expidus-neutron-git+dirty> error: the following build command failed with exit code 1:
expidus-neutron-git+dirty> /build/source/zig-cache/o/ae51be07b4176dcbdee547276624c937/build /nix/store/5nnciv3g8knn7nl7isdhbwv9qm1k0i4x-zig-0.11.0-dev.2160+49d37e2d1/bin/zig /build/source /build/source/zig-cache /build/.cache/zig -Dflutter-engine=/nix/store/4b34f91qfsdzxgj7ca4lqal97y2ajz7q-flutter-engine-3.3.7/lib/flutter/out/release -Dtarget=x86_64-linux-gnu -Dhost-dynamic-linker=/nix/store/76l4v99sk83ylfwkz8wmwrm4s8h73rhd-glibc-2.35-224/lib/ld-linux-x86-64.so.2 -Dtarget-dynamic-linker=/nix/store/76l4v99sk83ylfwkz8wmwrm4s8h73rhd-glibc-2.35-224/lib/ld-linux-x86-64.so.2 --prefix /nix/store/3b4098396jwmvgfxj2z6mhxg0iipn5x8-expidus-neutron-git+dirty --prefix-lib-dir /nix/store/3b4098396jwmvgfxj2z6mhxg0iipn5x8-expidus-neutron-git+dirty/lib -freference-trace -freference-trace -fno-summary

As you can see, an error occurred in a step called "Scan Protocols" but it is difficult to understand where the error is coming from.

Expected Behavior

Either -freference-trace should at least be able to show the trace or when an error is thrown in a custom step, the trace is shown automatically.

jiacai2050 commented 1 year ago

Same issue with 0.11.0-dev.2154+2089b3f19.

Wow, this issue is fixed in https://github.com/ziglang/zig/commit/49d37e2d179948f526f500043c6ea9ae324e9476.

@RossComputerGuy Would you mind give another try?

RossComputerGuy commented 1 year ago

That's unrelated to this issue and I've tried several times to rebuild but I get the same issue.

jiacai2050 commented 1 year ago

Could you provide a minimal example to reproduce this issue?

RossComputerGuy commented 1 year ago

This should work and should print out only a FileNotFound error with no trace.

const std = @import("std");

fn make_step(step: *std.Build.Step, prog_node: *std.Progress.Node) !void {
  _ = step;
  _ = prog_node;

  return error.FileNotFound;
}

pub fn build(b: *std.Build) void {
  var step = std.Build.Step.init(.{
    .id = .custom,
    .name = "Failure",
    .owner = b,
    .makeFn = make_step,
  });

  b.default_step.dependOn(&step);
}
jiacai2050 commented 1 year ago

I try your build.zig, but got segfault in my macbook...

$ zig build
Segmentation fault at address 0x0
/Users/jiacai/x/zig-macos-aarch64-0.11.0-dev.2168+322ace70f/lib/std/mem.zig:199:31: 0x100641524 in copy__anon_6567 (build)                                           
    for (dest[0..source.len], source) |*d, s|                                     
                              ^
/Users/jiacai/x/zig-macos-aarch64-0.11.0-dev.2168+322ace70f/lib/std/array_list.zig:886:45: 0x1006d255b in ensureTotalCapacityPrecise (build)                         
                mem.copy(T, new_memory, self.items);                              
                                            ^                                     
/Users/jiacai/x/zig-macos-aarch64-0.11.0-dev.2168+322ace70f/lib/std/array_list.zig:861:51: 0x1006ad27f in ensureTotalCapacity (build)
            return self.ensureTotalCapacityPrecise(allocator, better_capacity);
                                                  ^
/Users/jiacai/x/zig-macos-aarch64-0.11.0-dev.2168+322ace70f/lib/std/array_list.zig:914:41: 0x100668d57 in addOne (build)
            try self.ensureTotalCapacity(allocator, newlen);

0.11.0-dev.2168+322ace70f

RossComputerGuy commented 1 year ago

Yeah, I have the same segfault. Code wise, it should work but it doesn't.

RossComputerGuy commented 1 year ago

@jiacai2050 I decided to take a look at why the example wouldn't work and I just had to allocate step:

const std = @import("std");

fn make_step(step: *std.Build.Step, prog_node: *std.Progress.Node) !void {
  _ = step;
  _ = prog_node;

  return error.FileNotFound;
}

pub fn build(b: *std.Build) !void {
  var step = try b.allocator.create(std.Build.Step);
  step.* = std.Build.Step.init(.{
    .id = .custom,
    .name = "Failure",
    .owner = b,
    .makeFn = make_step,
  });

  b.default_step.dependOn(step);
}

Log:

Failure: error: FileNotFound
Build Summary: 0/2 steps succeeded; 1 failed (disable with -fno-summary)
install transitive failure
└─ Failure failure

And it happens as expected of the issue, it prints error: FileNotFound but it's hard to debug because no trace is printed.

andrewrk commented 1 year ago

This is not confirmed to be a bug yet. Can I see your custom build step logic? Also could you perhaps not use a custom step?

RossComputerGuy commented 1 year ago

I saw this originally here but I don't have an exact point of failure due to the stack trace not being printed. Also, what would be the alternative to a custom step if a custom step isn't supposed to be used?

andrewrk commented 1 year ago

Whatever needs being done, it can be done by one of these:

If all else fails, a RunStep allows for arbitrary code execution - and such code will be done in a sub-process, so you have no chance of accidentally misusing the build system custom step API.

RossComputerGuy commented 1 year ago

It looks like std defined steps print a stack trace on error but custom steps do not.

ls: unrecognized option '--broken-arg'
詳しくは 'ls --help' を実行して下さい。
The following command exited with code 2 (expected exited with code 0):
cd /home/ross/ExpidusOS && ls --broken-arg
error: UnexpectedExit
/nix/store/innnzvrqknfq288r5knzpfl618da8hma-zig-0.11.0-dev.1910+6d7fb8f19/lib/std/Build/RunStep.zig:424:9: 0x2c8670 in runCommand (build)
        return error.UnexpectedExit;
        ^
/nix/store/innnzvrqknfq288r5knzpfl618da8hma-zig-0.11.0-dev.1910+6d7fb8f19/lib/std/Build/RunStep.zig:290:5: 0x2b0dd9 in make (build)
    try runCommand(
    ^
/nix/store/innnzvrqknfq288r5knzpfl618da8hma-zig-0.11.0-dev.1910+6d7fb8f19/lib/std/Build/Step.zig:75:5: 0x26e3cb in make (build)
    try self.makeFn(self);
    ^
/nix/store/innnzvrqknfq288r5knzpfl618da8hma-zig-0.11.0-dev.1910+6d7fb8f19/lib/std/Build.zig:760:5: 0x25a6fa in makeOneStep (build)
    try s.make();
    ^
/nix/store/innnzvrqknfq288r5knzpfl618da8hma-zig-0.11.0-dev.1910+6d7fb8f19/lib/std/Build.zig:754:13: 0x25a69d in makeOneStep (build)
            return err;
            ^
/nix/store/innnzvrqknfq288r5knzpfl618da8hma-zig-0.11.0-dev.1910+6d7fb8f19/lib/std/Build.zig:715:9: 0x25a441 in make (build)
        try self.makeOneStep(s);
        ^
/nix/store/innnzvrqknfq288r5knzpfl618da8hma-zig-0.11.0-dev.1910+6d7fb8f19/lib/build_runner.zig:259:21: 0x25da12 in main (build)
            else => return err,
const std = @import("std");
const Build = std.Build;

pub fn build(b: *Build) !void {
  const exec = b.addSystemCommand(&.{
    "ls",
    "--broken-arg",
  });

  b.default_step.dependOn(&exec.step);
}

Not sure why custom steps don't print error traces. It really should be printed because there's cases where just from error names, not enough information is provided. There's always a proposal like #2647 but imo, it probably would be best to have at the very least error traces printed when a function fails in zig build.