[CRIU] [PATCH 5/6] dump: try to interrupt a task as soon as possible

Pavel Emelyanov xemul at parallels.com
Thu Dec 19 10:50:56 PST 2013


On 12/19/2013 04:59 PM, Andrey Vagin wrote:
> A task can die while we are reading /proc/pid/stat.

Task may as well die while we're checking for PTRACE_SEIZE ret code
being 0 or not. Where is the catch?

> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
>  ptrace.c | 30 ++++++++++++++++++------------
>  1 file changed, 18 insertions(+), 12 deletions(-)
> 
> diff --git a/ptrace.c b/ptrace.c
> index b3b8241..3df6ea0 100644
> --- a/ptrace.c
> +++ b/ptrace.c
> @@ -52,6 +52,14 @@ int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid)
>  
>  	ret = ptrace(PTRACE_SEIZE, pid, NULL, 0);
>  	ptrace_errno = errno;
> +	if (ret == 0) {
> +		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
> @@ -88,12 +96,6 @@ int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid)
>  		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:
>  	ret = wait4(pid, &status, __WALL, NULL);
>  	if (ret < 0) {
> @@ -145,31 +147,35 @@ try_again:
>  		ret = ptrace(PTRACE_CONT, pid, 0, 0);
>  		if (ret) {
>  			pr_perror("Unable to start process");
> -			goto err;
> +			goto err_stop;
>  		}
>  
>  		ret = wait4(pid, &status, __WALL, NULL);
>  		if (ret < 0) {
>  			pr_perror("SEIZE %d: can't wait task", pid);
> -			goto err;
> +			goto err_stop;
>  		}
>  
>  		if (ret != pid) {
>  			pr_err("SEIZE %d: wrong task attached (%d)\n", pid, ret);
> -			goto err;
> +			goto err_stop;
>  		}
>  
>  		if (!WIFSTOPPED(status)) {
>  			pr_err("SEIZE %d: task not stopped after seize\n", pid);
> -			goto err;
> +			goto err_stop;
>  		}
>  
>  		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:
> -	unseize_task(pid, TASK_STOPPED);
> +	ptrace(PTRACE_DETACH, pid, NULL, NULL);
>  	return -1;
>  }
>  
> 




More information about the CRIU mailing list