From ae648bafda2d82a6641e4a28bed34dae40d426ec Mon Sep 17 00:00:00 2001 From: Fabricio Voznika Date: Mon, 27 Aug 2018 20:35:00 -0700 Subject: Add command-line parameter to trigger panic on signal This is to troubleshoot problems with a hung process that is not responding to 'runsc debug --stack' command. PiperOrigin-RevId: 210483513 Change-Id: I4377b210b4e51bc8a281ad34fd94f3df13d9187d --- runsc/boot/config.go | 6 ++++++ runsc/boot/loader.go | 14 +++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'runsc/boot') diff --git a/runsc/boot/config.go b/runsc/boot/config.go index bc392deb3..efb8563ea 100644 --- a/runsc/boot/config.go +++ b/runsc/boot/config.go @@ -204,7 +204,12 @@ type Config struct { // TODO: Remove this when multiple container is fully supported. MultiContainer bool + // WatchdogAction sets what action the watchdog takes when triggered. WatchdogAction watchdog.Action + + // PanicSignal register signal handling that panics. Usually set to + // SIGUSR2(12) to troubleshoot hangs. -1 disables it. + PanicSignal int } // ToFlags returns a slice of flags that correspond to the given Config. @@ -225,5 +230,6 @@ func (c *Config) ToFlags() []string { "--strace-syscalls=" + strings.Join(c.StraceSyscalls, ","), "--strace-log-size=" + strconv.Itoa(int(c.StraceLogSize)), "--watchdog-action=" + c.WatchdogAction.String(), + "--panic-signal=" + strconv.Itoa(c.PanicSignal), } } diff --git a/runsc/boot/loader.go b/runsc/boot/loader.go index 3963ed55d..0ad830a6b 100644 --- a/runsc/boot/loader.go +++ b/runsc/boot/loader.go @@ -20,6 +20,7 @@ import ( "fmt" "math/rand" "os" + "os/signal" "runtime" "sync" "sync/atomic" @@ -229,7 +230,18 @@ func New(spec *specs.Spec, conf *Config, controllerFD int, ioFDs []int, console return nil, fmt.Errorf("failed to ignore child stop signals: %v", err) } // Ensure that signals received are forwarded to the emulated kernel. - stopSignalForwarding := sighandling.PrepareForwarding(k, false)() + ps := syscall.Signal(conf.PanicSignal) + stopSignalForwarding := sighandling.PrepareForwarding(k, ps)() + if conf.PanicSignal != -1 { + // Panics if the sentry receives 'conf.PanicSignal'. + panicChan := make(chan os.Signal, 1) + signal.Notify(panicChan, ps) + go func() { // S/R-SAFE: causes sentry panic. + <-panicChan + panic("Signal-induced panic") + }() + log.Infof("Panic signal set to %v(%d)", ps, conf.PanicSignal) + } procArgs, err := newProcess(spec, creds, utsns, ipcns, k) if err != nil { -- cgit v1.2.3