[CRIU] [PATCH] ptrace: Factor out pie stopping code

Pavel Emelyanov xemul at parallels.com
Mon Sep 22 02:37:40 PDT 2014


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