aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Yue Gan <yueg@google.com>2016-02-18 13:34:51 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2016-02-19 08:56:39 +0000
commit40ee9de052e3bb8cf5a59eeff3936148e1f55e69 (patch)
tree6695f29de93b67dcee0be703057184ee9462b46e /src
parent9f93673c4ffca8c2288600a8163cfa7c8e75fe79 (diff)
sandbox: Easier debugging of sandbox failures, when using both --verbose_failures and --sandbox_debug.
RELNOTES: - When using both --verbose_failures and --sandbox_debug, Bazel prints instructions how to spawn a debugging shell inside the sandbox. - When namespace-sandbox is run with the -D (debug) flag and inside a terminal, it spawns a shell inside the sandbox to aid in debugging when the sandboxed command fails. -- MOS_MIGRATED_REVID=114953983
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/sandbox/NamespaceSandboxRunner.java12
-rw-r--r--src/main/tools/namespace-sandbox.c38
2 files changed, 44 insertions, 6 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/NamespaceSandboxRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/NamespaceSandboxRunner.java
index ed6f714d33..c6069bdb71 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/NamespaceSandboxRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/NamespaceSandboxRunner.java
@@ -47,6 +47,11 @@ import java.util.List;
public class NamespaceSandboxRunner {
private static final String NAMESPACE_SANDBOX =
"namespace-sandbox" + OsUtils.executableExtension();
+ private static final String SANDBOX_TIP =
+ "\n\nSandboxed execution failed, which may be legitimate (e.g. a compiler error), "
+ + "or due to missing dependencies. To enter the sandbox environment for easier debugging,"
+ + " run the following command in brackets. On command failure, "
+ + "a bash shell running inside the sandbox will then automatically be spawned\n\n";
private final Path execRoot;
private final Path sandboxPath;
private final Path sandboxExecRoot;
@@ -198,8 +203,9 @@ public class NamespaceSandboxRunner {
}
String message =
CommandFailureUtils.describeCommandFailure(
- verboseFailures, spawnArguments, env, cwd.getPath());
- throw new UserExecException(message, e, timedOut);
+ verboseFailures, commandLineArgs, env, cwd.getPath());
+ String finalMsg = (sandboxDebug && verboseFailures) ? SANDBOX_TIP + message : message;
+ throw new UserExecException(finalMsg, e, timedOut);
} finally {
copyOutputs(outputs);
}
@@ -230,7 +236,7 @@ public class NamespaceSandboxRunner {
if (sandboxPath.exists()) {
FileSystemUtils.deleteTree(sandboxPath);
}
- if (argumentsFilePath.exists()) {
+ if (!sandboxDebug && argumentsFilePath.exists()) {
argumentsFilePath.delete();
}
}
diff --git a/src/main/tools/namespace-sandbox.c b/src/main/tools/namespace-sandbox.c
index ce81d57907..04f1c9c734 100644
--- a/src/main/tools/namespace-sandbox.c
+++ b/src/main/tools/namespace-sandbox.c
@@ -16,6 +16,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <ftw.h>
#include <libgen.h>
#include <limits.h>
#include <pwd.h>
@@ -476,7 +477,31 @@ static void SetupDevices() {
CHECK_CALL(symlink("/proc/self/fd", "dev/fd"));
}
+static int rmrf(const char *fpath, const struct stat *sb, int typeflag,
+ struct FTW *ftwbuf) {
+ if (typeflag == FTW_DP) {
+ return rmdir(fpath);
+ } else {
+ return unlink(fpath);
+ }
+}
+
static void SetupDirectories(struct Options *opt) {
+ // If in sandbox_debug mode and debugging, create the sandbox root dir first
+ if (global_debug && isatty(fileno(stdin))) {
+ // Enter sandbox_debug mode a second time, delete old sandbox
+ struct stat sb;
+ int err = stat(opt->sandbox_root, &sb);
+ if (err == 0) {
+ CHECK_CALL(nftw(opt->sandbox_root, *rmrf, sysconf(_SC_OPEN_MAX),
+ FTW_DEPTH | FTW_PHYS));
+ } else if (errno != ENOENT) {
+ CHECK_CALL(err);
+ }
+
+ CHECK_CALL(mkdir(opt->sandbox_root, 0755));
+ }
+
// Mount the sandbox and go there.
CHECK_CALL(mount(opt->sandbox_root, opt->sandbox_root, NULL,
MS_BIND | MS_NOSUID, NULL));
@@ -653,11 +678,11 @@ void OnSignal(int sig) {
// Run the command specified by the argv array and kill it after timeout
// seconds.
-static void SpawnCommand(char *const *argv, double timeout_secs) {
+static void SpawnCommand(char *const *argv, double timeout_secs,
+ bool isFallback) {
for (int i = 0; argv[i] != NULL; i++) {
PRINT_DEBUG("arg: %s\n", argv[i]);
}
-
CHECK_CALL(global_child_pid = fork());
if (global_child_pid == 0) {
// In child.
@@ -691,6 +716,13 @@ static void SpawnCommand(char *const *argv, double timeout_secs) {
UnHandle(global_signal);
raise(global_signal);
} else if (WIFEXITED(status)) {
+ if (global_debug && !isFallback && isatty(fileno(stdin)) &&
+ WEXITSTATUS(status) > 0) {
+ char **cmdList = calloc(2, sizeof(char *));
+ cmdList[0] = "/bin/bash";
+ cmdList[1] = NULL;
+ SpawnCommand(cmdList, 0, true);
+ }
exit(WEXITSTATUS(status));
} else {
int sig = WTERMSIG(status);
@@ -749,7 +781,7 @@ int main(int argc, char *const argv[]) {
}
ChangeRoot(&opt);
- SpawnCommand(opt.args, opt.timeout_secs);
+ SpawnCommand(opt.args, opt.timeout_secs, false);
free(opt.create_dirs);
free(opt.mount_sources);