Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/checkpoint-restore/criu.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Vagin <avagin@gmail.com>2022-08-08 02:36:15 +0300
committerAndrei Vagin <avagin@gmail.com>2022-08-15 08:23:49 +0300
commit40f5d9b4592788f9975605625cc749dea7f2bec2 (patch)
tree7534ffcc23429fe38ee09411b42cf74a3f32b0c8
parent373281f50dfa9069058aa0bfde05c4f4a40ddd8a (diff)
compel: clear a breakpoint right after it's been triggered
Breakpoints are used to stop as close as possible to a target system call. First, we don't need it after this point. Second, PTRACE_CONT can't pass through a breakpoint on arm64. Signed-off-by: Andrei Vagin <avagin@gmail.com>
-rw-r--r--compel/src/lib/infect.c15
-rw-r--r--criu/cr-restore.c21
2 files changed, 11 insertions, 25 deletions
diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
index 7d7865480..6413a1860 100644
--- a/compel/src/lib/infect.c
+++ b/compel/src/lib/infect.c
@@ -1418,9 +1418,6 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
if (compel_stop_on_syscall(1, __NR(rt_sigreturn, 0), __NR(rt_sigreturn, 1)))
return -1;
- if (ptrace_flush_breakpoints(pid))
- return -1;
-
/*
* All signals are unblocked now. The kernel notifies about leaving
* syscall before starting to deliver signals. All parasite code are
@@ -1650,8 +1647,18 @@ int compel_stop_on_syscall(int tasks, const int sys_nr, const int sys_nr_compat)
pr_debug("%d was trapped\n", pid);
- if ((WSTOPSIG(status) & PTRACE_SYSCALL_TRAP) == 0)
+ if ((WSTOPSIG(status) & PTRACE_SYSCALL_TRAP) == 0) {
+ /*
+ * On some platforms such as ARM64, it is impossible to
+ * pass through a breakpoint, so let's clear it right
+ * after it has been triggered.
+ */
+ if (ptrace_flush_breakpoints(pid)) {
+ pr_err("Unable to clear breakpoints\n");
+ return -1;
+ }
goto goon;
+ }
if (trace == TRACE_EXIT) {
trace = TRACE_ENTER;
pr_debug("`- Expecting exit\n");
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 9a1b23999..9c480be78 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -2071,24 +2071,6 @@ static int catch_tasks(bool root_seized)
return 0;
}
-static int clear_breakpoints(void)
-{
- struct pstree_item *item;
- int ret = 0, i;
-
- if (fault_injected(FI_NO_BREAKPOINTS))
- return 0;
-
- for_each_pstree_item(item) {
- if (!task_alive(item))
- continue;
- for (i = 0; i < item->nr_threads; i++)
- ret |= ptrace_flush_breakpoints(item->threads[i].real);
- }
-
- return ret;
-}
-
static void finalize_restore(void)
{
struct pstree_item *item;
@@ -2459,9 +2441,6 @@ skip_ns_bouncing:
goto out_kill_network_unlocked;
}
- if (clear_breakpoints())
- pr_err("Unable to flush breakpoints\n");
-
finalize_restore();
/*
* Some external devices such as GPUs might need a very late