{"record":{"id":"bce9217e9c2e4ad5","repo":"bazelbuild/bazel","slug":"file-s-line-va-args","errorCode":null,"errorMessage":"__FILE__ \":\" S__LINE__ \": \\\"\" __VA_ARGS__","messagePattern":"__FILE__ \":\" S__LINE__ \": \\\\\"\" __VA_ARGS__","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/main/tools/logging.h","lineNumber":36,"sourceCode":"// See https://stackoverflow.com/a/8132440 .\n#ifndef __STDC_FORMAT_MACROS\n#define __STDC_FORMAT_MACROS\n#endif\n#include <inttypes.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <time.h>\n\n// see\n// http://stackoverflow.com/questions/5641427/how-to-make-preprocessor-generate-a-string-for-line-keyword\n#define S(x) #x\n#define S_(x) S(x)\n#define S__LINE__ S_(__LINE__)\n\n#define DIE(...)                                                \\\n  {                                                             \\\n    fprintf(stderr, __FILE__ \":\" S__LINE__ \": \\\"\" __VA_ARGS__); \\\n    fprintf(stderr, \"\\\": \");                                    \\\n    perror(nullptr);                                            \\\n    exit(EXIT_FAILURE);                                         \\\n  }\n\n#define PRINT_DEBUG(fmt, ...)                                       \\\n  do {                                                              \\\n    if (global_debug) {                                             \\\n      struct timespec ts;                                           \\\n      clock_gettime(CLOCK_REALTIME, &ts);                           \\\n                                                                    \\\n      fprintf(global_debug, \"%\" PRId64 \".%09ld: %s:%d: \" fmt \"\\n\",  \\\n              ((int64_t)ts.tv_sec), ts.tv_nsec, __FILE__, __LINE__, \\\n              ##__VA_ARGS__);                                       \\\n                                                                    \\\n      /* Minimize probability of losing output if we're killed. */  \\\n      fflush(global_debug);                                         \\\n    }                                                               \\","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/bazelbuild/bazel/blob/e6e199d0601a244511b4cf18c8b2828aa73db1fd/src/main/tools/logging.h#L18-L54","documentation":"DIE is the fatal-error macro used by Bazel's low-level client tools (process-wrapper, linux-sandbox). It prints 'file:line: \"<message>\": ' to stderr, appends the errno description via perror(nullptr), then calls exit(EXIT_FAILURE), so the wrapped subprocess is killed immediately. It fires whenever one of these tools hits an unrecoverable OS-level failure such as open(), stat(), mkdir(), chdir(), or pipe() returning -1.","triggerScenarios":"Invoking process-wrapper or linux-sandbox with a working directory (-W) that does not exist or is not readable; redirect files (-l/-L/-o/-e) pointing to unwritable paths; sandbox setup failing because /proc is not mounted or user namespaces are disabled; any syscall inside the tool whose errno-triggering failure is routed through DIE().","commonSituations":"Sandboxed actions failing on hardened kernels (unprivileged userns disabled, AppArmor/SELinux denials); Docker containers lacking /proc or with read-only tmpfs for sandbox roots; stale sandbox directories owned by another user; running the tools by hand with wrong argument order.","solutions":["Rerun the Bazel command with --sandbox_debug (and --subcommands) to keep the sandbox alive and see the exact file:line plus perror output.","Read the errno text after the colon (e.g. 'Permission denied', 'No such file or directory') and fix that filesystem condition for the path shown.","If user namespaces are blocked (common in gVisor/Docker), run Bazel with --spawn_strategy=standalone or --sandbox_base=/tmp/bazel-sandbox.","Manually reproduce the failing setup: try mkdir/chdir/open on the printed path as the same user.","If the message is inconsistent with the environment, file a bug with bazel info and the full stderr line."],"exampleFix":"# before: bazel build //pkg (dies with sandbox DIE message)\nbazel build --sandbox_debug --subcommands //pkg\n# then inspect the printed path, e.g.:\nls -ld /tmp/bazel-sandbox.* ; mkdir -p /tmp/bazel-sandbox ; chmod 1777 /tmp/bazel-sandbox","handlingStrategy":"validation","validationCode":"// before spawning the sandboxed action, verify its filesystem preconditions\nstd::filesystem::create_directories(workdir);\nif (access(workdir.c_str(), R_OK | W_OK | X_OK) != 0) {\n  perror(\"sandbox workdir unusable\");\n  return false;  // skip action instead of letting process-wrapper DIE\n}\nfor (auto &f : {stdout_path, stderr_path})\n  if (!f.empty() && !std::filesystem::exists(std::filesystem::path(f).parent_path()))\n    return false;","typeGuard":null,"tryCatchPattern":"// if you are the parent spawning the tool, treat the exit code as the 'catch':\nint rc = run_sandboxed(cmd);\nif (rc != 0) {\n  // stderr already carries 'file:line: \"msg\": strerror'\n  fprintf(stderr, \"sandbox failed rc=%d; rerun with --sandbox_debug\\n\", rc);\n}","preventionTips":["Pre-flight every path flag (-W, -l, -L): parent directories must exist and be writable.","Run Bazel with --sandbox_debug during bring-up so DIE diagnostics are not destroyed with the sandbox.","Keep sandbox base on a real writable filesystem (not noexec/read-only mounts).","Never hand-edit the argv captured from --subcommands; copy it verbatim."],"tags":["c","macro","sandbox","process-wrapper","errno","fatal-exit","client-tools"],"backgroundTag":null,"analyzedSha":"e6e199d0601a244511b4cf18c8b2828aa73db1fd","analyzedAt":"2026-08-14T10:24:27.848Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}