Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bcc
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
bcc
Commits
b77915df
Commit
b77915df
authored
Jan 31, 2017
by
4ast
Committed by
GitHub
Jan 31, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #918 from derek0883/mybcc
Handling multiple concurrent probe users.
parents
199b341a
227b5b99
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
179 additions
and
130 deletions
+179
-130
src/cc/BPF.cc
src/cc/BPF.cc
+12
-21
src/cc/BPF.h
src/cc/BPF.h
+12
-17
src/cc/libbpf.c
src/cc/libbpf.c
+92
-25
src/cc/libbpf.h
src/cc/libbpf.h
+17
-8
src/lua/bcc/bpf.lua
src/lua/bcc/bpf.lua
+6
-13
src/lua/bcc/libbcc.lua
src/lua/bcc/libbcc.lua
+12
-6
src/python/bcc/__init__.py
src/python/bcc/__init__.py
+14
-24
src/python/bcc/libbcc.py
src/python/bcc/libbcc.py
+3
-3
tools/argdist.py
tools/argdist.py
+10
-12
tools/cpudist.py
tools/cpudist.py
+1
-1
No files found.
src/cc/BPF.cc
View file @
b77915df
...
...
@@ -147,7 +147,7 @@ StatusTuple BPF::detach_all() {
StatusTuple
BPF
::
attach_kprobe
(
const
std
::
string
&
kernel_func
,
const
std
::
string
&
probe_func
,
bpf_attach_type
attach_type
,
bpf_
probe_
attach_type
attach_type
,
pid_t
pid
,
int
cpu
,
int
group_fd
,
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
std
::
string
probe_event
=
get_kprobe_event
(
kernel_func
,
attach_type
);
...
...
@@ -157,11 +157,8 @@ StatusTuple BPF::attach_kprobe(const std::string& kernel_func,
int
probe_fd
;
TRY2
(
load_func
(
probe_func
,
BPF_PROG_TYPE_KPROBE
,
probe_fd
));
std
::
string
probe_event_desc
=
attach_type_prefix
(
attach_type
);
probe_event_desc
+=
":kprobes/"
+
probe_event
+
" "
+
kernel_func
;
void
*
res
=
bpf_attach_kprobe
(
probe_fd
,
probe_event
.
c_str
(),
probe_event_des
c
.
c_str
(),
bpf_attach_kprobe
(
probe_fd
,
attach_type
,
probe_event
.
c_str
(),
kernel_fun
c
.
c_str
(),
pid
,
cpu
,
group_fd
,
cb
,
cb_cookie
);
if
(
!
res
)
{
...
...
@@ -182,7 +179,7 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
const
std
::
string
&
symbol
,
const
std
::
string
&
probe_func
,
uint64_t
symbol_addr
,
bpf_attach_type
attach_type
,
bpf_
probe_
attach_type
attach_type
,
pid_t
pid
,
int
cpu
,
int
group_fd
,
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
bcc_symbol
sym
=
bcc_symbol
();
...
...
@@ -196,13 +193,9 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
int
probe_fd
;
TRY2
(
load_func
(
probe_func
,
BPF_PROG_TYPE_KPROBE
,
probe_fd
));
std
::
string
probe_event_desc
=
attach_type_prefix
(
attach_type
);
probe_event_desc
+=
":uprobes/"
+
probe_event
+
" "
;
probe_event_desc
+=
binary_path
+
":0x"
+
uint_to_hex
(
sym
.
offset
);
void
*
res
=
bpf_attach_uprobe
(
probe_fd
,
probe_event
.
c_str
(),
probe_event_desc
.
c_str
(),
pid
,
cpu
,
group_fd
,
cb
,
cb_cookie
);
bpf_attach_uprobe
(
probe_fd
,
attach_type
,
probe_event
.
c_str
(),
binary_path
.
c_str
(),
sym
.
offset
,
pid
,
cpu
,
group_fd
,
cb
,
cb_cookie
);
if
(
!
res
)
{
TRY2
(
unload_func
(
probe_func
));
...
...
@@ -325,7 +318,7 @@ StatusTuple BPF::attach_perf_event(uint32_t ev_type, uint32_t ev_config,
}
StatusTuple
BPF
::
detach_kprobe
(
const
std
::
string
&
kernel_func
,
bpf_attach_type
attach_type
)
{
bpf_
probe_
attach_type
attach_type
)
{
std
::
string
event
=
get_kprobe_event
(
kernel_func
,
attach_type
);
auto
it
=
kprobes_
.
find
(
event
);
...
...
@@ -341,7 +334,7 @@ StatusTuple BPF::detach_kprobe(const std::string& kernel_func,
StatusTuple
BPF
::
detach_uprobe
(
const
std
::
string
&
binary_path
,
const
std
::
string
&
symbol
,
uint64_t
symbol_addr
,
bpf_attach_type
attach_type
)
{
bpf_
probe_
attach_type
attach_type
)
{
bcc_symbol
sym
=
bcc_symbol
();
TRY2
(
check_binary_symbol
(
binary_path
,
symbol
,
symbol_addr
,
&
sym
));
...
...
@@ -423,7 +416,7 @@ void BPF::poll_perf_buffer(const std::string& name, int timeout) {
}
StatusTuple
BPF
::
load_func
(
const
std
::
string
&
func_name
,
enum
bpf_prog_type
type
,
int
&
fd
)
{
bpf_prog_type
type
,
int
&
fd
)
{
if
(
funcs_
.
find
(
func_name
)
!=
funcs_
.
end
())
{
fd
=
funcs_
[
func_name
];
return
StatusTuple
(
0
);
...
...
@@ -473,14 +466,14 @@ StatusTuple BPF::check_binary_symbol(const std::string& binary_path,
}
std
::
string
BPF
::
get_kprobe_event
(
const
std
::
string
&
kernel_func
,
bpf_attach_type
type
)
{
bpf_
probe_
attach_type
type
)
{
std
::
string
res
=
attach_type_prefix
(
type
)
+
"_"
;
res
+=
sanitize_str
(
kernel_func
,
&
BPF
::
kprobe_event_validator
);
return
res
;
}
std
::
string
BPF
::
get_uprobe_event
(
const
std
::
string
&
binary_path
,
uint64_t
offset
,
bpf_attach_type
type
)
{
uint64_t
offset
,
bpf_
probe_
attach_type
type
)
{
std
::
string
res
=
attach_type_prefix
(
type
)
+
"_"
;
res
+=
sanitize_str
(
binary_path
,
&
BPF
::
uprobe_path_validator
);
res
+=
"_0x"
+
uint_to_hex
(
offset
);
...
...
@@ -494,8 +487,7 @@ StatusTuple BPF::detach_kprobe_event(const std::string& event,
attr
.
reader_ptr
=
nullptr
;
}
TRY2
(
unload_func
(
attr
.
func
));
std
::
string
detach_event
=
"-:kprobes/"
+
event
;
if
(
bpf_detach_kprobe
(
detach_event
.
c_str
())
<
0
)
if
(
bpf_detach_kprobe
(
event
.
c_str
())
<
0
)
return
StatusTuple
(
-
1
,
"Unable to detach kprobe %s"
,
event
.
c_str
());
return
StatusTuple
(
0
);
}
...
...
@@ -507,8 +499,7 @@ StatusTuple BPF::detach_uprobe_event(const std::string& event,
attr
.
reader_ptr
=
nullptr
;
}
TRY2
(
unload_func
(
attr
.
func
));
std
::
string
detach_event
=
"-:uprobes/"
+
event
;
if
(
bpf_detach_uprobe
(
detach_event
.
c_str
())
<
0
)
if
(
bpf_detach_uprobe
(
event
.
c_str
())
<
0
)
return
StatusTuple
(
-
1
,
"Unable to detach uprobe %s"
,
event
.
c_str
());
return
StatusTuple
(
0
);
}
...
...
src/cc/BPF.h
View file @
b77915df
...
...
@@ -29,11 +29,6 @@
namespace
ebpf
{
enum
class
bpf_attach_type
{
probe_entry
,
probe_return
};
struct
open_probe_t
{
void
*
reader_ptr
;
std
::
string
func
;
...
...
@@ -56,23 +51,23 @@ public:
StatusTuple
attach_kprobe
(
const
std
::
string
&
kernel_func
,
const
std
::
string
&
probe_func
,
bpf_
attach_type
attach_type
=
bpf_attach_type
::
probe_entry
,
bpf_
probe_attach_type
=
BPF_PROBE_ENTRY
,
pid_t
pid
=
-
1
,
int
cpu
=
0
,
int
group_fd
=
-
1
,
perf_reader_cb
cb
=
nullptr
,
void
*
cb_cookie
=
nullptr
);
StatusTuple
detach_kprobe
(
const
std
::
string
&
kernel_func
,
bpf_
attach_type
attach_type
=
bpf_attach_type
::
probe_entry
);
bpf_
probe_attach_type
attach_type
=
BPF_PROBE_ENTRY
);
StatusTuple
attach_uprobe
(
const
std
::
string
&
binary_path
,
const
std
::
string
&
symbol
,
const
std
::
string
&
probe_func
,
uint64_t
symbol_addr
=
0
,
bpf_
attach_type
attach_type
=
bpf_attach_type
::
probe_entry
,
bpf_
probe_attach_type
attach_type
=
BPF_PROBE_ENTRY
,
pid_t
pid
=
-
1
,
int
cpu
=
0
,
int
group_fd
=
-
1
,
perf_reader_cb
cb
=
nullptr
,
void
*
cb_cookie
=
nullptr
);
StatusTuple
detach_uprobe
(
const
std
::
string
&
binary_path
,
const
std
::
string
&
symbol
,
uint64_t
symbol_addr
=
0
,
bpf_
attach_type
attach_type
=
bpf_attach_type
::
probe_entry
);
bpf_
probe_attach_type
attach_type
=
BPF_PROBE_ENTRY
);
StatusTuple
attach_usdt
(
const
USDT
&
usdt
,
pid_t
pid
=
-
1
,
int
cpu
=
0
,
int
group_fd
=
-
1
);
StatusTuple
detach_usdt
(
const
USDT
&
usdt
);
...
...
@@ -111,9 +106,9 @@ private:
StatusTuple
unload_func
(
const
std
::
string
&
func_name
);
std
::
string
get_kprobe_event
(
const
std
::
string
&
kernel_func
,
bpf_attach_type
type
);
bpf_
probe_
attach_type
type
);
std
::
string
get_uprobe_event
(
const
std
::
string
&
binary_path
,
uint64_t
offset
,
bpf_attach_type
type
);
bpf_
probe_
attach_type
type
);
StatusTuple
detach_kprobe_event
(
const
std
::
string
&
event
,
open_probe_t
&
attr
);
StatusTuple
detach_uprobe_event
(
const
std
::
string
&
event
,
open_probe_t
&
attr
);
...
...
@@ -121,21 +116,21 @@ private:
open_probe_t
&
attr
);
StatusTuple
detach_perf_event_all_cpu
(
open_probe_t
&
attr
);
std
::
string
attach_type_debug
(
bpf_attach_type
type
)
{
std
::
string
attach_type_debug
(
bpf_
probe_
attach_type
type
)
{
switch
(
type
)
{
case
bpf_attach_type
:
:
probe_entry
:
case
BPF_PROBE_ENTRY
:
return
""
;
case
bpf_attach_type
:
:
probe_return
:
case
BPF_PROBE_RETURN
:
return
"return "
;
}
return
"ERROR"
;
}
std
::
string
attach_type_prefix
(
bpf_attach_type
type
)
{
std
::
string
attach_type_prefix
(
bpf_
probe_
attach_type
type
)
{
switch
(
type
)
{
case
bpf_attach_type
:
:
probe_entry
:
case
BPF_PROBE_ENTRY
:
return
"p"
;
case
bpf_attach_type
:
:
probe_return
:
case
BPF_PROBE_RETURN
:
return
"r"
;
}
return
"ERROR"
;
...
...
src/cc/libbpf.c
View file @
b77915df
...
...
@@ -35,6 +35,8 @@
#include <sys/resource.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "libbpf.h"
#include "perf_reader.h"
...
...
@@ -336,14 +338,19 @@ static int bpf_attach_tracing_event(int progfd, const char *event_path,
return
0
;
}
static
void
*
bpf_attach_probe
(
int
progfd
,
const
char
*
event
,
const
char
*
event_desc
,
const
char
*
event_type
,
pid_t
pid
,
int
cpu
,
int
group_fd
,
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
void
*
bpf_attach_kprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
const
char
*
ev_name
,
const
char
*
fn_name
,
pid_t
pid
,
int
cpu
,
int
group_fd
,
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
int
kfd
;
char
buf
[
256
];
char
new_name
[
128
];
struct
perf_reader
*
reader
=
NULL
;
static
char
*
event_type
=
"kprobe"
;
int
n
;
snprintf
(
new_name
,
sizeof
(
new_name
),
"%s_bcc_%d"
,
ev_name
,
getpid
());
reader
=
perf_reader_new
(
cb
,
NULL
,
cb_cookie
);
if
(
!
reader
)
goto
error
;
...
...
@@ -355,8 +362,9 @@ static void * bpf_attach_probe(int progfd, const char *event,
goto
error
;
}
if
(
write
(
kfd
,
event_desc
,
strlen
(
event_desc
))
<
0
)
{
fprintf
(
stderr
,
"write(%s,
\"
%s
\"
) failed: %s
\n
"
,
buf
,
event_desc
,
strerror
(
errno
));
snprintf
(
buf
,
sizeof
(
buf
),
"%c:%ss/%s %s"
,
attach_type
==
BPF_PROBE_ENTRY
?
'p'
:
'r'
,
event_type
,
new_name
,
fn_name
);
if
(
write
(
kfd
,
buf
,
strlen
(
buf
))
<
0
)
{
if
(
errno
==
EINVAL
)
fprintf
(
stderr
,
"check dmesg output for possible cause
\n
"
);
close
(
kfd
);
...
...
@@ -364,34 +372,82 @@ static void * bpf_attach_probe(int progfd, const char *event,
}
close
(
kfd
);
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/events/%ss/%s"
,
event_type
,
event
);
if
(
access
(
"/sys/kernel/debug/tracing/instances"
,
F_OK
)
!=
-
1
)
{
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/instances/%s"
,
new_name
);
if
(
mkdir
(
buf
,
0755
)
==
-
1
)
goto
retry
;
n
=
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/instances/%s/events/%ss/%s"
,
new_name
,
event_type
,
new_name
);
if
(
n
<
sizeof
(
buf
)
&&
bpf_attach_tracing_event
(
progfd
,
buf
,
reader
,
pid
,
cpu
,
group_fd
)
==
0
)
goto
out
;
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/instances/%s"
,
new_name
);
rmdir
(
buf
);
}
retry:
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/events/%ss/%s"
,
event_type
,
new_name
);
if
(
bpf_attach_tracing_event
(
progfd
,
buf
,
reader
,
pid
,
cpu
,
group_fd
)
<
0
)
goto
error
;
out:
return
reader
;
error:
perf_reader_free
(
reader
);
return
NULL
;
}
void
*
bpf_attach_kprobe
(
int
progfd
,
const
char
*
event
,
const
char
*
event_desc
,
pid_t
pid
,
int
cpu
,
int
group_fd
,
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
return
bpf_attach_probe
(
progfd
,
event
,
event_desc
,
"kprobe"
,
pid
,
cpu
,
group_fd
,
cb
,
cb_cookie
);
}
void
*
bpf_attach_uprobe
(
int
progfd
,
const
char
*
event
,
const
char
*
event_desc
,
void
*
bpf_attach_uprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
const
char
*
ev_name
,
const
char
*
binary_path
,
uint64_t
offset
,
pid_t
pid
,
int
cpu
,
int
group_fd
,
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
return
bpf_attach_probe
(
progfd
,
event
,
event_desc
,
"uprobe"
,
pid
,
cpu
,
group_fd
,
cb
,
cb_cookie
);
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
int
kfd
;
char
buf
[
PATH_MAX
];
char
new_name
[
128
];
struct
perf_reader
*
reader
=
NULL
;
static
char
*
event_type
=
"uprobe"
;
int
n
;
snprintf
(
new_name
,
sizeof
(
new_name
),
"%s_bcc_%d"
,
ev_name
,
getpid
());
reader
=
perf_reader_new
(
cb
,
NULL
,
cb_cookie
);
if
(
!
reader
)
goto
error
;
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/%s_events"
,
event_type
);
kfd
=
open
(
buf
,
O_WRONLY
|
O_APPEND
,
0
);
if
(
kfd
<
0
)
{
fprintf
(
stderr
,
"open(%s): %s
\n
"
,
buf
,
strerror
(
errno
));
goto
error
;
}
n
=
snprintf
(
buf
,
sizeof
(
buf
),
"%c:%ss/%s %s:0x%lx"
,
attach_type
==
BPF_PROBE_ENTRY
?
'p'
:
'r'
,
event_type
,
new_name
,
binary_path
,
offset
);
if
(
n
>=
sizeof
(
buf
))
{
close
(
kfd
);
goto
error
;
}
if
(
write
(
kfd
,
buf
,
strlen
(
buf
))
<
0
)
{
if
(
errno
==
EINVAL
)
fprintf
(
stderr
,
"check dmesg output for possible cause
\n
"
);
close
(
kfd
);
goto
error
;
}
close
(
kfd
);
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/events/%ss/%s"
,
event_type
,
new_name
);
if
(
bpf_attach_tracing_event
(
progfd
,
buf
,
reader
,
pid
,
cpu
,
group_fd
)
<
0
)
goto
error
;
return
reader
;
error:
perf_reader_free
(
reader
);
return
NULL
;
}
static
int
bpf_detach_probe
(
const
char
*
event_desc
,
const
char
*
event_type
)
{
static
int
bpf_detach_probe
(
const
char
*
ev_name
,
const
char
*
event_type
)
{
int
kfd
;
char
buf
[
256
];
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/%s_events"
,
event_type
);
kfd
=
open
(
buf
,
O_WRONLY
|
O_APPEND
,
0
);
...
...
@@ -400,7 +456,8 @@ static int bpf_detach_probe(const char *event_desc, const char *event_type) {
return
-
1
;
}
if
(
write
(
kfd
,
event_desc
,
strlen
(
event_desc
))
<
0
)
{
snprintf
(
buf
,
sizeof
(
buf
),
"-:%ss/%s_bcc_%d"
,
event_type
,
ev_name
,
getpid
());
if
(
write
(
kfd
,
buf
,
strlen
(
buf
))
<
0
)
{
fprintf
(
stderr
,
"write(%s): %s
\n
"
,
buf
,
strerror
(
errno
));
close
(
kfd
);
return
-
1
;
...
...
@@ -410,14 +467,24 @@ static int bpf_detach_probe(const char *event_desc, const char *event_type) {
return
0
;
}
int
bpf_detach_kprobe
(
const
char
*
event_desc
)
{
return
bpf_detach_probe
(
event_desc
,
"kprobe"
);
int
bpf_detach_kprobe
(
const
char
*
ev_name
)
{
char
buf
[
256
];
int
ret
=
bpf_detach_probe
(
ev_name
,
"kprobe"
);
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/instances/%s_bcc_%d"
,
ev_name
,
getpid
());
if
(
access
(
buf
,
F_OK
)
!=
-
1
)
{
rmdir
(
buf
);
}
return
ret
;
}
int
bpf_detach_uprobe
(
const
char
*
event_desc
)
{
return
bpf_detach_probe
(
event_desc
,
"uprobe"
);
int
bpf_detach_uprobe
(
const
char
*
ev_name
)
{
return
bpf_detach_probe
(
ev_name
,
"uprobe"
);
}
void
*
bpf_attach_tracepoint
(
int
progfd
,
const
char
*
tp_category
,
const
char
*
tp_name
,
int
pid
,
int
cpu
,
int
group_fd
,
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
...
...
src/cc/libbpf.h
View file @
b77915df
...
...
@@ -24,6 +24,11 @@
extern
"C"
{
#endif
enum
bpf_probe_attach_type
{
BPF_PROBE_ENTRY
,
BPF_PROBE_RETURN
};
int
bpf_create_map
(
enum
bpf_map_type
map_type
,
int
key_size
,
int
value_size
,
int
max_entries
,
int
map_flags
);
int
bpf_update_elem
(
int
fd
,
void
*
key
,
void
*
value
,
unsigned
long
long
flags
);
...
...
@@ -44,15 +49,19 @@ typedef void (*perf_reader_cb)(void *cb_cookie, int pid, uint64_t callchain_num,
void
*
callchain
);
typedef
void
(
*
perf_reader_raw_cb
)(
void
*
cb_cookie
,
void
*
raw
,
int
raw_size
);
void
*
bpf_attach_kprobe
(
int
progfd
,
const
char
*
event
,
const
char
*
event_desc
,
int
pid
,
int
cpu
,
int
group_fd
,
perf_reader_cb
cb
,
void
*
cb_cookie
);
int
bpf_detach_kprobe
(
const
char
*
event_desc
);
void
*
bpf_attach_kprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
const
char
*
ev_name
,
const
char
*
fn_name
,
pid_t
pid
,
int
cpu
,
int
group_fd
,
perf_reader_cb
cb
,
void
*
cb_cookie
);
int
bpf_detach_kprobe
(
const
char
*
ev_name
);
void
*
bpf_attach_uprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
const
char
*
ev_name
,
const
char
*
binary_path
,
uint64_t
offset
,
pid_t
pid
,
int
cpu
,
int
group_fd
,
perf_reader_cb
cb
,
void
*
cb_cookie
);
void
*
bpf_attach_uprobe
(
int
progfd
,
const
char
*
event
,
const
char
*
event_desc
,
int
pid
,
int
cpu
,
int
group_fd
,
perf_reader_cb
cb
,
void
*
cb_cookie
);
int
bpf_detach_uprobe
(
const
char
*
event_desc
);
int
bpf_detach_uprobe
(
const
char
*
ev_name
);
void
*
bpf_attach_tracepoint
(
int
progfd
,
const
char
*
tp_category
,
const
char
*
tp_name
,
int
pid
,
int
cpu
,
...
...
src/lua/bcc/bpf.lua
View file @
b77915df
...
...
@@ -43,13 +43,10 @@ function Bpf.static.cleanup()
libbcc
.
perf_reader_free
(
probe
)
-- skip bcc-specific kprobes
if
not
key
:
starts
(
"bcc:"
)
then
local
desc
=
string.format
(
"-:%s/%s"
,
probe_type
,
key
)
log
.
info
(
"detaching %s"
,
desc
)
if
probe_type
==
"kprobes"
then
libbcc
.
bpf_detach_kprobe
(
desc
)
libbcc
.
bpf_detach_kprobe
(
key
)
elseif
probe_type
==
"uprobes"
then
libbcc
.
bpf_detach_uprobe
(
desc
)
libbcc
.
bpf_detach_uprobe
(
key
)
end
end
all_probes
[
key
]
=
nil
...
...
@@ -187,11 +184,9 @@ function Bpf:attach_uprobe(args)
local
fn
=
self
:
load_func
(
args
.
fn_name
,
'BPF_PROG_TYPE_KPROBE'
)
local
ptype
=
args
.
retprobe
and
"r"
or
"p"
local
ev_name
=
string.format
(
"%s_%s_0x%p"
,
ptype
,
path
:
gsub
(
"
[^
%a%d
]
"
,
"_"
),
addr
)
local
desc
=
string.format
(
"%s:uprobes/%s %s:0x%p"
,
ptype
,
ev_name
,
path
,
addr
)
log
.
info
(
desc
)
local
retprobe
=
args
.
retprobe
and
1
or
0
local
res
=
libbcc
.
bpf_attach_uprobe
(
fn
.
fd
,
ev_name
,
desc
,
local
res
=
libbcc
.
bpf_attach_uprobe
(
fn
.
fd
,
retprobe
,
ev_name
,
path
,
addr
,
args
.
pid
or
-
1
,
args
.
cpu
or
0
,
args
.
group_fd
or
-
1
,
nil
,
nil
)
-- TODO; reader callback
...
...
@@ -209,11 +204,9 @@ function Bpf:attach_kprobe(args)
local
event
=
args
.
event
or
""
local
ptype
=
args
.
retprobe
and
"r"
or
"p"
local
ev_name
=
string.format
(
"%s_%s"
,
ptype
,
event
:
gsub
(
"
[
%+%.
]
"
,
"_"
))
local
desc
=
string.format
(
"%s:kprobes/%s %s"
,
ptype
,
ev_name
,
event
)
log
.
info
(
desc
)
local
retprobe
=
args
.
retprobe
and
1
or
0
local
res
=
libbcc
.
bpf_attach_kprobe
(
fn
.
fd
,
ev_name
,
desc
,
local
res
=
libbcc
.
bpf_attach_kprobe
(
fn
.
fd
,
retprobe
,
ev_name
,
event
,
args
.
pid
or
-
1
,
args
.
cpu
or
0
,
args
.
group_fd
or
-
1
,
nil
,
nil
)
-- TODO; reader callback
...
...
src/lua/bcc/libbcc.lua
View file @
b77915df
...
...
@@ -40,13 +40,19 @@ int bpf_open_raw_sock(const char *name);
typedef void (*perf_reader_cb)(void *cb_cookie, int pid, uint64_t callchain_num, void *callchain);
typedef void (*perf_reader_raw_cb)(void *cb_cookie, void *raw, int raw_size);
void * bpf_attach_kprobe(int progfd, const char *event, const char *event_desc,
int pid, int cpu, int group_fd, perf_reader_cb cb, void *cb_cookie);
int bpf_detach_kprobe(const char *event_desc);
void * bpf_attach_kprobe(int progfd, int attach_type, const char *ev_name,
const char *fn_name,
int pid, int cpu, int group_fd,
perf_reader_cb cb, void *cb_cookie);
void * bpf_attach_uprobe(int progfd, const char *event, const char *event_desc,
int pid, int cpu, int group_fd, perf_reader_cb cb, void *cb_cookie);
int bpf_detach_uprobe(const char *event_desc);
int bpf_detach_kprobe(const char *ev_name);
void * bpf_attach_uprobe(int progfd, int attach_type, const char *ev_name,
const char *binary_path, uint64_t offset,
int pid, int cpu, int group_fd,
perf_reader_cb cb, void *cb_cookie);
int bpf_detach_uprobe(const char *ev_name);
void * bpf_open_perf_buffer(perf_reader_raw_cb raw_cb, void *cb_cookie, int pid, int cpu);
]]
...
...
src/python/bcc/__init__.py
View file @
b77915df
...
...
@@ -459,9 +459,8 @@ class BPF(object):
self
.
_check_probe_quota
(
1
)
fn
=
self
.
load_func
(
fn_name
,
BPF
.
KPROBE
)
ev_name
=
"p_"
+
event
.
replace
(
"+"
,
"_"
).
replace
(
"."
,
"_"
)
desc
=
"p:kprobes/%s %s"
%
(
ev_name
,
event
)
res
=
lib
.
bpf_attach_kprobe
(
fn
.
fd
,
ev_name
.
encode
(
"ascii"
),
desc
.
encode
(
"ascii"
),
pid
,
cpu
,
group_fd
,
res
=
lib
.
bpf_attach_kprobe
(
fn
.
fd
,
0
,
ev_name
.
encode
(
"ascii"
),
event
.
encode
(
"ascii"
),
pid
,
cpu
,
group_fd
,
self
.
_reader_cb_impl
,
ct
.
cast
(
id
(
self
),
ct
.
py_object
))
res
=
ct
.
cast
(
res
,
ct
.
c_void_p
)
if
not
res
:
...
...
@@ -475,8 +474,7 @@ class BPF(object):
if
ev_name
not
in
self
.
open_kprobes
:
raise
Exception
(
"Kprobe %s is not attached"
%
event
)
lib
.
perf_reader_free
(
self
.
open_kprobes
[
ev_name
])
desc
=
"-:kprobes/%s"
%
ev_name
res
=
lib
.
bpf_detach_kprobe
(
desc
.
encode
(
"ascii"
))
res
=
lib
.
bpf_detach_kprobe
(
ev_name
.
encode
(
"ascii"
))
if
res
<
0
:
raise
Exception
(
"Failed to detach BPF from kprobe"
)
self
.
_del_kprobe
(
ev_name
)
...
...
@@ -498,9 +496,8 @@ class BPF(object):
self
.
_check_probe_quota
(
1
)
fn
=
self
.
load_func
(
fn_name
,
BPF
.
KPROBE
)
ev_name
=
"r_"
+
event
.
replace
(
"+"
,
"_"
).
replace
(
"."
,
"_"
)
desc
=
"r:kprobes/%s %s"
%
(
ev_name
,
event
)
res
=
lib
.
bpf_attach_kprobe
(
fn
.
fd
,
ev_name
.
encode
(
"ascii"
),
desc
.
encode
(
"ascii"
),
pid
,
cpu
,
group_fd
,
res
=
lib
.
bpf_attach_kprobe
(
fn
.
fd
,
1
,
ev_name
.
encode
(
"ascii"
),
event
.
encode
(
"ascii"
),
pid
,
cpu
,
group_fd
,
self
.
_reader_cb_impl
,
ct
.
cast
(
id
(
self
),
ct
.
py_object
))
res
=
ct
.
cast
(
res
,
ct
.
c_void_p
)
if
not
res
:
...
...
@@ -514,8 +511,7 @@ class BPF(object):
if
ev_name
not
in
self
.
open_kprobes
:
raise
Exception
(
"Kretprobe %s is not attached"
%
event
)
lib
.
perf_reader_free
(
self
.
open_kprobes
[
ev_name
])
desc
=
"-:kprobes/%s"
%
ev_name
res
=
lib
.
bpf_detach_kprobe
(
desc
.
encode
(
"ascii"
))
res
=
lib
.
bpf_detach_kprobe
(
ev_name
.
encode
(
"ascii"
))
if
res
<
0
:
raise
Exception
(
"Failed to detach BPF from kprobe"
)
self
.
_del_kprobe
(
ev_name
)
...
...
@@ -767,9 +763,8 @@ class BPF(object):
self
.
_check_probe_quota
(
1
)
fn
=
self
.
load_func
(
fn_name
,
BPF
.
KPROBE
)
ev_name
=
"p_%s_0x%x"
%
(
self
.
_probe_repl
.
sub
(
"_"
,
path
),
addr
)
desc
=
"p:uprobes/%s %s:0x%x"
%
(
ev_name
,
path
,
addr
)
res
=
lib
.
bpf_attach_uprobe
(
fn
.
fd
,
ev_name
.
encode
(
"ascii"
),
desc
.
encode
(
"ascii"
),
pid
,
cpu
,
group_fd
,
res
=
lib
.
bpf_attach_uprobe
(
fn
.
fd
,
0
,
ev_name
.
encode
(
"ascii"
),
path
,
addr
,
pid
,
cpu
,
group_fd
,
self
.
_reader_cb_impl
,
ct
.
cast
(
id
(
self
),
ct
.
py_object
))
res
=
ct
.
cast
(
res
,
ct
.
c_void_p
)
if
not
res
:
...
...
@@ -790,8 +785,7 @@ class BPF(object):
if
ev_name
not
in
self
.
open_uprobes
:
raise
Exception
(
"Uprobe %s is not attached"
%
ev_name
)
lib
.
perf_reader_free
(
self
.
open_uprobes
[
ev_name
])
desc
=
"-:uprobes/%s"
%
ev_name
res
=
lib
.
bpf_detach_uprobe
(
desc
.
encode
(
"ascii"
))
res
=
lib
.
bpf_detach_uprobe
(
ev_name
.
encode
(
"ascii"
))
if
res
<
0
:
raise
Exception
(
"Failed to detach BPF from uprobe"
)
self
.
_del_uprobe
(
ev_name
)
...
...
@@ -819,9 +813,8 @@ class BPF(object):
self
.
_check_probe_quota
(
1
)
fn
=
self
.
load_func
(
fn_name
,
BPF
.
KPROBE
)
ev_name
=
"r_%s_0x%x"
%
(
self
.
_probe_repl
.
sub
(
"_"
,
path
),
addr
)
desc
=
"r:uprobes/%s %s:0x%x"
%
(
ev_name
,
path
,
addr
)
res
=
lib
.
bpf_attach_uprobe
(
fn
.
fd
,
ev_name
.
encode
(
"ascii"
),
desc
.
encode
(
"ascii"
),
pid
,
cpu
,
group_fd
,
res
=
lib
.
bpf_attach_uprobe
(
fn
.
fd
,
1
,
ev_name
.
encode
(
"ascii"
),
path
,
addr
,
pid
,
cpu
,
group_fd
,
self
.
_reader_cb_impl
,
ct
.
cast
(
id
(
self
),
ct
.
py_object
))
res
=
ct
.
cast
(
res
,
ct
.
c_void_p
)
if
not
res
:
...
...
@@ -842,8 +835,7 @@ class BPF(object):
if
ev_name
not
in
self
.
open_uprobes
:
raise
Exception
(
"Uretprobe %s is not attached"
%
ev_name
)
lib
.
perf_reader_free
(
self
.
open_uprobes
[
ev_name
])
desc
=
"-:uprobes/%s"
%
ev_name
res
=
lib
.
bpf_detach_uprobe
(
desc
.
encode
(
"ascii"
))
res
=
lib
.
bpf_detach_uprobe
(
ev_name
.
encode
(
"ascii"
))
if
res
<
0
:
raise
Exception
(
"Failed to detach BPF from uprobe"
)
self
.
_del_uprobe
(
ev_name
)
...
...
@@ -1045,13 +1037,11 @@ class BPF(object):
lib
.
perf_reader_free
(
v
)
# non-string keys here include the perf_events reader
if
isinstance
(
k
,
str
):
desc
=
"-:kprobes/%s"
%
k
lib
.
bpf_detach_kprobe
(
desc
.
encode
(
"ascii"
))
lib
.
bpf_detach_kprobe
(
str
(
k
).
encode
(
"ascii"
))
self
.
_del_kprobe
(
k
)
for
k
,
v
in
list
(
self
.
open_uprobes
.
items
()):
lib
.
perf_reader_free
(
v
)
desc
=
"-:uprobes/%s"
%
k
lib
.
bpf_detach_uprobe
(
desc
.
encode
(
"ascii"
))
lib
.
bpf_detach_uprobe
(
str
(
k
).
encode
(
"ascii"
))
self
.
_del_uprobe
(
k
)
for
k
,
v
in
self
.
open_tracepoints
.
items
():
lib
.
perf_reader_free
(
v
)
...
...
src/python/bcc/libbcc.py
View file @
b77915df
...
...
@@ -87,13 +87,13 @@ lib.bpf_attach_kprobe.restype = ct.c_void_p
_CB_TYPE
=
ct
.
CFUNCTYPE
(
None
,
ct
.
py_object
,
ct
.
c_int
,
ct
.
c_ulonglong
,
ct
.
POINTER
(
ct
.
c_ulonglong
))
_RAW_CB_TYPE
=
ct
.
CFUNCTYPE
(
None
,
ct
.
py_object
,
ct
.
c_void_p
,
ct
.
c_int
)
lib
.
bpf_attach_kprobe
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_char_p
,
ct
.
c_int
,
lib
.
bpf_attach_kprobe
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_
int
,
ct
.
c_
char_p
,
ct
.
c_char_p
,
ct
.
c_int
,
ct
.
c_int
,
ct
.
c_int
,
_CB_TYPE
,
ct
.
py_object
]
lib
.
bpf_detach_kprobe
.
restype
=
ct
.
c_int
lib
.
bpf_detach_kprobe
.
argtypes
=
[
ct
.
c_char_p
]
lib
.
bpf_attach_uprobe
.
restype
=
ct
.
c_void_p
lib
.
bpf_attach_uprobe
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_
char_p
,
ct
.
c_char_p
,
ct
.
c_int
,
ct
.
c_int
,
ct
.
c_int
,
_CB_TYPE
,
ct
.
py_object
]
lib
.
bpf_attach_uprobe
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_
int
,
ct
.
c_char_p
,
ct
.
c_char_p
,
ct
.
c_
ulonglong
,
ct
.
c_int
,
ct
.
c_
int
,
ct
.
c_int
,
_CB_TYPE
,
ct
.
py_object
]
lib
.
bpf_detach_uprobe
.
restype
=
ct
.
c_int
lib
.
bpf_detach_uprobe
.
argtypes
=
[
ct
.
c_char_p
]
lib
.
bpf_attach_tracepoint
.
restype
=
ct
.
c_void_p
...
...
tools/argdist.py
View file @
b77915df
...
...
@@ -20,7 +20,7 @@ import sys
class
Probe
(
object
):
next_probe_index
=
0
streq_index
=
0
aliases
=
{
"$PID"
:
"
(bpf_get_current_pid_tgid() >> 32
)"
}
aliases
=
{
"$PID"
:
"
bpf_get_current_pid_tgid(
)"
}
def
_substitute_aliases
(
self
,
expr
):
if
expr
is
None
:
...
...
@@ -47,9 +47,7 @@ class Probe(object):
text
=
"""
int PROBENAME(struct pt_regs *ctx SIGNATURE)
{
u64 __pid_tgid = bpf_get_current_pid_tgid();
u32 __pid = __pid_tgid; // lower 32 bits
u32 __tgid = __pid_tgid >> 32; // upper 32 bits
u32 pid = bpf_get_current_pid_tgid();
PID_FILTER
COLLECT
return 0;
...
...
@@ -58,17 +56,19 @@ int PROBENAME(struct pt_regs *ctx SIGNATURE)
text
=
text
.
replace
(
"PROBENAME"
,
self
.
entry_probe_func
)
text
=
text
.
replace
(
"SIGNATURE"
,
""
if
len
(
self
.
signature
)
==
0
else
", "
+
self
.
signature
)
text
=
text
.
replace
(
"PID_FILTER"
,
self
.
_generate_pid_filter
())
pid_filter
=
""
if
self
.
is_user
or
self
.
pid
is
None
\
else
"if (pid != %d) { return 0; }"
%
self
.
pid
text
=
text
.
replace
(
"PID_FILTER"
,
pid_filter
)
collect
=
""
for
pname
in
self
.
args_to_probe
:
param_hash
=
self
.
hashname_prefix
+
pname
if
pname
==
"__latency"
:
collect
+=
"""
u64 __time = bpf_ktime_get_ns();
%s.update(&
__
pid, &__time);
%s.update(&pid, &__time);
"""
%
param_hash
else
:
collect
+=
"%s.update(&
__
pid, &%s);
\
n
"
%
\
collect
+=
"%s.update(&pid, &%s);
\
n
"
%
\
(
param_hash
,
pname
)
text
=
text
.
replace
(
"COLLECT"
,
collect
)
return
text
...
...
@@ -108,7 +108,7 @@ u64 __time = bpf_ktime_get_ns();
# argument we needed to probe using $entry(name), and they all
# have values (which isn't necessarily the case if we missed
# the method entry probe).
text = ""
text = "
u32
__pid
=
bpf_get_current_pid_tgid
();
\
n
"
self.param_val_names = {}
for pname in self.args_to_probe:
val_name = "
__
%
s_val
" % pname
...
...
@@ -345,7 +345,8 @@ static inline bool %s(char const *ignored, char const *str) {
# Kernel probes need to explicitly filter pid, because the
# attach interface doesn't support pid filtering
if
self
.
pid
is
not
None
and
not
self
.
is_user
:
return
"if (__tgid != %d) { return 0; }"
%
self
.
pid
return
"u32 pid = bpf_get_current_pid_tgid();
\
n
"
+
\
"if (pid != %d) { return 0; }"
%
self
.
pid
else
:
return
""
...
...
@@ -359,9 +360,6 @@ DATA_DECL
if
self
.
probe_type
==
"t"
else
"int PROBENAME(struct pt_regs *ctx SIGNATURE)"
)
+
"""
{
u64 __pid_tgid = bpf_get_current_pid_tgid();
u32 __pid = __pid_tgid; // lower 32 bits
u32 __tgid = __pid_tgid >> 32; // upper 32 bits
PID_FILTER
PREFIX
if (!(FILTER)) return 0;
...
...
tools/cpudist.py
View file @
b77915df
...
...
@@ -12,7 +12,7 @@
# Licensed under the Apache License, Version 2.0 (the "License")
from
__future__
import
print_function
from
bcc
import
BPF
from
bcc
import
BPF
,
Tracepoint
from
time
import
sleep
,
strftime
import
argparse
...
...
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