Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
a0691b11
Commit
a0691b11
authored
Sep 17, 2002
by
Daniel Jacobowitz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new ptrace event tracing mechanism
parent
e6f9f840
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
98 additions
and
6 deletions
+98
-6
fs/binfmt_aout.c
fs/binfmt_aout.c
+6
-2
fs/binfmt_elf.c
fs/binfmt_elf.c
+6
-2
include/linux/ptrace.h
include/linux/ptrace.h
+12
-0
include/linux/sched.h
include/linux/sched.h
+6
-0
kernel/fork.c
kernel/fork.c
+29
-0
kernel/ptrace.c
kernel/ptrace.c
+39
-2
No files found.
fs/binfmt_aout.c
View file @
a0691b11
...
...
@@ -425,8 +425,12 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
regs
->
gp
=
ex
.
a_gpvalue
;
#endif
start_thread
(
regs
,
ex
.
a_entry
,
current
->
mm
->
start_stack
);
if
(
current
->
ptrace
&
PT_PTRACED
)
send_sig
(
SIGTRAP
,
current
,
0
);
if
(
unlikely
(
current
->
ptrace
&
PT_PTRACED
))
{
if
(
current
->
ptrace
&
PT_TRACE_EXEC
)
ptrace_notify
((
PTRACE_EVENT_EXEC
<<
8
)
|
SIGTRAP
);
else
send_sig
(
SIGTRAP
,
current
,
0
);
}
return
0
;
}
...
...
fs/binfmt_elf.c
View file @
a0691b11
...
...
@@ -792,8 +792,12 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
#endif
start_thread
(
regs
,
elf_entry
,
bprm
->
p
);
if
(
current
->
ptrace
&
PT_PTRACED
)
send_sig
(
SIGTRAP
,
current
,
0
);
if
(
unlikely
(
current
->
ptrace
&
PT_PTRACED
))
{
if
(
current
->
ptrace
&
PT_TRACE_EXEC
)
ptrace_notify
((
PTRACE_EVENT_EXEC
<<
8
)
|
SIGTRAP
);
else
send_sig
(
SIGTRAP
,
current
,
0
);
}
retval
=
0
;
out:
return
retval
;
...
...
include/linux/ptrace.h
View file @
a0691b11
...
...
@@ -25,9 +25,20 @@
/* 0x4200-0x4300 are reserved for architecture-independent additions. */
#define PTRACE_SETOPTIONS 0x4200
#define PTRACE_GETEVENTMSG 0x4201
/* options set using PTRACE_SETOPTIONS */
#define PTRACE_O_TRACESYSGOOD 0x00000001
#define PTRACE_O_TRACEFORK 0x00000002
#define PTRACE_O_TRACEVFORK 0x00000004
#define PTRACE_O_TRACECLONE 0x00000008
#define PTRACE_O_TRACEEXEC 0x00000010
/* 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
#include <asm/ptrace.h>
#include <linux/sched.h>
...
...
@@ -39,6 +50,7 @@ extern int ptrace_detach(struct task_struct *, unsigned int);
extern
void
ptrace_disable
(
struct
task_struct
*
);
extern
int
ptrace_check_attach
(
struct
task_struct
*
task
,
int
kill
);
extern
int
ptrace_request
(
struct
task_struct
*
child
,
long
request
,
long
addr
,
long
data
);
extern
void
ptrace_notify
(
int
exit_code
);
extern
void
__ptrace_link
(
struct
task_struct
*
child
,
struct
task_struct
*
new_parent
);
extern
void
__ptrace_unlink
(
struct
task_struct
*
child
);
...
...
include/linux/sched.h
View file @
a0691b11
...
...
@@ -397,6 +397,8 @@ struct task_struct {
/* journalling filesystem info */
void
*
journal_info
;
struct
dentry
*
proc_dentry
;
unsigned
long
ptrace_message
;
};
extern
void
__put_task_struct
(
struct
task_struct
*
tsk
);
...
...
@@ -435,6 +437,10 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0)
#define PT_DTRACE 0x00000002
/* delayed trace (used on m68k, i386) */
#define PT_TRACESYSGOOD 0x00000004
#define PT_PTRACE_CAP 0x00000008
/* ptracer can follow suid-exec */
#define PT_TRACE_FORK 0x00000010
#define PT_TRACE_VFORK 0x00000020
#define PT_TRACE_CLONE 0x00000040
#define PT_TRACE_EXEC 0x00000080
/*
* Limit the stack by to some sane default: root can always
...
...
kernel/fork.c
View file @
a0691b11
...
...
@@ -923,6 +923,22 @@ static struct task_struct *copy_process(unsigned long clone_flags,
goto
fork_out
;
}
static
inline
int
fork_traceflag
(
unsigned
clone_flags
)
{
if
(
clone_flags
&
(
CLONE_UNTRACED
|
CLONE_IDLETASK
))
return
0
;
else
if
(
clone_flags
&
CLONE_VFORK
)
{
if
(
current
->
ptrace
&
PT_TRACE_VFORK
)
return
PTRACE_EVENT_VFORK
;
}
else
if
((
clone_flags
&
CSIGNAL
)
!=
SIGCHLD
)
{
if
(
current
->
ptrace
&
PT_TRACE_CLONE
)
return
PTRACE_EVENT_CLONE
;
}
else
if
(
current
->
ptrace
&
PT_TRACE_FORK
)
return
PTRACE_EVENT_FORK
;
return
0
;
}
/*
* Ok, this is the main fork-routine.
*
...
...
@@ -936,6 +952,13 @@ struct task_struct *do_fork(unsigned long clone_flags,
int
*
user_tid
)
{
struct
task_struct
*
p
;
int
trace
=
0
;
if
(
unlikely
(
current
->
ptrace
))
{
trace
=
fork_traceflag
(
clone_flags
);
if
(
trace
)
clone_flags
|=
CLONE_PTRACE
;
}
p
=
copy_process
(
clone_flags
,
stack_start
,
regs
,
stack_size
,
user_tid
);
if
(
!
IS_ERR
(
p
))
{
...
...
@@ -951,6 +974,12 @@ struct task_struct *do_fork(unsigned long clone_flags,
wake_up_forked_process
(
p
);
/* do this last */
++
total_forks
;
if
(
unlikely
(
trace
))
{
current
->
ptrace_message
=
(
unsigned
long
)
p
->
pid
;
ptrace_notify
((
trace
<<
8
)
|
SIGTRAP
);
}
if
(
clone_flags
&
CLONE_VFORK
)
wait_for_completion
(
&
vfork
);
else
...
...
kernel/ptrace.c
View file @
a0691b11
...
...
@@ -249,14 +249,37 @@ int ptrace_writedata(struct task_struct *tsk, char * src, unsigned long dst, int
return
copied
;
}
int
ptrace_setoptions
(
struct
task_struct
*
child
,
long
data
)
static
int
ptrace_setoptions
(
struct
task_struct
*
child
,
long
data
)
{
if
(
data
&
PTRACE_O_TRACESYSGOOD
)
child
->
ptrace
|=
PT_TRACESYSGOOD
;
else
child
->
ptrace
&=
~
PT_TRACESYSGOOD
;
if
((
data
&
PTRACE_O_TRACESYSGOOD
)
!=
data
)
if
(
data
&
PTRACE_O_TRACEFORK
)
child
->
ptrace
|=
PT_TRACE_FORK
;
else
child
->
ptrace
&=
~
PT_TRACE_FORK
;
if
(
data
&
PTRACE_O_TRACEVFORK
)
child
->
ptrace
|=
PT_TRACE_VFORK
;
else
child
->
ptrace
&=
~
PT_TRACE_VFORK
;
if
(
data
&
PTRACE_O_TRACECLONE
)
child
->
ptrace
|=
PT_TRACE_CLONE
;
else
child
->
ptrace
&=
~
PT_TRACE_CLONE
;
if
(
data
&
PTRACE_O_TRACEEXEC
)
child
->
ptrace
|=
PT_TRACE_EXEC
;
else
child
->
ptrace
&=
~
PT_TRACE_EXEC
;
if
((
data
&
(
PTRACE_O_TRACESYSGOOD
|
PTRACE_O_TRACEFORK
|
PTRACE_O_TRACEVFORK
|
PTRACE_O_TRACECLONE
|
PTRACE_O_TRACEEXEC
))
!=
data
)
return
-
EINVAL
;
return
0
;
...
...
@@ -274,9 +297,23 @@ int ptrace_request(struct task_struct *child, long request,
case
PTRACE_SETOPTIONS
:
ret
=
ptrace_setoptions
(
child
,
data
);
break
;
case
PTRACE_GETEVENTMSG
:
ret
=
put_user
(
child
->
ptrace_message
,
(
unsigned
long
*
)
data
);
break
;
default:
break
;
}
return
ret
;
}
void
ptrace_notify
(
int
exit_code
)
{
BUG_ON
(
!
(
current
->
ptrace
&
PT_PTRACED
));
/* Let the debugger run. */
current
->
exit_code
=
exit_code
;
set_current_state
(
TASK_STOPPED
);
notify_parent
(
current
,
SIGCHLD
);
schedule
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment