mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-29 13:28:27 +00:00
ptrace: Factor out pie stopping code
Signed-off-by: Pavel Emelyanov <xemul@parallels.com> Acked-by: Andrey Vagin <avagin@parallels.com>
This commit is contained in:
parent
48fcc7994d
commit
ab50f6ac18
13
cr-restore.c
13
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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__ */
|
||||
|
@ -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;
|
||||
@ -1238,3 +1226,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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user