summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrei Vagin <avagin@google.com>2019-08-13 11:54:59 -0700
committergVisor bot <gvisor-bot@google.com>2019-08-13 11:56:29 -0700
commit8d97b22aa8e565ff05c5e9209f13d2394e9706c8 (patch)
tree560454cee4e8aa2ee3d948d5e381f61765fe68a0
parentfa3d0e6f63d6ecc9a6566ec80e4a8c7519c6cf76 (diff)
tests: print stack traces if test failed by timeout
PiperOrigin-RevId: 263184083
-rw-r--r--runsc/main.go8
-rw-r--r--runsc/sandbox/sandbox.go2
-rw-r--r--test/syscalls/syscall_test_runner.go45
3 files changed, 52 insertions, 3 deletions
diff --git a/runsc/main.go b/runsc/main.go
index 5823819f4..e864118b2 100644
--- a/runsc/main.go
+++ b/runsc/main.go
@@ -22,6 +22,7 @@ import (
"io"
"io/ioutil"
"os"
+ "os/signal"
"path/filepath"
"strings"
"syscall"
@@ -116,6 +117,13 @@ func main() {
// All subcommands must be registered before flag parsing.
flag.Parse()
+ if *testOnlyAllowRunAsCurrentUserWithoutChroot {
+ // SIGTERM is sent to all processes if a test exceeds its
+ // timeout and this case is handled by syscall_test_runner.
+ log.Warningf("Block the TERM signal. This is only safe in tests!")
+ signal.Ignore(syscall.SIGTERM)
+ }
+
// Are we showing the version?
if *showVersion {
// The format here is the same as runc.
diff --git a/runsc/sandbox/sandbox.go b/runsc/sandbox/sandbox.go
index 851b1304b..df3c0c5ef 100644
--- a/runsc/sandbox/sandbox.go
+++ b/runsc/sandbox/sandbox.go
@@ -361,6 +361,8 @@ func (s *Sandbox) createSandboxProcess(conf *boot.Config, args *Args, startSyncF
nextFD++
}
+ cmd.Args = append(cmd.Args, "--panic-signal="+strconv.Itoa(int(syscall.SIGTERM)))
+
// Add the "boot" command to the args.
//
// All flags after this must be for the boot command
diff --git a/test/syscalls/syscall_test_runner.go b/test/syscalls/syscall_test_runner.go
index 5936d66ff..d1f9552a2 100644
--- a/test/syscalls/syscall_test_runner.go
+++ b/test/syscalls/syscall_test_runner.go
@@ -23,11 +23,13 @@ import (
"math"
"os"
"os/exec"
+ "os/signal"
"path/filepath"
"strconv"
"strings"
"syscall"
"testing"
+ "time"
specs "github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/sys/unix"
@@ -189,6 +191,8 @@ func runTestCaseRunsc(testBin string, tc gtest.TestCase, t *testing.T) {
"-log-format=text",
"-TESTONLY-unsafe-nonroot=true",
"-net-raw=true",
+ fmt.Sprintf("-panic-signal=%d", syscall.SIGTERM),
+ "-watchdog-action=panic",
}
if *overlay {
args = append(args, "-overlay")
@@ -220,8 +224,8 @@ func runTestCaseRunsc(testBin string, tc gtest.TestCase, t *testing.T) {
// Current process doesn't have CAP_SYS_ADMIN, create user namespace and run
// as root inside that namespace to get it.
- args = append(args, "run", "--bundle", bundleDir, id)
- cmd := exec.Command(*runscPath, args...)
+ rArgs := append(args, "run", "--bundle", bundleDir, id)
+ cmd := exec.Command(*runscPath, rArgs...)
cmd.SysProcAttr = &syscall.SysProcAttr{
Cloneflags: syscall.CLONE_NEWUSER | syscall.CLONE_NEWNS,
// Set current user/group as root inside the namespace.
@@ -239,9 +243,44 @@ func runTestCaseRunsc(testBin string, tc gtest.TestCase, t *testing.T) {
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
+ sig := make(chan os.Signal, 1)
+ signal.Notify(sig, syscall.SIGTERM)
+ go func() {
+ s, ok := <-sig
+ if !ok {
+ return
+ }
+ t.Errorf("%s: Got signal: %v", tc.FullName(), s)
+ done := make(chan bool)
+ go func() {
+ dArgs := append(args, "-alsologtostderr=true", "debug", "--stacks", id)
+ cmd := exec.Command(*runscPath, dArgs...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ cmd.Run()
+ done <- true
+ }()
+
+ timeout := time.Tick(3 * time.Second)
+ select {
+ case <-timeout:
+ t.Logf("runsc debug --stacks is timeouted")
+ case <-done:
+ }
+
+ t.Logf("Send SIGTERM to the sandbox process")
+ dArgs := append(args, "debug",
+ fmt.Sprintf("--signal=%d", syscall.SIGTERM),
+ id)
+ cmd = exec.Command(*runscPath, dArgs...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ cmd.Run()
+ }()
if err = cmd.Run(); err != nil {
t.Errorf("test %q exited with status %v, want 0", tc.FullName(), err)
}
+ close(sig)
}
// filterEnv returns an environment with the blacklisted variables removed.
@@ -277,7 +316,7 @@ func main() {
fatalf("test-name flag must be provided")
}
- log.SetLevel(log.Warning)
+ log.SetLevel(log.Info)
if *debug {
log.SetLevel(log.Debug)
}