Commit dc914912 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

dump: try to stop a task as soon as possible

We read /proc/pid/status to determine a task state, but if a task is
running in this moment, its state may be changed.

This patch stops tasks before reading their /proc/pid/status
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent bf678790
...@@ -52,6 +52,15 @@ int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid) ...@@ -52,6 +52,15 @@ int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid)
ret = ptrace(PTRACE_SEIZE, pid, NULL, 0); ret = ptrace(PTRACE_SEIZE, pid, NULL, 0);
ptrace_errno = errno; ptrace_errno = errno;
if (ret == 0) {
/* Stop task before determing its state */
ret = ptrace(PTRACE_INTERRUPT, pid, NULL, NULL);
if (ret < 0) {
pr_perror("SEIZE %d: can't interrupt task", pid);
ptrace(PTRACE_DETACH, pid, NULL, NULL);
goto err;
}
}
/* /*
* It's ugly, but the ptrace API doesn't allow to distinguish * It's ugly, but the ptrace API doesn't allow to distinguish
...@@ -88,12 +97,6 @@ int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid) ...@@ -88,12 +97,6 @@ int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid)
goto err; goto err;
} }
ret = ptrace(PTRACE_INTERRUPT, pid, NULL, NULL);
if (ret < 0) {
pr_perror("SEIZE %d: can't interrupt task", pid);
goto err;
}
try_again: try_again:
ret = wait4(pid, &status, __WALL, NULL); ret = wait4(pid, &status, __WALL, NULL);
if (ret < 0) { if (ret < 0) {
...@@ -145,31 +148,35 @@ try_again: ...@@ -145,31 +148,35 @@ try_again:
ret = ptrace(PTRACE_CONT, pid, 0, 0); ret = ptrace(PTRACE_CONT, pid, 0, 0);
if (ret) { if (ret) {
pr_perror("Unable to start process"); pr_perror("Unable to start process");
goto err; goto err_stop;
} }
ret = wait4(pid, &status, __WALL, NULL); ret = wait4(pid, &status, __WALL, NULL);
if (ret < 0) { if (ret < 0) {
pr_perror("SEIZE %d: can't wait task", pid); pr_perror("SEIZE %d: can't wait task", pid);
goto err; goto err_stop;
} }
if (ret != pid) { if (ret != pid) {
pr_err("SEIZE %d: wrong task attached (%d)\n", pid, ret); pr_err("SEIZE %d: wrong task attached (%d)\n", pid, ret);
goto err; goto err_stop;
} }
if (!WIFSTOPPED(status)) { if (!WIFSTOPPED(status)) {
pr_err("SEIZE %d: task not stopped after seize\n", pid); pr_err("SEIZE %d: task not stopped after seize\n", pid);
goto err; goto err_stop;
} }
return TASK_STOPPED; return TASK_STOPPED;
} else {
pr_err("SEIZE %d: unsupported stop signal %d\n", pid, si.si_signo);
goto err;
} }
pr_err("SEIZE %d: unsupported stop signal %d\n", pid, si.si_signo); err_stop:
kill(pid, SIGSTOP);
err: err:
unseize_task(pid, TASK_STOPPED); ptrace(PTRACE_DETACH, pid, NULL, NULL);
return -1; return -1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment