linux: implement PTRACE_EVENT_EXEC

This fixes strace(1) from Ubuntu Focal.

Reviewed By:	jhb
Sponsored By:	EPSRC
Differential Revision:	https://reviews.freebsd.org/D32367

(cherry picked from commit 6e66030c4c)
This commit is contained in:
Edward Tomasz Napierala 2021-10-23 19:13:14 +01:00
parent 3b7841de78
commit fc36cd43fd
2 changed files with 19 additions and 2 deletions

View File

@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
#define LINUX_PTRACE_SEIZE 0x4206
#define LINUX_PTRACE_GET_SYSCALL_INFO 0x420e
#define LINUX_PTRACE_EVENT_EXEC 4
#define LINUX_PTRACE_EVENT_EXIT 6
#define LINUX_PTRACE_O_TRACESYSGOOD 1
@ -152,8 +153,12 @@ linux_ptrace_status(struct thread *td, pid_t pid, int status)
lwpinfo.pl_flags & PL_FLAG_SCE)
status |= (LINUX_SIGTRAP | 0x80) << 8;
if ((pem->ptrace_flags & LINUX_PTRACE_O_TRACESYSGOOD) &&
lwpinfo.pl_flags & PL_FLAG_SCX)
status |= (LINUX_SIGTRAP | 0x80) << 8;
lwpinfo.pl_flags & PL_FLAG_SCX) {
if (lwpinfo.pl_flags & PL_FLAG_EXEC)
status |= (LINUX_SIGTRAP | LINUX_PTRACE_EVENT_EXEC << 8) << 8;
else
status |= (LINUX_SIGTRAP | 0x80) << 8;
}
if ((pem->ptrace_flags & LINUX_PTRACE_O_TRACEEXIT) &&
lwpinfo.pl_flags & PL_FLAG_EXITED)
status |= (LINUX_SIGTRAP | LINUX_PTRACE_EVENT_EXIT << 8) << 8;

View File

@ -255,6 +255,18 @@ syscallret(struct thread *td)
if (__predict_false(traced ||
(td->td_dbgflags & (TDB_EXEC | TDB_FORK)) != 0)) {
PROC_LOCK(p);
/*
* Linux debuggers expect an additional stop for exec,
* between the usual syscall entry and exit. Raise
* the exec event now and then clear TDB_EXEC so that
* the next stop is reported as a syscall exit by
* linux_ptrace_status().
*/
if ((td->td_dbgflags & TDB_EXEC) != 0 &&
SV_PROC_ABI(td->td_proc) == SV_ABI_LINUX) {
ptracestop(td, SIGTRAP, NULL);
td->td_dbgflags &= ~TDB_EXEC;
}
/*
* If tracing the execed process, trap to the debugger
* so that breakpoints can be set before the program