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
6e682236
Commit
6e682236
authored
Dec 15, 2016
by
Teng Qin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add USDT support to C++ API
parent
9476bff0
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
137 additions
and
4 deletions
+137
-4
src/cc/BPF.cc
src/cc/BPF.cc
+92
-3
src/cc/BPF.h
src/cc/BPF.h
+45
-1
No files found.
src/cc/BPF.cc
View file @
6e682236
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
#include "bpf_module.h"
#include "bpf_module.h"
#include "libbpf.h"
#include "libbpf.h"
#include "perf_reader.h"
#include "perf_reader.h"
#include "usdt.h"
#include "BPF.h"
#include "BPF.h"
...
@@ -50,13 +51,25 @@ std::string sanitize_str(std::string str, bool (*validator)(char),
...
@@ -50,13 +51,25 @@ std::string sanitize_str(std::string str, bool (*validator)(char),
}
}
StatusTuple
BPF
::
init
(
const
std
::
string
&
bpf_program
,
StatusTuple
BPF
::
init
(
const
std
::
string
&
bpf_program
,
std
::
vector
<
std
::
string
>
cflags
)
{
std
::
vector
<
std
::
string
>
cflags
,
std
::
vector
<
USDT
>
usdt
)
{
std
::
string
all_bpf_program
;
for
(
auto
u
:
usdt
)
{
if
(
!
u
.
initialized_
)
TRY2
(
u
.
init
());
all_bpf_program
+=
u
.
program_text_
;
usdt_
.
push_back
(
std
::
move
(
u
));
}
auto
flags_len
=
cflags
.
size
();
auto
flags_len
=
cflags
.
size
();
const
char
*
flags
[
flags_len
];
const
char
*
flags
[
flags_len
];
for
(
size_t
i
=
0
;
i
<
flags_len
;
i
++
)
for
(
size_t
i
=
0
;
i
<
flags_len
;
i
++
)
flags
[
i
]
=
cflags
[
i
].
c_str
();
flags
[
i
]
=
cflags
[
i
].
c_str
();
if
(
bpf_module_
->
load_string
(
bpf_program
,
flags
,
flags_len
)
!=
0
)
all_bpf_program
+=
bpf_program
;
if
(
bpf_module_
->
load_string
(
all_bpf_program
,
flags
,
flags_len
)
!=
0
)
return
StatusTuple
(
-
1
,
"Unable to initialize BPF program"
);
return
StatusTuple
(
-
1
,
"Unable to initialize BPF program"
);
return
StatusTuple
(
0
);
return
StatusTuple
(
0
);
};
};
...
@@ -206,6 +219,37 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
...
@@ -206,6 +219,37 @@ StatusTuple BPF::attach_uprobe(const std::string& binary_path,
return
StatusTuple
(
0
);
return
StatusTuple
(
0
);
}
}
StatusTuple
BPF
::
attach_usdt
(
const
USDT
&
usdt
,
pid_t
pid
,
int
cpu
,
int
group_fd
)
{
for
(
auto
&
u
:
usdt_
)
if
(
u
==
usdt
)
{
bool
failed
=
false
;
std
::
string
err_msg
;
int
cnt
=
0
;
for
(
auto
addr
:
u
.
addresses_
)
{
auto
res
=
attach_uprobe
(
u
.
binary_path_
,
std
::
string
(),
u
.
probe_func_
,
addr
);
if
(
res
.
code
()
!=
0
)
{
failed
=
true
;
err_msg
+=
"USDT "
+
u
.
print_name
()
+
" at "
+
std
::
to_string
(
addr
);
err_msg
+=
": "
+
res
.
msg
()
+
"
\n
"
;
break
;
}
cnt
++
;
}
if
(
failed
)
{
for
(
int
i
=
0
;
i
<
cnt
;
i
++
)
{
auto
res
=
detach_uprobe
(
u
.
binary_path_
,
std
::
string
(),
u
.
addresses_
[
i
]);
err_msg
+=
"During clean up: "
+
res
.
msg
()
+
"
\n
"
;
}
return
StatusTuple
(
-
1
,
err_msg
);
}
else
return
StatusTuple
(
0
);
}
return
StatusTuple
(
-
1
,
"USDT %s not found"
,
usdt
.
print_name
().
c_str
());
}
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
,
pid_t
pid
,
int
cpu
,
int
group_fd
,
pid_t
pid
,
int
cpu
,
int
group_fd
,
...
@@ -311,6 +355,27 @@ StatusTuple BPF::detach_uprobe(const std::string& binary_path,
...
@@ -311,6 +355,27 @@ StatusTuple BPF::detach_uprobe(const std::string& binary_path,
return
StatusTuple
(
0
);
return
StatusTuple
(
0
);
}
}
StatusTuple
BPF
::
detach_usdt
(
const
USDT
&
usdt
)
{
for
(
auto
&
u
:
usdt_
)
if
(
u
==
usdt
)
{
bool
failed
=
false
;
std
::
string
err_msg
;
for
(
auto
addr
:
u
.
addresses_
)
{
auto
res
=
detach_uprobe
(
u
.
binary_path_
,
std
::
string
(),
addr
);
if
(
res
.
code
()
!=
0
)
{
failed
=
true
;
err_msg
+=
"USDT "
+
u
.
print_name
()
+
" at "
+
std
::
to_string
(
addr
);
err_msg
+=
": "
+
res
.
msg
()
+
"
\n
"
;
}
}
if
(
failed
)
return
StatusTuple
(
-
1
,
err_msg
);
else
return
StatusTuple
(
0
);
}
return
StatusTuple
(
-
1
,
"USDT %s not found"
,
usdt
.
print_name
().
c_str
());
}
StatusTuple
BPF
::
detach_tracepoint
(
const
std
::
string
&
tracepoint
)
{
StatusTuple
BPF
::
detach_tracepoint
(
const
std
::
string
&
tracepoint
)
{
auto
it
=
tracepoints_
.
find
(
tracepoint
);
auto
it
=
tracepoints_
.
find
(
tracepoint
);
if
(
it
==
tracepoints_
.
end
())
if
(
it
==
tracepoints_
.
end
())
...
@@ -383,7 +448,7 @@ StatusTuple BPF::load_func(const std::string& func_name,
...
@@ -383,7 +448,7 @@ StatusTuple BPF::load_func(const std::string& func_name,
StatusTuple
BPF
::
unload_func
(
const
std
::
string
&
func_name
)
{
StatusTuple
BPF
::
unload_func
(
const
std
::
string
&
func_name
)
{
auto
it
=
funcs_
.
find
(
func_name
);
auto
it
=
funcs_
.
find
(
func_name
);
if
(
it
==
funcs_
.
end
())
if
(
it
==
funcs_
.
end
())
return
StatusTuple
(
-
1
,
"Probe function %s not loaded"
,
func_name
.
c_str
()
);
return
StatusTuple
(
0
);
int
res
=
close
(
it
->
second
);
int
res
=
close
(
it
->
second
);
if
(
res
!=
0
)
if
(
res
!=
0
)
...
@@ -478,4 +543,28 @@ StatusTuple BPF::detach_perf_event_all_cpu(open_probe_t& attr) {
...
@@ -478,4 +543,28 @@ StatusTuple BPF::detach_perf_event_all_cpu(open_probe_t& attr) {
return
StatusTuple
(
0
);
return
StatusTuple
(
0
);
}
}
StatusTuple
USDT
::
init
()
{
auto
ctx
=
std
::
unique_ptr
<::
USDT
::
Context
>
(
new
::
USDT
::
Context
(
binary_path_
));
if
(
!
ctx
->
loaded
())
return
StatusTuple
(
-
1
,
"Unable to load USDT "
+
print_name
());
auto
probe
=
ctx
->
get
(
name_
);
if
(
probe
==
nullptr
)
return
StatusTuple
(
-
1
,
"Unable to find USDT "
+
print_name
());
if
(
!
probe
->
enable
(
probe_func_
))
return
StatusTuple
(
-
1
,
"Failed to enable USDT "
+
print_name
());
std
::
ostringstream
stream
;
if
(
!
probe
->
usdt_getarg
(
stream
))
return
StatusTuple
(
-
1
,
"Unable to generate program text for USDT "
+
print_name
());
program_text_
=
::
USDT
::
USDT_PROGRAM_HEADER
+
stream
.
str
();
for
(
size_t
i
=
0
;
i
<
probe
->
num_locations
();
i
++
)
addresses_
.
push_back
(
probe
->
address
(
i
));
initialized_
=
true
;
return
StatusTuple
(
0
);
}
}
// namespace ebpf
}
// namespace ebpf
src/cc/BPF.h
View file @
6e682236
...
@@ -40,13 +40,16 @@ struct open_probe_t {
...
@@ -40,13 +40,16 @@ struct open_probe_t {
std
::
map
<
int
,
int
>*
per_cpu_fd
;
std
::
map
<
int
,
int
>*
per_cpu_fd
;
};
};
class
USDT
;
class
BPF
{
class
BPF
{
public:
public:
static
const
int
BPF_MAX_STACK_DEPTH
=
127
;
static
const
int
BPF_MAX_STACK_DEPTH
=
127
;
explicit
BPF
(
unsigned
int
flag
=
0
)
:
bpf_module_
(
new
BPFModule
(
flag
))
{}
explicit
BPF
(
unsigned
int
flag
=
0
)
:
bpf_module_
(
new
BPFModule
(
flag
))
{}
StatusTuple
init
(
const
std
::
string
&
bpf_program
,
StatusTuple
init
(
const
std
::
string
&
bpf_program
,
std
::
vector
<
std
::
string
>
cflags
=
{});
std
::
vector
<
std
::
string
>
cflags
=
{},
std
::
vector
<
USDT
>
usdt
=
{});
~
BPF
();
~
BPF
();
StatusTuple
detach_all
();
StatusTuple
detach_all
();
...
@@ -70,6 +73,9 @@ public:
...
@@ -70,6 +73,9 @@ public:
const
std
::
string
&
binary_path
,
const
std
::
string
&
symbol
,
const
std
::
string
&
binary_path
,
const
std
::
string
&
symbol
,
uint64_t
symbol_addr
=
0
,
uint64_t
symbol_addr
=
0
,
bpf_attach_type
attach_type
=
bpf_attach_type
::
probe_entry
);
bpf_attach_type
attach_type
=
bpf_attach_type
::
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
);
StatusTuple
attach_tracepoint
(
const
std
::
string
&
tracepoint
,
StatusTuple
attach_tracepoint
(
const
std
::
string
&
tracepoint
,
const
std
::
string
&
probe_func
,
const
std
::
string
&
probe_func
,
...
@@ -151,6 +157,8 @@ private:
...
@@ -151,6 +157,8 @@ private:
std
::
map
<
std
::
string
,
int
>
funcs_
;
std
::
map
<
std
::
string
,
int
>
funcs_
;
std
::
vector
<
USDT
>
usdt_
;
std
::
map
<
std
::
string
,
open_probe_t
>
kprobes_
;
std
::
map
<
std
::
string
,
open_probe_t
>
kprobes_
;
std
::
map
<
std
::
string
,
open_probe_t
>
uprobes_
;
std
::
map
<
std
::
string
,
open_probe_t
>
uprobes_
;
std
::
map
<
std
::
string
,
open_probe_t
>
tracepoints_
;
std
::
map
<
std
::
string
,
open_probe_t
>
tracepoints_
;
...
@@ -158,4 +166,40 @@ private:
...
@@ -158,4 +166,40 @@ private:
std
::
map
<
std
::
pair
<
uint32_t
,
uint32_t
>
,
open_probe_t
>
perf_events_
;
std
::
map
<
std
::
pair
<
uint32_t
,
uint32_t
>
,
open_probe_t
>
perf_events_
;
};
};
class
USDT
{
public:
USDT
(
const
std
::
string
&
binary_path
,
const
std
::
string
&
provider
,
const
std
::
string
&
name
,
const
std
::
string
&
probe_func
)
:
initialized_
(
false
),
binary_path_
(
binary_path
),
provider_
(
provider
),
name_
(
name
),
probe_func_
(
probe_func
)
{}
bool
operator
==
(
const
USDT
&
other
)
const
{
return
(
provider_
==
other
.
provider_
)
&&
(
name_
==
other
.
name_
)
&&
(
binary_path_
==
other
.
binary_path_
)
&&
(
probe_func_
==
other
.
probe_func_
);
}
std
::
string
print_name
()
const
{
return
provider_
+
":"
+
name_
+
" from "
+
binary_path_
;
}
private:
StatusTuple
init
();
bool
initialized_
;
std
::
string
binary_path_
;
std
::
string
provider_
;
std
::
string
name_
;
std
::
string
probe_func_
;
std
::
vector
<
intptr_t
>
addresses_
;
std
::
string
program_text_
;
friend
class
BPF
;
};
}
// namespace ebpf
}
// namespace ebpf
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