[CRIU] [PATCH] ptrace: Factor out pie stopping code
Andrey Vagin
avagin at parallels.com
Mon Sep 22 02:51:03 PDT 2014
Acked-by: Andrey Vagin <avagin at parallels.com>
On Mon, Sep 22, 2014 at 01:37:40PM +0400, Pavel Emelyanov wrote:
> Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
>
> ---
>
> diff --git a/cr-restore.c b/cr-restore.c
> index 809564b..2716b2d 100644
> --- a/cr-restore.c
> +++ b/cr-restore.c
> @@ -1579,20 +1579,9 @@ static int attach_to_tasks(bool root_seized, enum trace_flags *flag)
> return -1;
> }
>
> - ret = ptrace_set_breakpoint(pid, item->rst->breakpoint);
> + ret = ptrace_stop_pie(pid, item->rst->breakpoint, flag);
> if (ret < 0)
> return -1;
> -
> - /* A breakpoint was not set */
> - if (ret > 0)
> - *flag = TRACE_EXIT;
> - else {
> - *flag = TRACE_ENTER;
> - if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL)) {
> - pr_perror("Unable to start %d", pid);
> - return -1;
> - }
> - }
> }
> }
>
> diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
> index 5d2df08..62d0ba4 100644
> --- a/include/parasite-syscall.h
> +++ b/include/parasite-syscall.h
> @@ -139,5 +139,6 @@ enum trace_flags {
>
> extern int parasite_stop_on_syscall(int tasks, int sys_nr, enum trace_flags trace);
> extern int parasite_unmap(struct parasite_ctl *ctl, unsigned long addr);
> +extern int ptrace_stop_pie(pid_t pid, void *addr, enum trace_flags *tf);
>
> #endif /* __CR_PARASITE_SYSCALL_H__ */
> diff --git a/parasite-syscall.c b/parasite-syscall.c
> index 37e9db0..c7fc11f 100644
> --- a/parasite-syscall.c
> +++ b/parasite-syscall.c
> @@ -871,21 +871,9 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
> return -1;
>
> /* Go to sigreturn as closer as we can */
> - ret = ptrace_set_breakpoint(pid, ctl->sigreturn_addr);
> + ret = ptrace_stop_pie(pid, ctl->sigreturn_addr, &flag);
> if (ret < 0)
> return ret;
> - if (ret > 0)
> - flag = TRACE_EXIT;
> - else {
> - /* Start tracing syscalls */
> - ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
> - if (ret) {
> - pr_perror("ptrace");
> - return -1;
> - }
> -
> - flag = TRACE_ENTER;
> - }
>
> if (parasite_stop_on_syscall(1, __NR_rt_sigreturn, flag))
> return -1;
> @@ -1235,3 +1223,34 @@ err_restore:
> parasite_cure_seized(ctl);
> return NULL;
> }
> +
> +int ptrace_stop_pie(pid_t pid, void *addr, enum trace_flags *tf)
> +{
> + int ret;
> +
> + ret = ptrace_set_breakpoint(pid, addr);
> + if (ret < 0)
> + return ret;
> +
> + if (ret > 0) {
> + /*
> + * PIE will stop on a breakpoint, next
> + * stop after that will be syscall enter.
> + */
> + *tf = TRACE_EXIT;
> + return 0;
> + }
> +
> + /*
> + * No breakpoints available -- start tracing it
> + * in a per-syscall manner.
> + */
> + ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
> + if (ret) {
> + pr_perror("ptrace");
> + return -1;
> + }
> +
> + *tf = TRACE_ENTER;
> + return 0;
> +}
>
More information about the CRIU
mailing list