[CRIU] [PATCH 3/3] core: Print stack trace in case of SIGSEGV
Kirill Tkhai
ktkhai at virtuozzo.com
Mon May 29 07:02:00 PDT 2017
Register SIGSEGV handler and print call trace in case of error.
This should make the debug easier. Look at error messages before
and after.
1)Before:
(01.227591)pie: 1: Task 86 exited, status= 11
(01.241495) Error (criu/cr-restore.c:1114): 489968 exited, status=1
and nobody knows where and why.
2)After:
(01.090136) 86: Error (criu/mount.c:346): mnt: stack 86#0: criu(print_stack_trace+0x1e) [0x459aee]
(01.090143) 86: Error (criu/mount.c:346): mnt: stack 86#1: criu(print_stack_and_exit+0x3e) [0x459b8e]
(01.090145) 86: Error (criu/mount.c:346): mnt: stack 86#2: /lib64/libc.so.6(+0x35250) [0x7fbbf16fb250]
(01.090147) 86: Error (criu/mount.c:346): mnt: stack 86#3: criu(phys_stat_resolve_dev+0x63) [0x459c03]
(01.090149) 86: Error (criu/mount.c:346): mnt: stack 86#4: criu(__open_mountpoint+0x4d) [0x45ca7d]
(01.090151) 86: Error (criu/mount.c:346): mnt: stack 86#5: criu() [0x44cf8e]
(01.090153) 86: Error (criu/mount.c:346): mnt: stack 86#6: criu() [0x44d7d3]
(01.090155) 86: Error (criu/mount.c:346): mnt: stack 86#7: criu() [0x44db6e]
(01.090157) 86: Error (criu/mount.c:346): mnt: stack 86#8: criu(prepare_fds+0x477) [0x44b077]
(01.090159) 86: Error (criu/mount.c:346): mnt: stack 86#9: criu() [0x43cbef]
(01.090471)pie: 1: Task 86 exited, status= 255
(01.103910) Error (criu/cr-restore.c:1114): 492906 exited, status=1
and everything is clear.
This will help developers in debug.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
criu/cr-dump.c | 6 ++++++
criu/cr-restore.c | 11 +++++++++--
criu/include/util.h | 1 +
criu/util.c | 10 ++++++++++
4 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index 1d661e7b1..acb90d9b5 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -1759,6 +1759,12 @@ int cr_dump_tasks(pid_t pid)
pr_info("Dumping processes (pid: %d)\n", pid);
pr_info("========================================\n");
+#ifdef __GLIBC__
+ if (signal(SIGSEGV, print_stack_and_exit) == SIG_ERR) {
+ pr_perror("signal() failed");
+ goto err;
+ }
+#endif
if (opts.remote && push_snapshot_id() < 0) {
pr_err("Failed to push image namespace.\n");
goto err;
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index a420f77af..8e9c04272 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -1429,7 +1429,7 @@ static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
futex_abort_and_wake(&task_entries->nr_in_progress);
}
-int criu_signals_setup(void (*handler)(int, siginfo_t *, void *))
+int criu_signals_setup(void (*sigchld_handler)(int, siginfo_t *, void *))
{
int ret;
struct sigaction act;
@@ -1442,7 +1442,7 @@ int criu_signals_setup(void (*handler)(int, siginfo_t *, void *))
}
act.sa_flags |= SA_NOCLDSTOP | SA_SIGINFO | SA_RESTART;
- act.sa_sigaction = handler;
+ act.sa_sigaction = sigchld_handler;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGCHLD);
@@ -1452,6 +1452,12 @@ int criu_signals_setup(void (*handler)(int, siginfo_t *, void *))
return -1;
}
+#ifdef __GLIBC__
+ if (signal(SIGSEGV, print_stack_and_exit) == SIG_ERR) {
+ pr_perror("signal() failed");
+ return -1;
+ }
+#endif
/*
* The block mask will be restored in sigreturn.
*
@@ -1459,6 +1465,7 @@ int criu_signals_setup(void (*handler)(int, siginfo_t *, void *))
*/
sigfillset(&blockmask);
sigdelset(&blockmask, SIGCHLD);
+ sigdelset(&blockmask, SIGSEGV);
/*
* Here we use SIG_SETMASK instead of SIG_BLOCK to avoid the case where
diff --git a/criu/include/util.h b/criu/include/util.h
index c1dd66676..b5fb77455 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -311,6 +311,7 @@ extern int open_fd_of_real_pid(pid_t pid, int fd, int flags);
extern int call_in_child_process(int (*fn)(void *), void *arg);
extern void print_stack_trace(pid_t pid);
+extern void print_stack_and_exit(int signum);
#define block_sigmask(saved_mask, sig_mask) ({ \
sigset_t ___blocked_mask; \
diff --git a/criu/util.c b/criu/util.c
index fef3ce7c8..cdec4b63b 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -45,6 +45,7 @@
#include "vma.h"
#include "mem.h"
#include "namespaces.h"
+#include "pstree.h"
#include "criu-log.h"
#include "clone-noasan.h"
@@ -1413,6 +1414,15 @@ void print_stack_trace(pid_t pid)
free(strings);
}
+
+void print_stack_and_exit(int signum)
+{
+ pid_t pid = current ? vpid(current) : -1;
+
+ pr_err("OOPS: task with vpid=%d got SIGSEGV:\n", pid);
+ print_stack_trace(pid);
+ exit(-1);
+}
#endif
/*
More information about the CRIU
mailing list