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
fafbf3ca
Commit
fafbf3ca
authored
Feb 27, 2018
by
Teng Qin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Do not use perf reader for TRACEPOINT events
parent
abef8350
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
232 additions
and
321 deletions
+232
-321
src/cc/api/BPF.cc
src/cc/api/BPF.cc
+18
-31
src/cc/api/BPF.h
src/cc/api/BPF.h
+4
-9
src/cc/libbpf.c
src/cc/libbpf.c
+54
-68
src/cc/libbpf.h
src/cc/libbpf.h
+7
-12
src/lua/bcc/bpf.lua
src/lua/bcc/bpf.lua
+32
-20
src/lua/bcc/libbcc.lua
src/lua/bcc/libbcc.lua
+6
-7
src/lua/bcc/table.lua
src/lua/bcc/table.lua
+1
-1
src/python/bcc/__init__.py
src/python/bcc/__init__.py
+100
-125
src/python/bcc/libbcc.py
src/python/bcc/libbcc.py
+6
-10
src/python/bcc/table.py
src/python/bcc/table.py
+4
-4
tests/python/CMakeLists.txt
tests/python/CMakeLists.txt
+0
-2
tests/python/test_callchain.py
tests/python/test_callchain.py
+0
-32
No files found.
src/cc/api/BPF.cc
View file @
fafbf3ca
...
@@ -159,8 +159,7 @@ StatusTuple BPF::detach_all() {
...
@@ -159,8 +159,7 @@ StatusTuple BPF::detach_all() {
StatusTuple
BPF
::
attach_kprobe
(
const
std
::
string
&
kernel_func
,
StatusTuple
BPF
::
attach_kprobe
(
const
std
::
string
&
kernel_func
,
const
std
::
string
&
probe_func
,
const
std
::
string
&
probe_func
,
bpf_probe_attach_type
attach_type
,
bpf_probe_attach_type
attach_type
)
{
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
std
::
string
probe_event
=
get_kprobe_event
(
kernel_func
,
attach_type
);
std
::
string
probe_event
=
get_kprobe_event
(
kernel_func
,
attach_type
);
if
(
kprobes_
.
find
(
probe_event
)
!=
kprobes_
.
end
())
if
(
kprobes_
.
find
(
probe_event
)
!=
kprobes_
.
end
())
return
StatusTuple
(
-
1
,
"kprobe %s already attached"
,
probe_event
.
c_str
());
return
StatusTuple
(
-
1
,
"kprobe %s already attached"
,
probe_event
.
c_str
());
...
@@ -168,10 +167,10 @@ StatusTuple BPF::attach_kprobe(const std::string& kernel_func,
...
@@ -168,10 +167,10 @@ StatusTuple BPF::attach_kprobe(const std::string& kernel_func,
int
probe_fd
;
int
probe_fd
;
TRY2
(
load_func
(
probe_func
,
BPF_PROG_TYPE_KPROBE
,
probe_fd
));
TRY2
(
load_func
(
probe_func
,
BPF_PROG_TYPE_KPROBE
,
probe_fd
));
void
*
res
=
bpf_attach_kprobe
(
probe_fd
,
attach_type
,
probe_event
.
c_str
(),
int
res_fd
=
bpf_attach_kprobe
(
probe_fd
,
attach_type
,
probe_event
.
c_str
(),
kernel_func
.
c_str
(),
cb
,
cb_cookie
);
kernel_func
.
c_str
()
);
if
(
!
res
)
{
if
(
res_fd
<
0
)
{
TRY2
(
unload_func
(
probe_func
));
TRY2
(
unload_func
(
probe_func
));
return
StatusTuple
(
-
1
,
"Unable to attach %skprobe for %s using %s"
,
return
StatusTuple
(
-
1
,
"Unable to attach %skprobe for %s using %s"
,
attach_type_debug
(
attach_type
).
c_str
(),
attach_type_debug
(
attach_type
).
c_str
(),
...
@@ -179,7 +178,7 @@ StatusTuple BPF::attach_kprobe(const std::string& kernel_func,
...
@@ -179,7 +178,7 @@ StatusTuple BPF::attach_kprobe(const std::string& kernel_func,
}
}
open_probe_t
p
=
{};
open_probe_t
p
=
{};
p
.
reader_ptr
=
res
;
p
.
perf_event_fd
=
res_fd
;
p
.
func
=
probe_func
;
p
.
func
=
probe_func
;
kprobes_
[
probe_event
]
=
std
::
move
(
p
);
kprobes_
[
probe_event
]
=
std
::
move
(
p
);
return
StatusTuple
(
0
);
return
StatusTuple
(
0
);
...
@@ -189,8 +188,7 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
...
@@ -189,8 +188,7 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
const
std
::
string
&
symbol
,
const
std
::
string
&
symbol
,
const
std
::
string
&
probe_func
,
const
std
::
string
&
probe_func
,
uint64_t
symbol_addr
,
uint64_t
symbol_addr
,
bpf_probe_attach_type
attach_type
,
pid_t
pid
,
bpf_probe_attach_type
attach_type
,
pid_t
pid
)
{
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
std
::
string
module
;
std
::
string
module
;
uint64_t
offset
;
uint64_t
offset
;
TRY2
(
check_binary_symbol
(
binary_path
,
symbol
,
symbol_addr
,
module
,
offset
));
TRY2
(
check_binary_symbol
(
binary_path
,
symbol
,
symbol_addr
,
module
,
offset
));
...
@@ -202,11 +200,10 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
...
@@ -202,11 +200,10 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
int
probe_fd
;
int
probe_fd
;
TRY2
(
load_func
(
probe_func
,
BPF_PROG_TYPE_KPROBE
,
probe_fd
));
TRY2
(
load_func
(
probe_func
,
BPF_PROG_TYPE_KPROBE
,
probe_fd
));
void
*
res
=
int
res_fd
=
bpf_attach_uprobe
(
probe_fd
,
attach_type
,
probe_event
.
c_str
(),
bpf_attach_uprobe
(
probe_fd
,
attach_type
,
probe_event
.
c_str
(),
binary_path
.
c_str
(),
offset
,
pid
);
binary_path
.
c_str
(),
offset
,
pid
,
cb
,
cb_cookie
);
if
(
!
res
)
{
if
(
res_fd
<
0
)
{
TRY2
(
unload_func
(
probe_func
));
TRY2
(
unload_func
(
probe_func
));
return
StatusTuple
(
return
StatusTuple
(
-
1
,
-
1
,
...
@@ -216,7 +213,7 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
...
@@ -216,7 +213,7 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
}
}
open_probe_t
p
=
{};
open_probe_t
p
=
{};
p
.
reader_ptr
=
res
;
p
.
perf_event_fd
=
res_fd
;
p
.
func
=
probe_func
;
p
.
func
=
probe_func
;
uprobes_
[
probe_event
]
=
std
::
move
(
p
);
uprobes_
[
probe_event
]
=
std
::
move
(
p
);
return
StatusTuple
(
0
);
return
StatusTuple
(
0
);
...
@@ -253,8 +250,7 @@ StatusTuple BPF::attach_usdt(const USDT& usdt, pid_t pid) {
...
@@ -253,8 +250,7 @@ StatusTuple BPF::attach_usdt(const USDT& usdt, pid_t pid) {
}
}
StatusTuple
BPF
::
attach_tracepoint
(
const
std
::
string
&
tracepoint
,
StatusTuple
BPF
::
attach_tracepoint
(
const
std
::
string
&
tracepoint
,
const
std
::
string
&
probe_func
,
const
std
::
string
&
probe_func
)
{
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
if
(
tracepoints_
.
find
(
tracepoint
)
!=
tracepoints_
.
end
())
if
(
tracepoints_
.
find
(
tracepoint
)
!=
tracepoints_
.
end
())
return
StatusTuple
(
-
1
,
"Tracepoint %s already attached"
,
return
StatusTuple
(
-
1
,
"Tracepoint %s already attached"
,
tracepoint
.
c_str
());
tracepoint
.
c_str
());
...
@@ -268,17 +264,17 @@ StatusTuple BPF::attach_tracepoint(const std::string& tracepoint,
...
@@ -268,17 +264,17 @@ StatusTuple BPF::attach_tracepoint(const std::string& tracepoint,
int
probe_fd
;
int
probe_fd
;
TRY2
(
load_func
(
probe_func
,
BPF_PROG_TYPE_TRACEPOINT
,
probe_fd
));
TRY2
(
load_func
(
probe_func
,
BPF_PROG_TYPE_TRACEPOINT
,
probe_fd
));
void
*
res
=
bpf_attach_tracepoint
(
probe_fd
,
tp_category
.
c_str
(),
int
res_fd
=
bpf_attach_tracepoint
(
probe_fd
,
tp_category
.
c_str
(),
tp_name
.
c_str
()
,
cb
,
cb_cookie
);
tp_name
.
c_str
());
if
(
!
res
)
{
if
(
res_fd
<
0
)
{
TRY2
(
unload_func
(
probe_func
));
TRY2
(
unload_func
(
probe_func
));
return
StatusTuple
(
-
1
,
"Unable to attach Tracepoint %s using %s"
,
return
StatusTuple
(
-
1
,
"Unable to attach Tracepoint %s using %s"
,
tracepoint
.
c_str
(),
probe_func
.
c_str
());
tracepoint
.
c_str
(),
probe_func
.
c_str
());
}
}
open_probe_t
p
=
{};
open_probe_t
p
=
{};
p
.
reader_ptr
=
res
;
p
.
perf_event_fd
=
res_fd
;
p
.
func
=
probe_func
;
p
.
func
=
probe_func
;
tracepoints_
[
tracepoint
]
=
std
::
move
(
p
);
tracepoints_
[
tracepoint
]
=
std
::
move
(
p
);
return
StatusTuple
(
0
);
return
StatusTuple
(
0
);
...
@@ -558,10 +554,7 @@ std::string BPF::get_uprobe_event(const std::string& binary_path,
...
@@ -558,10 +554,7 @@ std::string BPF::get_uprobe_event(const std::string& binary_path,
StatusTuple
BPF
::
detach_kprobe_event
(
const
std
::
string
&
event
,
StatusTuple
BPF
::
detach_kprobe_event
(
const
std
::
string
&
event
,
open_probe_t
&
attr
)
{
open_probe_t
&
attr
)
{
if
(
attr
.
reader_ptr
)
{
bpf_close_perf_event_fd
(
attr
.
perf_event_fd
);
perf_reader_free
(
attr
.
reader_ptr
);
attr
.
reader_ptr
=
nullptr
;
}
TRY2
(
unload_func
(
attr
.
func
));
TRY2
(
unload_func
(
attr
.
func
));
if
(
bpf_detach_kprobe
(
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
(
-
1
,
"Unable to detach kprobe %s"
,
event
.
c_str
());
...
@@ -570,10 +563,7 @@ StatusTuple BPF::detach_kprobe_event(const std::string& event,
...
@@ -570,10 +563,7 @@ StatusTuple BPF::detach_kprobe_event(const std::string& event,
StatusTuple
BPF
::
detach_uprobe_event
(
const
std
::
string
&
event
,
StatusTuple
BPF
::
detach_uprobe_event
(
const
std
::
string
&
event
,
open_probe_t
&
attr
)
{
open_probe_t
&
attr
)
{
if
(
attr
.
reader_ptr
)
{
bpf_close_perf_event_fd
(
attr
.
perf_event_fd
);
perf_reader_free
(
attr
.
reader_ptr
);
attr
.
reader_ptr
=
nullptr
;
}
TRY2
(
unload_func
(
attr
.
func
));
TRY2
(
unload_func
(
attr
.
func
));
if
(
bpf_detach_uprobe
(
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
(
-
1
,
"Unable to detach uprobe %s"
,
event
.
c_str
());
...
@@ -582,10 +572,7 @@ StatusTuple BPF::detach_uprobe_event(const std::string& event,
...
@@ -582,10 +572,7 @@ StatusTuple BPF::detach_uprobe_event(const std::string& event,
StatusTuple
BPF
::
detach_tracepoint_event
(
const
std
::
string
&
tracepoint
,
StatusTuple
BPF
::
detach_tracepoint_event
(
const
std
::
string
&
tracepoint
,
open_probe_t
&
attr
)
{
open_probe_t
&
attr
)
{
if
(
attr
.
reader_ptr
)
{
bpf_close_perf_event_fd
(
attr
.
perf_event_fd
);
perf_reader_free
(
attr
.
reader_ptr
);
attr
.
reader_ptr
=
nullptr
;
}
TRY2
(
unload_func
(
attr
.
func
));
TRY2
(
unload_func
(
attr
.
func
));
// TODO: bpf_detach_tracepoint currently does nothing.
// TODO: bpf_detach_tracepoint currently does nothing.
...
...
src/cc/api/BPF.h
View file @
fafbf3ca
...
@@ -34,7 +34,7 @@ static const int DEFAULT_PERF_BUFFER_PAGE_CNT = 8;
...
@@ -34,7 +34,7 @@ static const int DEFAULT_PERF_BUFFER_PAGE_CNT = 8;
namespace
ebpf
{
namespace
ebpf
{
struct
open_probe_t
{
struct
open_probe_t
{
void
*
reader_ptr
;
int
perf_event_fd
;
std
::
string
func
;
std
::
string
func
;
std
::
map
<
int
,
int
>*
per_cpu_fd
;
std
::
map
<
int
,
int
>*
per_cpu_fd
;
};
};
...
@@ -57,9 +57,7 @@ class BPF {
...
@@ -57,9 +57,7 @@ class BPF {
StatusTuple
attach_kprobe
(
const
std
::
string
&
kernel_func
,
StatusTuple
attach_kprobe
(
const
std
::
string
&
kernel_func
,
const
std
::
string
&
probe_func
,
const
std
::
string
&
probe_func
,
bpf_probe_attach_type
=
BPF_PROBE_ENTRY
,
bpf_probe_attach_type
=
BPF_PROBE_ENTRY
);
perf_reader_cb
cb
=
nullptr
,
void
*
cb_cookie
=
nullptr
);
StatusTuple
detach_kprobe
(
StatusTuple
detach_kprobe
(
const
std
::
string
&
kernel_func
,
const
std
::
string
&
kernel_func
,
bpf_probe_attach_type
attach_type
=
BPF_PROBE_ENTRY
);
bpf_probe_attach_type
attach_type
=
BPF_PROBE_ENTRY
);
...
@@ -69,8 +67,7 @@ class BPF {
...
@@ -69,8 +67,7 @@ class BPF {
const
std
::
string
&
probe_func
,
const
std
::
string
&
probe_func
,
uint64_t
symbol_addr
=
0
,
uint64_t
symbol_addr
=
0
,
bpf_probe_attach_type
attach_type
=
BPF_PROBE_ENTRY
,
bpf_probe_attach_type
attach_type
=
BPF_PROBE_ENTRY
,
pid_t
pid
=
-
1
,
perf_reader_cb
cb
=
nullptr
,
pid_t
pid
=
-
1
);
void
*
cb_cookie
=
nullptr
);
StatusTuple
detach_uprobe
(
const
std
::
string
&
binary_path
,
StatusTuple
detach_uprobe
(
const
std
::
string
&
binary_path
,
const
std
::
string
&
symbol
,
uint64_t
symbol_addr
=
0
,
const
std
::
string
&
symbol
,
uint64_t
symbol_addr
=
0
,
bpf_probe_attach_type
attach_type
=
BPF_PROBE_ENTRY
,
bpf_probe_attach_type
attach_type
=
BPF_PROBE_ENTRY
,
...
@@ -79,9 +76,7 @@ class BPF {
...
@@ -79,9 +76,7 @@ class BPF {
StatusTuple
detach_usdt
(
const
USDT
&
usdt
);
StatusTuple
detach_usdt
(
const
USDT
&
usdt
);
StatusTuple
attach_tracepoint
(
const
std
::
string
&
tracepoint
,
StatusTuple
attach_tracepoint
(
const
std
::
string
&
tracepoint
,
const
std
::
string
&
probe_func
,
const
std
::
string
&
probe_func
);
perf_reader_cb
cb
=
nullptr
,
void
*
cb_cookie
=
nullptr
);
StatusTuple
detach_tracepoint
(
const
std
::
string
&
tracepoint
);
StatusTuple
detach_tracepoint
(
const
std
::
string
&
tracepoint
);
StatusTuple
attach_perf_event
(
uint32_t
ev_type
,
uint32_t
ev_config
,
StatusTuple
attach_perf_event
(
uint32_t
ev_type
,
uint32_t
ev_config
,
...
...
src/cc/libbpf.c
View file @
fafbf3ca
...
@@ -151,8 +151,6 @@ static struct bpf_helper helpers[] = {
...
@@ -151,8 +151,6 @@ static struct bpf_helper helpers[] = {
{
"sock_ops_cb_flags_set"
,
"4.16"
},
{
"sock_ops_cb_flags_set"
,
"4.16"
},
};
};
static
int
probe_perf_reader_page_cnt
=
8
;
static
uint64_t
ptr_to_u64
(
void
*
ptr
)
static
uint64_t
ptr_to_u64
(
void
*
ptr
)
{
{
return
(
uint64_t
)
(
unsigned
long
)
ptr
;
return
(
uint64_t
)
(
unsigned
long
)
ptr
;
...
@@ -682,7 +680,6 @@ static int bpf_try_perf_event_open_with_probe(const char *name, uint64_t offs,
...
@@ -682,7 +680,6 @@ static int bpf_try_perf_event_open_with_probe(const char *name, uint64_t offs,
if
(
type
<
0
||
is_return_bit
<
0
)
if
(
type
<
0
||
is_return_bit
<
0
)
return
-
1
;
return
-
1
;
attr
.
sample_type
=
PERF_SAMPLE_RAW
|
PERF_SAMPLE_CALLCHAIN
;
attr
.
sample_period
=
1
;
attr
.
sample_period
=
1
;
attr
.
wakeup_events
=
1
;
attr
.
wakeup_events
=
1
;
if
(
is_return
)
if
(
is_return
)
...
@@ -724,16 +721,23 @@ static int bpf_try_perf_event_open_with_probe(const char *name, uint64_t offs,
...
@@ -724,16 +721,23 @@ static int bpf_try_perf_event_open_with_probe(const char *name, uint64_t offs,
PERF_FLAG_FD_CLOEXEC
);
PERF_FLAG_FD_CLOEXEC
);
}
}
static
int
bpf_attach_tracing_event
(
int
progfd
,
const
char
*
event_path
,
// When a valid Perf Event FD provided through pfd, it will be used to enable
struct
perf_reader
*
reader
,
int
pid
,
// and attach BPF program to the event, and event_path will be ignored.
int
pfd
)
// Otherwise, event_path is expected to contain the path to the event in debugfs
// and it will be used to open the Perf Event FD.
// In either case, if the attach partially failed (such as issue with the
// ioctl operations), the **caller** need to clean up the Perf Event FD, either
// provided by the caller or opened here.
static
int
bpf_attach_tracing_event
(
int
progfd
,
const
char
*
event_path
,
int
pid
,
int
*
pfd
)
{
{
int
efd
,
cpu
=
0
;
int
efd
,
cpu
=
0
;
ssize_t
bytes
;
ssize_t
bytes
;
char
buf
[
PATH_MAX
];
char
buf
[
PATH_MAX
];
struct
perf_event_attr
attr
=
{};
struct
perf_event_attr
attr
=
{};
// Caller did not provided a valid Perf Event FD. Create one with the debugfs
if
(
pfd
<
0
)
{
// event path provided.
if
(
*
pfd
<
0
)
{
snprintf
(
buf
,
sizeof
(
buf
),
"%s/id"
,
event_path
);
snprintf
(
buf
,
sizeof
(
buf
),
"%s/id"
,
event_path
);
efd
=
open
(
buf
,
O_RDONLY
,
0
);
efd
=
open
(
buf
,
O_RDONLY
,
0
);
if
(
efd
<
0
)
{
if
(
efd
<
0
)
{
...
@@ -751,7 +755,6 @@ static int bpf_attach_tracing_event(int progfd, const char *event_path,
...
@@ -751,7 +755,6 @@ static int bpf_attach_tracing_event(int progfd, const char *event_path,
buf
[
bytes
]
=
'\0'
;
buf
[
bytes
]
=
'\0'
;
attr
.
config
=
strtol
(
buf
,
NULL
,
0
);
attr
.
config
=
strtol
(
buf
,
NULL
,
0
);
attr
.
type
=
PERF_TYPE_TRACEPOINT
;
attr
.
type
=
PERF_TYPE_TRACEPOINT
;
attr
.
sample_type
=
PERF_SAMPLE_RAW
|
PERF_SAMPLE_CALLCHAIN
;
attr
.
sample_period
=
1
;
attr
.
sample_period
=
1
;
attr
.
wakeup_events
=
1
;
attr
.
wakeup_events
=
1
;
// PID filter is only possible for uprobe events.
// PID filter is only possible for uprobe events.
...
@@ -762,22 +765,18 @@ static int bpf_attach_tracing_event(int progfd, const char *event_path,
...
@@ -762,22 +765,18 @@ static int bpf_attach_tracing_event(int progfd, const char *event_path,
// Tracing events do not do CPU filtering in any cases.
// Tracing events do not do CPU filtering in any cases.
if
(
pid
!=
-
1
)
if
(
pid
!=
-
1
)
cpu
=
-
1
;
cpu
=
-
1
;
pfd
=
syscall
(
__NR_perf_event_open
,
&
attr
,
pid
,
cpu
,
-
1
/* group_fd */
,
PERF_FLAG_FD_CLOEXEC
);
*
pfd
=
syscall
(
__NR_perf_event_open
,
&
attr
,
pid
,
cpu
,
-
1
/* group_fd */
,
PERF_FLAG_FD_CLOEXEC
);
if
(
pfd
<
0
)
{
if
(
*
pfd
<
0
)
{
fprintf
(
stderr
,
"perf_event_open(%s/id): %s
\n
"
,
event_path
,
strerror
(
errno
));
fprintf
(
stderr
,
"perf_event_open(%s/id): %s
\n
"
,
event_path
,
strerror
(
errno
));
return
-
1
;
return
-
1
;
}
}
}
}
perf_reader_set_fd
(
reader
,
pfd
);
if
(
perf_reader_mmap
(
reader
,
attr
.
type
,
attr
.
sample_type
)
<
0
)
if
(
ioctl
(
*
pfd
,
PERF_EVENT_IOC_SET_BPF
,
progfd
)
<
0
)
{
return
-
1
;
if
(
ioctl
(
pfd
,
PERF_EVENT_IOC_SET_BPF
,
progfd
)
<
0
)
{
perror
(
"ioctl(PERF_EVENT_IOC_SET_BPF)"
);
perror
(
"ioctl(PERF_EVENT_IOC_SET_BPF)"
);
return
-
1
;
return
-
1
;
}
}
if
(
ioctl
(
pfd
,
PERF_EVENT_IOC_ENABLE
,
0
)
<
0
)
{
if
(
ioctl
(
*
pfd
,
PERF_EVENT_IOC_ENABLE
,
0
)
<
0
)
{
perror
(
"ioctl(PERF_EVENT_IOC_ENABLE)"
);
perror
(
"ioctl(PERF_EVENT_IOC_ENABLE)"
);
return
-
1
;
return
-
1
;
}
}
...
@@ -785,24 +784,19 @@ static int bpf_attach_tracing_event(int progfd, const char *event_path,
...
@@ -785,24 +784,19 @@ static int bpf_attach_tracing_event(int progfd, const char *event_path,
return
0
;
return
0
;
}
}
void
*
bpf_attach_kprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
int
bpf_attach_kprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
const
char
*
ev_name
,
const
char
*
fn_name
,
const
char
*
ev_name
,
const
char
*
fn_name
)
perf_reader_cb
cb
,
void
*
cb_cookie
)
{
{
int
kfd
;
int
kfd
,
pfd
=
-
1
;
int
pfd
;
char
buf
[
256
];
char
buf
[
256
];
char
event_alias
[
128
];
char
event_alias
[
128
];
struct
perf_reader
*
reader
=
NULL
;
static
char
*
event_type
=
"kprobe"
;
static
char
*
event_type
=
"kprobe"
;
reader
=
perf_reader_new
(
cb
,
NULL
,
NULL
,
cb_cookie
,
probe_perf_reader_page_cnt
);
// Try create the kprobe Perf Event with perf_event_open API.
if
(
!
reader
)
goto
error
;
pfd
=
bpf_try_perf_event_open_with_probe
(
fn_name
,
0
,
-
1
,
event_type
,
pfd
=
bpf_try_perf_event_open_with_probe
(
fn_name
,
0
,
-
1
,
event_type
,
attach_type
!=
BPF_PROBE_ENTRY
);
attach_type
!=
BPF_PROBE_ENTRY
);
// If failed, most likely Kernel doesn't support the new perf_event_open API
// yet. Try create the event using debugfs.
if
(
pfd
<
0
)
{
if
(
pfd
<
0
)
{
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/%s_events"
,
event_type
);
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/%s_events"
,
event_type
);
kfd
=
open
(
buf
,
O_WRONLY
|
O_APPEND
,
0
);
kfd
=
open
(
buf
,
O_WRONLY
|
O_APPEND
,
0
);
...
@@ -823,15 +817,16 @@ void *bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type,
...
@@ -823,15 +817,16 @@ void *bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type,
close
(
kfd
);
close
(
kfd
);
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/events/%ss/%s"
,
event_type
,
event_alias
);
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/events/%ss/%s"
,
event_type
,
event_alias
);
}
}
if
(
bpf_attach_tracing_event
(
progfd
,
buf
,
reader
,
-
1
/* PID */
,
pfd
)
<
0
)
// If perf_event_open succeeded, bpf_attach_tracing_event will use the created
goto
error
;
// Perf Event FD directly and buf would be empty and unused.
// Otherwise it will read the event ID from the path in buf, create the
return
reader
;
// Perf Event event using that ID, and updated value of pfd.
if
(
bpf_attach_tracing_event
(
progfd
,
buf
,
-
1
/* PID */
,
&
pfd
)
==
0
)
return
pfd
;
error:
error:
perf_reader_free
(
reader
);
bpf_close_perf_event_fd
(
pfd
);
return
NULL
;
return
-
1
;
}
}
static
int
enter_mount_ns
(
int
pid
)
{
static
int
enter_mount_ns
(
int
pid
)
{
...
@@ -895,24 +890,19 @@ static void exit_mount_ns(int fd) {
...
@@ -895,24 +890,19 @@ static void exit_mount_ns(int fd) {
perror
(
"setns"
);
perror
(
"setns"
);
}
}
void
*
bpf_attach_uprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
int
bpf_attach_uprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
const
char
*
ev_name
,
const
char
*
binary_path
,
const
char
*
ev_name
,
const
char
*
binary_path
,
uint64_t
offset
,
pid_t
pid
,
perf_reader_cb
cb
,
uint64_t
offset
,
pid_t
pid
)
void
*
cb_cookie
)
{
{
char
buf
[
PATH_MAX
];
char
buf
[
PATH_MAX
];
char
event_alias
[
PATH_MAX
];
char
event_alias
[
PATH_MAX
];
struct
perf_reader
*
reader
=
NULL
;
static
char
*
event_type
=
"uprobe"
;
static
char
*
event_type
=
"uprobe"
;
int
res
,
kfd
=
-
1
,
ns_fd
=
-
1
;
int
res
,
kfd
=
-
1
,
pfd
=
-
1
,
ns_fd
=
-
1
;
int
pfd
;
// Try create the uprobe Perf Event with perf_event_open API.
reader
=
perf_reader_new
(
cb
,
NULL
,
NULL
,
cb_cookie
,
probe_perf_reader_page_cnt
);
if
(
!
reader
)
goto
error
;
pfd
=
bpf_try_perf_event_open_with_probe
(
binary_path
,
offset
,
pid
,
event_type
,
pfd
=
bpf_try_perf_event_open_with_probe
(
binary_path
,
offset
,
pid
,
event_type
,
attach_type
!=
BPF_PROBE_ENTRY
);
attach_type
!=
BPF_PROBE_ENTRY
);
// If failed, most likely Kernel doesn't support the new perf_event_open API
// yet. Try create the event using debugfs.
if
(
pfd
<
0
)
{
if
(
pfd
<
0
)
{
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/%s_events"
,
event_type
);
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/%s_events"
,
event_type
);
kfd
=
open
(
buf
,
O_WRONLY
|
O_APPEND
,
0
);
kfd
=
open
(
buf
,
O_WRONLY
|
O_APPEND
,
0
);
...
@@ -940,22 +930,25 @@ void *bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type,
...
@@ -940,22 +930,25 @@ void *bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type,
goto
error
;
goto
error
;
}
}
close
(
kfd
);
close
(
kfd
);
kfd
=
-
1
;
exit_mount_ns
(
ns_fd
);
exit_mount_ns
(
ns_fd
);
ns_fd
=
-
1
;
ns_fd
=
-
1
;
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/events/%ss/%s"
,
event_type
,
event_alias
);
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/events/%ss/%s"
,
event_type
,
event_alias
);
}
}
if
(
bpf_attach_tracing_event
(
progfd
,
buf
,
reader
,
pid
,
pfd
)
<
0
)
// If perf_event_open succeeded, bpf_attach_tracing_event will use the created
goto
error
;
// Perf Event FD directly and buf would be empty and unused.
// Otherwise it will read the event ID from the path in buf, create the
return
reader
;
// Perf Event event using that ID, and updated value of pfd.
if
(
bpf_attach_tracing_event
(
progfd
,
buf
,
pid
,
&
pfd
)
==
0
)
return
pfd
;
error:
error:
if
(
kfd
>=
0
)
if
(
kfd
>=
0
)
close
(
kfd
);
close
(
kfd
);
exit_mount_ns
(
ns_fd
);
exit_mount_ns
(
ns_fd
);
perf_reader_free
(
reader
);
bpf_close_perf_event_fd
(
pfd
);
return
NULL
;
return
-
1
;
}
}
static
int
bpf_detach_probe
(
const
char
*
ev_name
,
const
char
*
event_type
)
static
int
bpf_detach_probe
(
const
char
*
ev_name
,
const
char
*
event_type
)
...
@@ -1036,26 +1029,19 @@ int bpf_detach_uprobe(const char *ev_name)
...
@@ -1036,26 +1029,19 @@ int bpf_detach_uprobe(const char *ev_name)
}
}
void
*
bpf_attach_tracepoint
(
int
progfd
,
const
char
*
tp_category
,
int
bpf_attach_tracepoint
(
int
progfd
,
const
char
*
tp_category
,
const
char
*
tp_name
,
perf_reader_cb
cb
,
const
char
*
tp_name
)
void
*
cb_cookie
)
{
{
char
buf
[
256
];
char
buf
[
256
];
struct
perf_reader
*
reader
=
NULL
;
int
pfd
=
-
1
;
reader
=
perf_reader_new
(
cb
,
NULL
,
NULL
,
cb_cookie
,
probe_perf_reader_page_cnt
);
if
(
!
reader
)
goto
error
;
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/events/%s/%s"
,
snprintf
(
buf
,
sizeof
(
buf
),
"/sys/kernel/debug/tracing/events/%s/%s"
,
tp_category
,
tp_name
);
tp_category
,
tp_name
);
if
(
bpf_attach_tracing_event
(
progfd
,
buf
,
reader
,
-
1
/* PID */
,
-
1
/* pfd */
)
<
0
)
if
(
bpf_attach_tracing_event
(
progfd
,
buf
,
-
1
/* PID */
,
&
pfd
)
==
0
)
goto
error
;
return
pfd
;
return
reader
;
bpf_close_perf_event_fd
(
pfd
);
return
-
1
;
error:
perf_reader_free
(
reader
);
return
NULL
;
}
}
int
bpf_detach_tracepoint
(
const
char
*
tp_category
,
const
char
*
tp_name
)
{
int
bpf_detach_tracepoint
(
const
char
*
tp_category
,
const
char
*
tp_name
)
{
...
...
src/cc/libbpf.h
View file @
fafbf3ca
...
@@ -70,22 +70,17 @@ typedef void (*perf_reader_cb)(void *cb_cookie, int pid, uint64_t callchain_num,
...
@@ -70,22 +70,17 @@ typedef void (*perf_reader_cb)(void *cb_cookie, int pid, uint64_t callchain_num,
typedef
void
(
*
perf_reader_raw_cb
)(
void
*
cb_cookie
,
void
*
raw
,
int
raw_size
);
typedef
void
(
*
perf_reader_raw_cb
)(
void
*
cb_cookie
,
void
*
raw
,
int
raw_size
);
typedef
void
(
*
perf_reader_lost_cb
)(
void
*
cb_cookie
,
uint64_t
lost
);
typedef
void
(
*
perf_reader_lost_cb
)(
void
*
cb_cookie
,
uint64_t
lost
);
void
*
bpf_attach_kprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
int
bpf_attach_kprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
const
char
*
ev_name
,
const
char
*
fn_name
,
const
char
*
ev_name
,
const
char
*
fn_name
);
perf_reader_cb
cb
,
void
*
cb_cookie
);
int
bpf_detach_kprobe
(
const
char
*
ev_name
);
int
bpf_detach_kprobe
(
const
char
*
ev_name
);
void
*
bpf_attach_uprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
int
bpf_attach_uprobe
(
int
progfd
,
enum
bpf_probe_attach_type
attach_type
,
const
char
*
ev_name
,
const
char
*
binary_path
,
const
char
*
ev_name
,
const
char
*
binary_path
,
uint64_t
offset
,
pid_t
pid
,
perf_reader_cb
cb
,
uint64_t
offset
,
pid_t
pid
);
void
*
cb_cookie
);
int
bpf_detach_uprobe
(
const
char
*
ev_name
);
int
bpf_detach_uprobe
(
const
char
*
ev_name
);
void
*
bpf_attach_tracepoint
(
int
progfd
,
const
char
*
tp_category
,
int
bpf_attach_tracepoint
(
int
progfd
,
const
char
*
tp_category
,
const
char
*
tp_name
,
perf_reader_cb
cb
,
const
char
*
tp_name
);
void
*
cb_cookie
);
int
bpf_detach_tracepoint
(
const
char
*
tp_category
,
const
char
*
tp_name
);
int
bpf_detach_tracepoint
(
const
char
*
tp_category
,
const
char
*
tp_name
);
void
*
bpf_open_perf_buffer
(
perf_reader_raw_cb
raw_cb
,
void
*
bpf_open_perf_buffer
(
perf_reader_raw_cb
raw_cb
,
...
...
src/lua/bcc/bpf.lua
View file @
fafbf3ca
...
@@ -24,6 +24,7 @@ local Bpf = class("BPF")
...
@@ -24,6 +24,7 @@ local Bpf = class("BPF")
Bpf
.
static
.
open_kprobes
=
{}
Bpf
.
static
.
open_kprobes
=
{}
Bpf
.
static
.
open_uprobes
=
{}
Bpf
.
static
.
open_uprobes
=
{}
Bpf
.
static
.
perf_buffers
=
{}
Bpf
.
static
.
KPROBE_LIMIT
=
1000
Bpf
.
static
.
KPROBE_LIMIT
=
1000
Bpf
.
static
.
tracer_pipe
=
nil
Bpf
.
static
.
tracer_pipe
=
nil
Bpf
.
static
.
DEFAULT_CFLAGS
=
{
Bpf
.
static
.
DEFAULT_CFLAGS
=
{
...
@@ -39,8 +40,8 @@ end
...
@@ -39,8 +40,8 @@ end
function
Bpf
.
static
.
cleanup
()
function
Bpf
.
static
.
cleanup
()
local
function
detach_all
(
probe_type
,
all_probes
)
local
function
detach_all
(
probe_type
,
all_probes
)
for
key
,
probe
in
pairs
(
all_probes
)
do
for
key
,
fd
in
pairs
(
all_probes
)
do
libbcc
.
perf_reader_free
(
probe
)
libbcc
.
bpf_close_perf_event_fd
(
fd
)
-- skip bcc-specific kprobes
-- skip bcc-specific kprobes
if
not
key
:
starts
(
"bcc:"
)
then
if
not
key
:
starts
(
"bcc:"
)
then
if
probe_type
==
"kprobes"
then
if
probe_type
==
"kprobes"
then
...
@@ -55,6 +56,12 @@ function Bpf.static.cleanup()
...
@@ -55,6 +56,12 @@ function Bpf.static.cleanup()
detach_all
(
"kprobes"
,
Bpf
.
static
.
open_kprobes
)
detach_all
(
"kprobes"
,
Bpf
.
static
.
open_kprobes
)
detach_all
(
"uprobes"
,
Bpf
.
static
.
open_uprobes
)
detach_all
(
"uprobes"
,
Bpf
.
static
.
open_uprobes
)
for
key
,
perf_buffer
in
pairs
(
Bpf
.
static
.
perf_buffers
)
do
libbcc
.
perf_reader_free
(
perf_buffer
)
Bpf
.
static
.
perf_buffers
[
key
]
=
nil
end
if
Bpf
.
static
.
tracer_pipe
~=
nil
then
if
Bpf
.
static
.
tracer_pipe
~=
nil
then
Bpf
.
static
.
tracer_pipe
:
close
()
Bpf
.
static
.
tracer_pipe
:
close
()
end
end
...
@@ -189,9 +196,9 @@ function Bpf:attach_uprobe(args)
...
@@ -189,9 +196,9 @@ function Bpf:attach_uprobe(args)
local
retprobe
=
args
.
retprobe
and
1
or
0
local
retprobe
=
args
.
retprobe
and
1
or
0
local
res
=
libbcc
.
bpf_attach_uprobe
(
fn
.
fd
,
retprobe
,
ev_name
,
path
,
addr
,
local
res
=
libbcc
.
bpf_attach_uprobe
(
fn
.
fd
,
retprobe
,
ev_name
,
path
,
addr
,
args
.
pid
or
-
1
,
nil
,
nil
)
-- TODO; reader callback
args
.
pid
or
-
1
)
assert
(
res
~=
nil
,
"failed to attach BPF to uprobe"
)
assert
(
res
>=
0
,
"failed to attach BPF to uprobe"
)
self
:
probe_store
(
"uprobe"
,
ev_name
,
res
)
self
:
probe_store
(
"uprobe"
,
ev_name
,
res
)
return
self
return
self
end
end
...
@@ -206,10 +213,9 @@ function Bpf:attach_kprobe(args)
...
@@ -206,10 +213,9 @@ function Bpf:attach_kprobe(args)
local
ev_name
=
string.format
(
"%s_%s"
,
ptype
,
event
:
gsub
(
"
[
%+%.
]
"
,
"_"
))
local
ev_name
=
string.format
(
"%s_%s"
,
ptype
,
event
:
gsub
(
"
[
%+%.
]
"
,
"_"
))
local
retprobe
=
args
.
retprobe
and
1
or
0
local
retprobe
=
args
.
retprobe
and
1
or
0
local
res
=
libbcc
.
bpf_attach_kprobe
(
fn
.
fd
,
retprobe
,
ev_name
,
event
,
local
res
=
libbcc
.
bpf_attach_kprobe
(
fn
.
fd
,
retprobe
,
ev_name
,
event
)
nil
,
nil
)
-- TODO; reader callback
assert
(
res
~=
nil
,
"failed to attach BPF to kprobe"
)
assert
(
res
>=
0
,
"failed to attach BPF to kprobe"
)
self
:
probe_store
(
"kprobe"
,
ev_name
,
res
)
self
:
probe_store
(
"kprobe"
,
ev_name
,
res
)
return
self
return
self
end
end
...
@@ -228,16 +234,22 @@ function Bpf:get_table(name, key_type, leaf_type)
...
@@ -228,16 +234,22 @@ function Bpf:get_table(name, key_type, leaf_type)
return
self
.
tables
[
name
]
return
self
.
tables
[
name
]
end
end
function
Bpf
:
probe_store
(
t
,
id
,
reader
)
function
Bpf
:
probe_store
(
t
,
id
,
fd
)
if
t
==
"kprobe"
then
if
t
==
"kprobe"
then
Bpf
.
open_kprobes
[
id
]
=
reader
Bpf
.
open_kprobes
[
id
]
=
fd
elseif
t
==
"uprobe"
then
elseif
t
==
"uprobe"
then
Bpf
.
open_uprobes
[
id
]
=
reader
Bpf
.
open_uprobes
[
id
]
=
fd
else
else
error
(
"unknown probe type '%s'"
%
t
)
error
(
"unknown probe type '%s'"
%
t
)
end
end
log
.
info
(
"%s -> %s"
,
id
,
reader
)
log
.
info
(
"%s -> %s"
,
id
,
fd
)
end
function
Bpf
:
perf_buffer_store
(
t
,
id
,
reader
)
Bpf
.
perf_buffers
[
id
]
=
reader
log
.
info
(
"%s -> %s"
,
id
,
fd
)
end
end
function
Bpf
:
probe_lookup
(
t
,
id
)
function
Bpf
:
probe_lookup
(
t
,
id
)
...
@@ -250,32 +262,32 @@ function Bpf:probe_lookup(t, id)
...
@@ -250,32 +262,32 @@ function Bpf:probe_lookup(t, id)
end
end
end
end
function
Bpf
:
_
kprobe
_array
()
function
Bpf
:
_
perf_buffer
_array
()
local
kprobe_count
=
table
.
count
(
Bpf
.
open_kprobe
s
)
local
perf_buffer_count
=
table
.
count
(
Bpf
.
perf_buffer
s
)
local
readers
=
ffi
.
new
(
"struct perf_reader*[?]"
,
kprobe
_count
)
local
readers
=
ffi
.
new
(
"struct perf_reader*[?]"
,
perf_buffer
_count
)
local
n
=
0
local
n
=
0
for
_
,
r
in
pairs
(
Bpf
.
open_kprobe
s
)
do
for
_
,
r
in
pairs
(
Bpf
.
perf_buffer
s
)
do
readers
[
n
]
=
r
readers
[
n
]
=
r
n
=
n
+
1
n
=
n
+
1
end
end
assert
(
n
==
kprobe
_count
)
assert
(
n
==
perf_buffer
_count
)
return
readers
,
n
return
readers
,
n
end
end
function
Bpf
:
kprobe_poll_loop
()
function
Bpf
:
kprobe_poll_loop
()
local
p
robes
,
probe_count
=
self
:
_kprobe
_array
()
local
p
erf_buffer
,
perf_buffer_count
=
self
:
_perf_buffer
_array
()
return
pcall
(
function
()
return
pcall
(
function
()
while
true
do
while
true
do
libbcc
.
perf_reader_poll
(
p
robe_count
,
probe
s
,
-
1
)
libbcc
.
perf_reader_poll
(
p
erf_buffer_count
,
perf_buffer
s
,
-
1
)
end
end
end
)
end
)
end
end
function
Bpf
:
kprobe_poll
(
timeout
)
function
Bpf
:
kprobe_poll
(
timeout
)
local
p
robes
,
probe_count
=
self
:
_kprobe
_array
()
local
p
erf_buffer
,
perf_buffer_count
=
self
:
_perf_buffer
_array
()
libbcc
.
perf_reader_poll
(
p
robe_count
,
probe
s
,
timeout
or
-
1
)
libbcc
.
perf_reader_poll
(
p
erf_buffer_count
,
perf_buffer
s
,
timeout
or
-
1
)
end
end
return
Bpf
return
Bpf
src/lua/bcc/libbcc.lua
View file @
fafbf3ca
...
@@ -39,23 +39,22 @@ int bpf_attach_socket(int sockfd, int progfd);
...
@@ -39,23 +39,22 @@ int bpf_attach_socket(int sockfd, int progfd);
/* create RAW socket and bind to interface 'name' */
/* create RAW socket and bind to interface 'name' */
int bpf_open_raw_sock(const char *name);
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);
typedef void (*perf_reader_raw_cb)(void *cb_cookie, void *raw, int raw_size);
typedef void (*perf_reader_lost_cb)(void *cb_cookie, uint64_t lost);
typedef void (*perf_reader_lost_cb)(void *cb_cookie, uint64_t lost);
void *bpf_attach_kprobe(int progfd, int attach_type, const char *ev_name,
int bpf_attach_kprobe(int progfd, int attach_type, const char *ev_name,
const char *fn_name, perf_reader_cb cb,
const char *fn_name);
void *cb_cookie);
int bpf_detach_kprobe(const char *ev_name);
int bpf_detach_kprobe(const char *ev_name);
void *bpf_attach_uprobe(int progfd, int attach_type, const char *ev_name,
int bpf_attach_uprobe(int progfd, int attach_type, const char *ev_name,
const char *binary_path, uint64_t offset, int pid,
const char *binary_path, uint64_t offset, int pid);
perf_reader_cb cb, void *cb_cookie);
int bpf_detach_uprobe(const char *ev_name);
int bpf_detach_uprobe(const char *ev_name);
void * bpf_open_perf_buffer(perf_reader_raw_cb raw_cb, perf_reader_lost_cb lost_cb, void *cb_cookie, int pid, int cpu, int page_cnt);
void * bpf_open_perf_buffer(perf_reader_raw_cb raw_cb, perf_reader_lost_cb lost_cb, void *cb_cookie, int pid, int cpu, int page_cnt);
int bpf_close_perf_event_fd(int fd);
]]
]]
ffi
.
cdef
[[
ffi
.
cdef
[[
...
...
src/lua/bcc/table.lua
View file @
fafbf3ca
...
@@ -263,7 +263,7 @@ function PerfEventArray:_open_perf_buffer(cpu, callback, ctype, page_cnt, lost_c
...
@@ -263,7 +263,7 @@ function PerfEventArray:_open_perf_buffer(cpu, callback, ctype, page_cnt, lost_c
local
fd
=
libbcc
.
perf_reader_fd
(
reader
)
local
fd
=
libbcc
.
perf_reader_fd
(
reader
)
self
:
set
(
cpu
,
fd
)
self
:
set
(
cpu
,
fd
)
self
.
bpf
:
p
robe_store
(
"kprobe"
,
_perf_id
(
self
.
map_id
,
cpu
),
reader
)
self
.
bpf
:
p
erf_buffer_store
(
_perf_id
(
self
.
map_id
,
cpu
),
reader
)
self
.
_callbacks
[
cpu
]
=
_cb
self
.
_callbacks
[
cpu
]
=
_cb
end
end
...
...
src/python/bcc/__init__.py
View file @
fafbf3ca
This diff is collapsed.
Click to expand it.
src/python/bcc/libbcc.py
View file @
fafbf3ca
...
@@ -85,23 +85,19 @@ lib.bpf_attach_socket.argtypes = [ct.c_int, ct.c_int]
...
@@ -85,23 +85,19 @@ lib.bpf_attach_socket.argtypes = [ct.c_int, ct.c_int]
lib
.
bpf_prog_load
.
restype
=
ct
.
c_int
lib
.
bpf_prog_load
.
restype
=
ct
.
c_int
lib
.
bpf_prog_load
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_void_p
,
lib
.
bpf_prog_load
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_void_p
,
ct
.
c_size_t
,
ct
.
c_char_p
,
ct
.
c_uint
,
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_uint
]
ct
.
c_size_t
,
ct
.
c_char_p
,
ct
.
c_uint
,
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_uint
]
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
)
_RAW_CB_TYPE
=
ct
.
CFUNCTYPE
(
None
,
ct
.
py_object
,
ct
.
c_void_p
,
ct
.
c_int
)
_LOST_CB_TYPE
=
ct
.
CFUNCTYPE
(
None
,
ct
.
py_object
,
ct
.
c_ulonglong
)
_LOST_CB_TYPE
=
ct
.
CFUNCTYPE
(
None
,
ct
.
py_object
,
ct
.
c_ulonglong
)
lib
.
bpf_attach_kprobe
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_char_p
,
lib
.
bpf_attach_kprobe
.
restype
=
ct
.
c_int
_CB_TYPE
,
ct
.
py_object
]
lib
.
bpf_attach_kprobe
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_char_p
]
lib
.
bpf_detach_kprobe
.
restype
=
ct
.
c_int
lib
.
bpf_detach_kprobe
.
restype
=
ct
.
c_int
lib
.
bpf_detach_kprobe
.
argtypes
=
[
ct
.
c_char_p
]
lib
.
bpf_detach_kprobe
.
argtypes
=
[
ct
.
c_char_p
]
lib
.
bpf_attach_uprobe
.
restype
=
ct
.
c_
void_p
lib
.
bpf_attach_uprobe
.
restype
=
ct
.
c_
int
lib
.
bpf_attach_uprobe
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_char_p
,
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
,
_CB_TYPE
,
ct
.
py_object
]
ct
.
c_ulonglong
,
ct
.
c_int
]
lib
.
bpf_detach_uprobe
.
restype
=
ct
.
c_int
lib
.
bpf_detach_uprobe
.
restype
=
ct
.
c_int
lib
.
bpf_detach_uprobe
.
argtypes
=
[
ct
.
c_char_p
]
lib
.
bpf_detach_uprobe
.
argtypes
=
[
ct
.
c_char_p
]
lib
.
bpf_attach_tracepoint
.
restype
=
ct
.
c_void_p
lib
.
bpf_attach_tracepoint
.
restype
=
ct
.
c_int
lib
.
bpf_attach_tracepoint
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_char_p
,
lib
.
bpf_attach_tracepoint
.
argtypes
=
[
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_char_p
]
_CB_TYPE
,
ct
.
py_object
]
lib
.
bpf_detach_tracepoint
.
restype
=
ct
.
c_int
lib
.
bpf_detach_tracepoint
.
restype
=
ct
.
c_int
lib
.
bpf_detach_tracepoint
.
argtypes
=
[
ct
.
c_char_p
,
ct
.
c_char_p
]
lib
.
bpf_detach_tracepoint
.
argtypes
=
[
ct
.
c_char_p
,
ct
.
c_char_p
]
lib
.
bpf_open_perf_buffer
.
restype
=
ct
.
c_void_p
lib
.
bpf_open_perf_buffer
.
restype
=
ct
.
c_void_p
...
...
src/python/bcc/table.py
View file @
fafbf3ca
...
@@ -494,10 +494,10 @@ class PerfEventArray(ArrayBase):
...
@@ -494,10 +494,10 @@ class PerfEventArray(ArrayBase):
# Delete entry from the array
# Delete entry from the array
super
(
PerfEventArray
,
self
).
__delitem__
(
key
)
super
(
PerfEventArray
,
self
).
__delitem__
(
key
)
key_id
=
(
id
(
self
),
key
)
key_id
=
(
id
(
self
),
key
)
if
key_id
in
self
.
bpf
.
open_kprobe
s
:
if
key_id
in
self
.
bpf
.
perf_buffer
s
:
# The key is opened for perf ring buffer
# The key is opened for perf ring buffer
lib
.
perf_reader_free
(
self
.
bpf
.
open_kprobe
s
[
key_id
])
lib
.
perf_reader_free
(
self
.
bpf
.
perf_buffer
s
[
key_id
])
self
.
bpf
.
_del_kprobe
(
key_id
)
del
self
.
bpf
.
perf_buffers
[
key_id
]
del
self
.
_cbs
[
key
]
del
self
.
_cbs
[
key
]
else
:
else
:
# The key is opened for perf event read
# The key is opened for perf event read
...
@@ -544,7 +544,7 @@ class PerfEventArray(ArrayBase):
...
@@ -544,7 +544,7 @@ class PerfEventArray(ArrayBase):
raise
Exception
(
"Could not open perf buffer"
)
raise
Exception
(
"Could not open perf buffer"
)
fd
=
lib
.
perf_reader_fd
(
reader
)
fd
=
lib
.
perf_reader_fd
(
reader
)
self
[
self
.
Key
(
cpu
)]
=
self
.
Leaf
(
fd
)
self
[
self
.
Key
(
cpu
)]
=
self
.
Leaf
(
fd
)
self
.
bpf
.
_add_kprobe
((
id
(
self
),
cpu
),
reader
)
self
.
bpf
.
perf_buffers
[(
id
(
self
),
cpu
)]
=
reader
# keep a refcnt
# keep a refcnt
self
.
_cbs
[
cpu
]
=
(
fn
,
lost_fn
)
self
.
_cbs
[
cpu
]
=
(
fn
,
lost_fn
)
# The actual fd is held by the perf reader, add to track opened keys
# The actual fd is held by the perf reader, add to track opened keys
...
...
tests/python/CMakeLists.txt
View file @
fafbf3ca
...
@@ -46,8 +46,6 @@ add_test(NAME py_test_clang WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
...
@@ -46,8 +46,6 @@ add_test(NAME py_test_clang WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND
${
TEST_WRAPPER
}
py_clang sudo
${
CMAKE_CURRENT_SOURCE_DIR
}
/test_clang.py
)
COMMAND
${
TEST_WRAPPER
}
py_clang sudo
${
CMAKE_CURRENT_SOURCE_DIR
}
/test_clang.py
)
add_test
(
NAME py_test_histogram WORKING_DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
add_test
(
NAME py_test_histogram WORKING_DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
COMMAND
${
TEST_WRAPPER
}
py_histogram sudo
${
CMAKE_CURRENT_SOURCE_DIR
}
/test_histogram.py
)
COMMAND
${
TEST_WRAPPER
}
py_histogram sudo
${
CMAKE_CURRENT_SOURCE_DIR
}
/test_histogram.py
)
add_test
(
NAME py_test_callchain WORKING_DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
COMMAND
${
TEST_WRAPPER
}
py_callchain sudo
${
CMAKE_CURRENT_SOURCE_DIR
}
/test_callchain.py
)
add_test
(
NAME py_array WORKING_DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
add_test
(
NAME py_array WORKING_DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
COMMAND
${
TEST_WRAPPER
}
py_array sudo
${
CMAKE_CURRENT_SOURCE_DIR
}
/test_array.py
)
COMMAND
${
TEST_WRAPPER
}
py_array sudo
${
CMAKE_CURRENT_SOURCE_DIR
}
/test_array.py
)
add_test
(
NAME py_uprobes WORKING_DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
add_test
(
NAME py_uprobes WORKING_DIRECTORY
${
CMAKE_CURRENT_SOURCE_DIR
}
...
...
tests/python/test_callchain.py
deleted
100755 → 0
View file @
abef8350
#!/usr/bin/env python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")
from
bcc
import
BPF
import
time
from
unittest
import
main
,
TestCase
class
TestCallchain
(
TestCase
):
def
test_callchain1
(
self
):
hist
=
{}
def
cb
(
pid
,
callchain
):
counter
=
hist
.
get
(
callchain
,
0
)
counter
+=
1
hist
[
callchain
]
=
counter
b
=
BPF
(
text
=
"""
#include <linux/ptrace.h>
int kprobe__finish_task_switch(struct pt_regs *ctx) {
return 1;
}
"""
,
cb
=
cb
)
start
=
time
.
time
()
while
time
.
time
()
<
start
+
1
:
b
.
kprobe_poll
()
for
k
,
v
in
hist
.
items
():
syms
=
[
b
.
ksym
(
addr
)
for
addr
in
k
]
print
(
"%-08d:"
%
v
,
syms
)
if
__name__
==
"__main__"
:
main
()
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