Commit 45c1a159 authored by Daniel Jacobowitz's avatar Daniel Jacobowitz

Add PTRACE_O_TRACEVFORKDONE and PTRACE_O_TRACEEXIT facilities.

parent 762cc267
......@@ -35,12 +35,16 @@
#define PTRACE_O_TRACEVFORK 0x00000004
#define PTRACE_O_TRACECLONE 0x00000008
#define PTRACE_O_TRACEEXEC 0x00000010
#define PTRACE_O_TRACEVFORKDONE 0x00000020
#define PTRACE_O_TRACEEXIT 0x00000040
/* Wait extended result codes for the above trace options. */
#define PTRACE_EVENT_FORK 1
#define PTRACE_EVENT_VFORK 2
#define PTRACE_EVENT_CLONE 3
#define PTRACE_EVENT_EXEC 4
#define PTRACE_EVENT_VFORK_DONE 5
#define PTRACE_EVENT_EXIT 6
#include <asm/ptrace.h>
#include <linux/sched.h>
......
......@@ -441,6 +441,8 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
#define PT_TRACE_VFORK 0x00000020
#define PT_TRACE_CLONE 0x00000040
#define PT_TRACE_EXEC 0x00000080
#define PT_TRACE_VFORK_DONE 0x00000100
#define PT_TRACE_EXIT 0x00000200
#if CONFIG_SMP
extern void set_cpus_allowed(task_t *p, unsigned long new_mask);
......
......@@ -653,6 +653,9 @@ NORET_TYPE void do_exit(long code)
profile_exit_task(tsk);
if (unlikely(current->ptrace & PT_TRACE_EXIT))
ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP);
fake_volatile:
acct_process(code);
__exit_mm(tsk);
......
......@@ -1046,9 +1046,11 @@ struct task_struct *do_fork(unsigned long clone_flags,
ptrace_notify ((trace << 8) | SIGTRAP);
}
if (clone_flags & CLONE_VFORK)
if (clone_flags & CLONE_VFORK) {
wait_for_completion(&vfork);
else
if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE))
ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
} else
/*
* Let the child process run first, to avoid most of the
* COW overhead when the child exec()s afterwards.
......
......@@ -277,9 +277,20 @@ static int ptrace_setoptions(struct task_struct *child, long data)
else
child->ptrace &= ~PT_TRACE_EXEC;
if (data & PTRACE_O_TRACEVFORKDONE)
child->ptrace |= PT_TRACE_VFORK_DONE;
else
child->ptrace &= ~PT_TRACE_VFORK_DONE;
if (data & PTRACE_O_TRACEEXIT)
child->ptrace |= PT_TRACE_EXIT;
else
child->ptrace &= ~PT_TRACE_EXIT;
if ((data & (PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEFORK
| PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE
| PTRACE_O_TRACEEXEC))
| PTRACE_O_TRACEEXEC | PTRACE_O_TRACEEXIT
| PTRACE_O_TRACEVFORKDONE))
!= data)
return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment