[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