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;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ptrace_set_breakpoint(pid, item->rst->breakpoint);
|
ret = ptrace_stop_pie(pid, item->rst->breakpoint, flag);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return -1;
|
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_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 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__ */
|
#endif /* __CR_PARASITE_SYSCALL_H__ */
|
||||||
|
@ -871,21 +871,9 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Go to sigreturn as closer as we can */
|
/* 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)
|
if (ret < 0)
|
||||||
return ret;
|
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))
|
if (parasite_stop_on_syscall(1, __NR_rt_sigreturn, flag))
|
||||||
return -1;
|
return -1;
|
||||||
@ -1238,3 +1226,34 @@ err_restore:
|
|||||||
parasite_cure_seized(ctl);
|
parasite_cure_seized(ctl);
|
||||||
return NULL;
|
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