From a2eaa5cf44d607473bd801500e467b44bbf868cd Mon Sep 17 00:00:00 2001 From: Andrew Vagin Date: Fri, 20 Dec 2013 20:36:12 +0400 Subject: [PATCH] ptrace: the task state is restored automatically It's a feature of PTRACE_SEIZE. So we need to do something, only if we want to change the state. [xemul: If task _was_ in stopped state before dump and we want them to stay alive after dump, the existing code queues one more STOP to it. This affects subsequent dump, as we seize a stopped task with STOP in queue. One more item in TODO list -- support stopped tasks with STOP in queue :) ] Signed-off-by: Andrew Vagin Signed-off-by: Pavel Emelyanov --- cr-dump.c | 5 +---- cr-exec.c | 2 +- include/ptrace.h | 2 +- ptrace.c | 4 ++-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/cr-dump.c b/cr-dump.c index 6685c1f52..e02e4ae03 100644 --- a/cr-dump.c +++ b/cr-dump.c @@ -808,10 +808,7 @@ static void unseize_task_and_threads(const struct pstree_item *item, int st) * the item->state is the state task was in when we seized one. */ - if (st == TASK_ALIVE) - unseize_task(item->pid.real, item->state); - else - unseize_task(item->pid.real, st); /* item->pid will be here */ + unseize_task(item->pid.real, item->state, st); for (i = 1; i < item->nr_threads; i++) ptrace(PTRACE_DETACH, item->threads[i].real, NULL, NULL); diff --git a/cr-exec.c b/cr-exec.c index 5ada6f642..987fe5b5e 100644 --- a/cr-exec.c +++ b/cr-exec.c @@ -153,7 +153,7 @@ int cr_exec(int pid, char **opt) parasite_cure_seized(ctl); out_unseize: - unseize_task(pid, prev_state); + unseize_task(pid, prev_state, prev_state); out: return ret; } diff --git a/include/ptrace.h b/include/ptrace.h index d8034b4df..ce892b09e 100644 --- a/include/ptrace.h +++ b/include/ptrace.h @@ -56,7 +56,7 @@ struct ptrace_peeksiginfo_args { #define SI_EVENT(_si_code) (((_si_code) & 0xFFFF) >> 8) extern int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid); -extern int unseize_task(pid_t pid, int state); +extern int unseize_task(pid_t pid, int orig_state, int state); extern int ptrace_peek_area(pid_t pid, void *dst, void *addr, long bytes); extern int ptrace_poke_area(pid_t pid, void *src, void *addr, long bytes); extern int ptrace_swap_area(pid_t pid, void *dst, void *src, long bytes); diff --git a/ptrace.c b/ptrace.c index 6f738a00e..fea085e2f 100644 --- a/ptrace.c +++ b/ptrace.c @@ -19,13 +19,13 @@ #include "ptrace.h" #include "proc_parse.h" -int unseize_task(pid_t pid, int st) +int unseize_task(pid_t pid, int orig_st, int st) { pr_debug("\tUnseizing %d into %d\n", pid, st); if (st == TASK_DEAD) kill(pid, SIGKILL); - else if (st == TASK_STOPPED) + else if (st == TASK_STOPPED && orig_st == TASK_ALIVE) kill(pid, SIGSTOP); else if (st == TASK_ALIVE) /* do nothing */ ;