Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bpftrace
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
bpftrace
Commits
e89957ff
Commit
e89957ff
authored
Dec 28, 2018
by
Brendan Gregg
Committed by
GitHub
Dec 28, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #297 from danobi/cmd_runner
Add -c CMD option
parents
d33e6f03
a3086a88
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
120 additions
and
5 deletions
+120
-5
man/man8/bpftrace.8
man/man8/bpftrace.8
+10
-1
src/bpftrace.cpp
src/bpftrace.cpp
+88
-0
src/bpftrace.h
src/bpftrace.h
+4
-1
src/main.cpp
src/main.cpp
+18
-3
No files found.
man/man8/bpftrace.8
View file @
e89957ff
...
...
@@ -60,7 +60,12 @@ Execute PROGRAM.
.
.TP
\fB\-p PID\fR
Process ID for enabling USDT probes.
Enable USDT probes on PID. Will terminate bpftrace on PID termination. Note this is not a global PID filter on probes.
.
.TP
\fB\-c CMD\fR
Helper to run CMD. Equivalent to manually running CMD and then giving passing the PID to -p. This is useful to ensure
you've traced at least the duration CMD's execution. You must provide an absolute path for the executable.
.
.TP
\fB\-v\fR
...
...
@@ -85,6 +90,10 @@ List probes containing "sleep".
Trace processes calling sleep.
.
.TP
\fBbpftrace \-c \'sleep 5\' \-e \'kprobe:do_nanosleep { printf("PID %d sleeping\en", pid); }\'\fR
run "sleep 5" in a new process and then trace processes calling sleep.
.
.TP
\fBbpftrace \-e \'tracepoint:raw_syscalls:sys_enter { @[comm]=count(); }\'\fR
Count syscalls by process name.
.
...
...
src/bpftrace.cpp
View file @
e89957ff
...
...
@@ -10,7 +10,10 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/prctl.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include "bcc_syms.h"
#include "perf_reader.h"
...
...
@@ -21,11 +24,25 @@
#include "triggers.h"
#include "resolve_cgroupid.h"
extern
char
**
environ
;
namespace
bpftrace
{
DebugLevel
bt_debug
=
DebugLevel
::
kNone
;
bool
bt_verbose
=
false
;
BPFtrace
::~
BPFtrace
()
{
for
(
int
pid
:
child_pids_
)
{
// We don't care if waitpid returns any errors. We're just trying
// to make a best effort here. It's not like we could recover from
// an error.
int
status
;
waitpid
(
pid
,
&
status
,
0
);
}
}
int
BPFtrace
::
add_probe
(
ast
::
Probe
&
p
)
{
for
(
auto
attach_point
:
*
p
.
attach_points
)
...
...
@@ -427,6 +444,21 @@ int BPFtrace::run(std::unique_ptr<BpfOrc> bpforc)
if
(
epollfd
<
0
)
return
epollfd
;
// Spawn a child process if we've been passed a command to run
if
(
cmd_
.
size
())
{
auto
args
=
split_string
(
cmd_
,
' '
);
int
pid
=
spawn_child
(
args
);
if
(
pid
<
0
)
{
std
::
cerr
<<
"Failed to spawn child="
<<
cmd_
<<
std
::
endl
;
return
pid
;
}
child_pids_
.
emplace_back
(
pid
);
pid_
=
pid
;
}
BEGIN_trigger
();
// NOTE (mmarchini): Apparently the kernel fires kprobe_events in the reverse
...
...
@@ -1079,6 +1111,56 @@ int BPFtrace::print_lhist(const std::vector<uint64_t> &values, int min, int max,
return
0
;
}
int
BPFtrace
::
spawn_child
(
const
std
::
vector
<
std
::
string
>&
args
)
{
static
const
int
maxargs
=
256
;
char
*
argv
[
maxargs
];
// Convert vector of strings into raw array of C-strings for execve(2)
int
idx
=
0
;
for
(
const
auto
&
arg
:
args
)
{
if
(
idx
==
maxargs
-
1
)
{
std
::
cerr
<<
"Too many args passed into spawn_child ("
<<
args
.
size
()
<<
" > "
<<
maxargs
-
1
<<
")"
<<
std
::
endl
;
return
-
1
;
}
argv
[
idx
]
=
const_cast
<
char
*>
(
arg
.
c_str
());
++
idx
;
}
argv
[
idx
]
=
nullptr
;
// must be null terminated
// Fork and exec
int
ret
=
fork
();
if
(
ret
==
0
)
{
// Receive SIGTERM if parent dies
//
// Useful if user doesn't kill the bpftrace process group
if
(
prctl
(
PR_SET_PDEATHSIG
,
SIGTERM
))
perror
(
"prctl(PR_SET_PDEATHSIG)"
);
if
(
execve
(
argv
[
0
],
argv
,
environ
))
{
perror
(
"execve"
);
return
-
1
;
}
}
else
if
(
ret
>
0
)
{
return
ret
;
}
else
{
perror
(
"fork"
);
return
-
1
;
}
return
-
1
;
// silence end of control compiler warning
}
std
::
string
BPFtrace
::
hist_index_label
(
int
power
)
{
char
suffix
=
'\0'
;
...
...
@@ -1477,6 +1559,12 @@ bool BPFtrace::is_pid_alive(int pid)
throw
std
::
runtime_error
(
"failed to snprintf"
);
}
// Do a nonblocking wait on the pid just in case it's our child and it
// has exited. We don't really care about any errors, we're just trying
// to make a best effort.
int
status
;
waitpid
(
pid
,
&
status
,
WNOHANG
);
int
fd
=
open
(
buf
,
0
,
O_RDONLY
);
if
(
fd
<
0
&&
errno
==
ENOENT
)
{
...
...
src/bpftrace.h
View file @
e89957ff
...
...
@@ -50,7 +50,7 @@ class BPFtrace
{
public:
BPFtrace
()
:
ncpus_
(
ebpf
::
get_possible_cpus
().
size
())
{
}
virtual
~
BPFtrace
()
{
}
virtual
~
BPFtrace
()
;
virtual
int
add_probe
(
ast
::
Probe
&
p
);
int
num_probes
()
const
;
int
run
(
std
::
unique_ptr
<
BpfOrc
>
bpforc
);
...
...
@@ -68,6 +68,7 @@ public:
std
::
string
resolve_probe
(
uint64_t
probe_id
);
uint64_t
resolve_cgroupid
(
const
std
::
string
&
path
);
std
::
vector
<
uint64_t
>
get_arg_values
(
std
::
vector
<
Field
>
args
,
uint8_t
*
arg_data
);
std
::
string
cmd_
;
int
pid_
{
0
};
std
::
map
<
std
::
string
,
std
::
unique_ptr
<
IMap
>>
maps_
;
...
...
@@ -97,6 +98,7 @@ private:
std
::
map
<
int
,
void
*>
pid_sym_
;
int
ncpus_
;
int
online_cpus_
;
std
::
vector
<
int
>
child_pids_
;
std
::
unique_ptr
<
AttachedProbe
>
attach_probe
(
Probe
&
probe
,
const
BpfOrc
&
bpforc
);
int
setup_perf_events
();
...
...
@@ -118,6 +120,7 @@ private:
static
std
::
string
lhist_index_label
(
int
number
);
static
std
::
vector
<
std
::
string
>
split_string
(
std
::
string
&
str
,
char
split_by
);
std
::
vector
<
uint8_t
>
find_empty_key
(
IMap
&
map
,
size_t
size
)
const
;
static
int
spawn_child
(
const
std
::
vector
<
std
::
string
>&
args
);
static
bool
is_pid_alive
(
int
pid
);
};
...
...
src/main.cpp
View file @
e89957ff
...
...
@@ -25,7 +25,8 @@ void usage()
std
::
cerr
<<
" -e 'program' execute this program"
<<
std
::
endl
;
std
::
cerr
<<
" -h show this help message"
<<
std
::
endl
;
std
::
cerr
<<
" -l [search] list probes"
<<
std
::
endl
;
std
::
cerr
<<
" -p PID PID for enabling USDT probes"
<<
std
::
endl
;
std
::
cerr
<<
" -p PID enable USDT probes on PID"
<<
std
::
endl
;
std
::
cerr
<<
" -c 'CMD' run CMD and enable USDT probes on resulting process"
<<
std
::
endl
;
std
::
cerr
<<
" -v verbose messages"
<<
std
::
endl
<<
std
::
endl
;
std
::
cerr
<<
"EXAMPLES:"
<<
std
::
endl
;
std
::
cerr
<<
"bpftrace -l '*sleep*'"
<<
std
::
endl
;
...
...
@@ -56,12 +57,13 @@ int main(int argc, char *argv[])
{
int
err
;
Driver
driver
;
char
*
pid_str
=
NULL
;
char
*
pid_str
=
nullptr
;
char
*
cmd_str
=
nullptr
;
bool
listing
=
false
;
std
::
string
script
,
search
;
int
c
;
while
((
c
=
getopt
(
argc
,
argv
,
"de:hlp:v"
))
!=
-
1
)
while
((
c
=
getopt
(
argc
,
argv
,
"de:hlp:v
c:
"
))
!=
-
1
)
{
switch
(
c
)
{
...
...
@@ -84,6 +86,9 @@ int main(int argc, char *argv[])
case
'l'
:
listing
=
true
;
break
;
case
'c'
:
cmd_str
=
optarg
;
break
;
default:
usage
();
return
1
;
...
...
@@ -97,6 +102,13 @@ int main(int argc, char *argv[])
return
1
;
}
if
(
cmd_str
&&
pid_str
)
{
std
::
cerr
<<
"USAGE: Cannot use both -c and -p."
<<
std
::
endl
;
usage
();
return
1
;
}
// Listing probes
if
(
listing
)
{
...
...
@@ -152,6 +164,9 @@ int main(int argc, char *argv[])
if
(
pid_str
)
bpftrace
.
pid_
=
atoi
(
pid_str
);
if
(
cmd_str
)
bpftrace
.
cmd_
=
cmd_str
;
TracepointFormatParser
::
parse
(
driver
.
root_
);
if
(
bt_debug
!=
DebugLevel
::
kNone
)
...
...
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