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
0e82af01
Commit
0e82af01
authored
Aug 07, 2017
by
Alastair Robertson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add func builtin
parent
834a8eae
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
121 additions
and
31 deletions
+121
-31
README.md
README.md
+1
-0
src/arch/arch.h
src/arch/arch.h
+1
-0
src/arch/x86_64.cpp
src/arch/x86_64.cpp
+5
-0
src/bpftrace.cpp
src/bpftrace.cpp
+50
-23
src/bpftrace.h
src/bpftrace.h
+9
-4
src/codegen_llvm.cpp
src/codegen_llvm.cpp
+10
-0
src/mapkey.cpp
src/mapkey.cpp
+6
-2
src/mapkey.h
src/mapkey.h
+2
-2
src/printf.cpp
src/printf.cpp
+2
-0
src/semantic_analyser.cpp
src/semantic_analyser.cpp
+11
-0
src/semantic_analyser.h
src/semantic_analyser.h
+1
-0
src/types.cpp
src/types.cpp
+19
-0
src/types.h
src/types.h
+4
-0
No files found.
README.md
View file @
0e82af01
...
...
@@ -104,6 +104,7 @@ Variables:
-
`ustack`
- User stack trace
-
`arg0`
,
`arg1`
, ... etc. - Arguments to the function being traced
-
`retval`
- Return value from function being traced
-
`func`
- Name of the function currently being traced
Functions:
-
`quantize(int n)`
- produce a log2 histogram of values of
`n`
...
...
src/arch/arch.h
View file @
0e82af01
...
...
@@ -8,6 +8,7 @@ namespace arch {
int
max_arg
();
int
arg_offset
(
int
arg_num
);
int
ret_offset
();
int
pc_offset
();
std
::
string
name
();
}
// namespace arch
...
...
src/arch/x86_64.cpp
View file @
0e82af01
...
...
@@ -29,6 +29,11 @@ int ret_offset()
return
10
;
// ax
}
int
pc_offset
()
{
return
16
;
// ip
}
std
::
string
name
()
{
return
std
::
string
(
"x86_64"
);
...
...
src/bpftrace.cpp
View file @
0e82af01
...
...
@@ -6,7 +6,6 @@
#include "bcc_syms.h"
#include "common.h"
#include "perf_reader.h"
#include "syms.h"
#include "bpftrace.h"
#include "attached_probe.h"
...
...
@@ -20,17 +19,10 @@ int BPFtrace::add_probe(ast::Probe &p)
probe
.
path
=
p
.
path
;
probe
.
attach_point
=
p
.
attach_point
;
probe
.
name
=
p
.
name
;
if
(
p
.
type
==
"kprobe"
)
probe
.
type
=
ProbeType
::
kprobe
;
else
if
(
p
.
type
==
"kretprobe"
)
probe
.
type
=
ProbeType
::
kretprobe
;
else
if
(
p
.
type
==
"uprobe"
)
probe
.
type
=
ProbeType
::
uprobe
;
else
if
(
p
.
type
==
"uretprobe"
)
probe
.
type
=
ProbeType
::
uretprobe
;
else
if
(
p
.
type
==
"BEGIN"
)
probe
.
type
=
probetype
(
p
.
type
);
if
(
p
.
type
==
"BEGIN"
)
{
probe
.
type
=
ProbeType
::
uprobe
;
probe
.
path
=
bpftrace_path_
;
probe
.
attach_point
=
"BEGIN_trigger"
;
special_probes_
.
push_back
(
probe
);
...
...
@@ -38,14 +30,11 @@ int BPFtrace::add_probe(ast::Probe &p)
}
else
if
(
p
.
type
==
"END"
)
{
probe
.
type
=
ProbeType
::
uprobe
;
probe
.
path
=
bpftrace_path_
;
probe
.
attach_point
=
"END_trigger"
;
special_probes_
.
push_back
(
probe
);
return
0
;
}
else
abort
();
probes_
.
push_back
(
probe
);
return
0
;
...
...
@@ -60,6 +49,7 @@ void perf_event_printer(void *cb_cookie, void *data, int size)
auto
args
=
bpftrace
->
format_strings_
[
fmt
];
std
::
vector
<
uint64_t
>
arg_values
;
std
::
vector
<
std
::
string
>
resolved_symbols
;
for
(
auto
arg
:
args
)
{
switch
(
arg
.
type
)
...
...
@@ -70,6 +60,14 @@ void perf_event_printer(void *cb_cookie, void *data, int size)
case
Type
:
:
string
:
arg_values
.
push_back
((
uint64_t
)
arg_data
);
break
;
case
Type
:
:
sym
:
resolved_symbols
.
push_back
(
bpftrace
->
resolve_sym
(
*
(
uint64_t
*
)
arg_data
));
arg_values
.
push_back
((
uint64_t
)
resolved_symbols
.
back
().
c_str
());
break
;
case
Type
:
:
usym
:
resolved_symbols
.
push_back
(
bpftrace
->
resolve_usym
(
*
(
uint64_t
*
)
arg_data
));
arg_values
.
push_back
((
uint64_t
)
resolved_symbols
.
back
().
c_str
());
break
;
default:
abort
();
}
...
...
@@ -221,7 +219,7 @@ void BPFtrace::poll_perf_events(int epollfd, int timeout)
return
;
}
int
BPFtrace
::
print_maps
()
const
int
BPFtrace
::
print_maps
()
{
for
(
auto
&
mapmap
:
maps_
)
{
...
...
@@ -239,7 +237,7 @@ int BPFtrace::print_maps() const
return
0
;
}
int
BPFtrace
::
print_map
(
Map
&
map
)
const
int
BPFtrace
::
print_map
(
Map
&
map
)
{
std
::
vector
<
uint8_t
>
old_key
;
try
...
...
@@ -269,6 +267,10 @@ int BPFtrace::print_map(Map &map) const
std
::
cout
<<
get_stack
(
*
(
uint32_t
*
)
value
.
data
(),
false
,
8
);
else
if
(
map
.
type_
.
type
==
Type
::
ustack
)
std
::
cout
<<
get_stack
(
*
(
uint32_t
*
)
value
.
data
(),
true
,
8
);
else
if
(
map
.
type_
.
type
==
Type
::
sym
)
std
::
cout
<<
resolve_sym
(
*
(
uint64_t
*
)
value
.
data
());
else
if
(
map
.
type_
.
type
==
Type
::
usym
)
std
::
cout
<<
resolve_usym
(
*
(
uint64_t
*
)
value
.
data
());
else
if
(
map
.
type_
.
type
==
Type
::
string
)
std
::
cout
<<
value
.
data
()
<<
std
::
endl
;
else
...
...
@@ -282,7 +284,7 @@ int BPFtrace::print_map(Map &map) const
return
0
;
}
int
BPFtrace
::
print_map_quantize
(
Map
&
map
)
const
int
BPFtrace
::
print_map_quantize
(
Map
&
map
)
{
// A quantize-map adds an extra 8 bytes onto the end of its key for storing
// the bucket number.
...
...
@@ -436,7 +438,7 @@ std::vector<uint8_t> BPFtrace::find_empty_key(Map &map, size_t size) const
throw
std
::
runtime_error
(
"Could not find empty key"
);
}
std
::
string
BPFtrace
::
get_stack
(
uint32_t
stackid
,
bool
ustack
,
int
indent
)
const
std
::
string
BPFtrace
::
get_stack
(
uint32_t
stackid
,
bool
ustack
,
int
indent
)
{
auto
stack_trace
=
std
::
vector
<
uint64_t
>
(
MAX_STACK_SIZE
);
int
err
=
bpf_lookup_elem
(
stackid_map_
->
mapfd_
,
&
stackid
,
stack_trace
.
data
());
...
...
@@ -448,21 +450,46 @@ std::string BPFtrace::get_stack(uint32_t stackid, bool ustack, int indent) const
std
::
ostringstream
stack
;
std
::
string
padding
(
indent
,
' '
);
struct
bcc_symbol
sym
;
KSyms
ksyms
;
stack
<<
"
\n
"
;
for
(
auto
&
addr
:
stack_trace
)
{
if
(
addr
==
0
)
break
;
if
(
!
ustack
&&
ksyms
.
resolve_addr
(
addr
,
&
sym
)
)
stack
<<
padding
<<
sym
.
name
<<
"+"
<<
sym
.
offset
<<
":"
<<
sym
.
module
<<
std
::
endl
;
if
(
!
ustack
)
stack
<<
padding
<<
resolve_sym
(
addr
,
true
)
<<
std
::
endl
;
else
stack
<<
padding
<<
(
void
*
)
addr
<<
std
::
endl
;
stack
<<
padding
<<
resolve_usym
(
addr
)
<<
std
::
endl
;
}
return
stack
.
str
();
}
std
::
string
BPFtrace
::
resolve_sym
(
uint64_t
addr
,
bool
show_offset
)
{
struct
bcc_symbol
sym
;
std
::
ostringstream
symbol
;
if
(
ksyms
.
resolve_addr
(
addr
,
&
sym
))
{
symbol
<<
sym
.
name
;
if
(
show_offset
)
symbol
<<
"+"
<<
sym
.
offset
;
}
else
{
symbol
<<
(
void
*
)
addr
;
}
return
symbol
.
str
();
}
std
::
string
BPFtrace
::
resolve_usym
(
uint64_t
addr
)
const
{
// TODO
std
::
ostringstream
symbol
;
symbol
<<
(
void
*
)
addr
;
return
symbol
.
str
();
}
}
// namespace bpftrace
src/bpftrace.h
View file @
0e82af01
...
...
@@ -4,6 +4,8 @@
#include <memory>
#include <vector>
#include "syms.h"
#include "ast.h"
#include "attached_probe.h"
#include "map.h"
...
...
@@ -18,8 +20,10 @@ public:
virtual
~
BPFtrace
()
{
}
virtual
int
add_probe
(
ast
::
Probe
&
p
);
int
run
();
int
print_maps
()
const
;
std
::
string
get_stack
(
uint32_t
stackid
,
bool
ustack
,
int
indent
=
0
)
const
;
int
print_maps
();
std
::
string
get_stack
(
uint32_t
stackid
,
bool
ustack
,
int
indent
=
0
);
std
::
string
resolve_sym
(
uint64_t
addr
,
bool
show_offset
=
false
);
std
::
string
resolve_usym
(
uint64_t
addr
)
const
;
std
::
map
<
std
::
string
,
std
::
unique_ptr
<
Map
>>
maps_
;
std
::
map
<
std
::
string
,
std
::
tuple
<
uint8_t
*
,
uintptr_t
>>
sections_
;
...
...
@@ -33,12 +37,13 @@ private:
std
::
vector
<
Probe
>
special_probes_
;
std
::
vector
<
std
::
unique_ptr
<
AttachedProbe
>>
attached_probes_
;
std
::
vector
<
std
::
unique_ptr
<
AttachedProbe
>>
special_attached_probes_
;
KSyms
ksyms
;
std
::
unique_ptr
<
AttachedProbe
>
attach_probe
(
Probe
&
probe
);
int
setup_perf_events
();
static
void
poll_perf_events
(
int
epollfd
,
int
timeout
=-
1
);
int
print_map
(
Map
&
map
)
const
;
int
print_map_quantize
(
Map
&
map
)
const
;
int
print_map
(
Map
&
map
);
int
print_map_quantize
(
Map
&
map
);
int
print_quantize
(
std
::
vector
<
uint64_t
>
values
)
const
;
std
::
string
quantize_index_label
(
int
power
)
const
;
std
::
vector
<
uint8_t
>
find_empty_key
(
Map
&
map
,
size_t
size
)
const
;
...
...
src/codegen_llvm.cpp
View file @
0e82af01
...
...
@@ -89,6 +89,14 @@ void CodegenLLVM::visit(Builtin &builtin)
b_
.
CreateProbeRead
(
dst
,
8
,
src
);
expr_
=
b_
.
CreateLoad
(
dst
);
}
else
if
(
builtin
.
ident
==
"func"
)
{
AllocaInst
*
dst
=
b_
.
CreateAllocaBPF
(
builtin
.
type
,
builtin
.
ident
);
int
offset
=
arch
::
pc_offset
()
*
sizeof
(
uintptr_t
);
Value
*
src
=
b_
.
CreateGEP
(
ctx_
,
b_
.
getInt64
(
offset
));
b_
.
CreateProbeRead
(
dst
,
8
,
src
);
expr_
=
b_
.
CreateLoad
(
dst
);
}
else
{
abort
();
...
...
@@ -147,6 +155,8 @@ void CodegenLLVM::visit(Call &call)
switch
(
t
.
type
)
{
case
Type
:
:
integer
:
case
Type
:
:
sym
:
case
Type
:
:
usym
:
elements
.
push_back
(
b_
.
getInt64Ty
());
break
;
case
Type
:
:
string
:
...
...
src/mapkey.cpp
View file @
0e82af01
...
...
@@ -30,7 +30,7 @@ std::string MapKey::argument_type_list() const
return
list
.
str
();
}
std
::
string
MapKey
::
argument_value_list
(
const
BPFtrace
&
bpftrace
,
std
::
string
MapKey
::
argument_value_list
(
BPFtrace
&
bpftrace
,
const
std
::
vector
<
uint8_t
>
&
data
)
const
{
size_t
n
=
args_
.
size
();
...
...
@@ -51,7 +51,7 @@ std::string MapKey::argument_value_list(const BPFtrace &bpftrace,
return
list
.
str
();
}
std
::
string
MapKey
::
argument_value
(
const
BPFtrace
&
bpftrace
,
std
::
string
MapKey
::
argument_value
(
BPFtrace
&
bpftrace
,
const
SizedType
&
arg
,
const
void
*
data
)
{
...
...
@@ -69,6 +69,10 @@ std::string MapKey::argument_value(const BPFtrace &bpftrace,
return
bpftrace
.
get_stack
(
*
(
uint32_t
*
)
data
,
false
);
case
Type
:
:
ustack
:
return
bpftrace
.
get_stack
(
*
(
uint32_t
*
)
data
,
true
);
case
Type
:
:
sym
:
return
bpftrace
.
resolve_sym
(
*
(
uint64_t
*
)
data
);
case
Type
:
:
usym
:
return
bpftrace
.
resolve_usym
(
*
(
uint64_t
*
)
data
);
case
Type
:
:
string
:
return
std
::
string
((
char
*
)
data
);
}
...
...
src/mapkey.h
View file @
0e82af01
...
...
@@ -18,11 +18,11 @@ public:
size_t
size
()
const
;
std
::
string
argument_type_list
()
const
;
std
::
string
argument_value_list
(
const
BPFtrace
&
bpftrace
,
std
::
string
argument_value_list
(
BPFtrace
&
bpftrace
,
const
std
::
vector
<
uint8_t
>
&
data
)
const
;
private:
static
std
::
string
argument_value
(
const
BPFtrace
&
bpftrace
,
static
std
::
string
argument_value
(
BPFtrace
&
bpftrace
,
const
SizedType
&
arg
,
const
void
*
data
);
};
...
...
src/printf.cpp
View file @
0e82af01
...
...
@@ -31,6 +31,8 @@ std::string verify_format_string(const std::string &fmt, std::vector<SizedType>
for
(
int
i
=
0
;
i
<
num_args
;
i
++
,
token_iter
++
)
{
Type
arg_type
=
args
.
at
(
i
).
type
;
if
(
arg_type
==
Type
::
sym
||
arg_type
==
Type
::
usym
)
arg_type
=
Type
::
string
;
// Symbols should be printed as strings
char
token
=
token_iter
->
str
()[
1
];
Type
token_type
;
...
...
src/semantic_analyser.cpp
View file @
0e82af01
...
...
@@ -46,6 +46,16 @@ void SemanticAnalyser::visit(Builtin &builtin)
else
if
(
builtin
.
ident
==
"comm"
)
{
builtin
.
type
=
SizedType
(
Type
::
string
,
STRING_SIZE
);
}
else
if
(
builtin
.
ident
==
"func"
)
{
ProbeType
type
=
probetype
(
probe_
->
type
);
if
(
type
==
ProbeType
::
kprobe
||
type
==
ProbeType
::
kretprobe
)
builtin
.
type
=
SizedType
(
Type
::
sym
,
8
);
else
if
(
type
==
ProbeType
::
uprobe
||
type
==
ProbeType
::
uretprobe
)
builtin
.
type
=
SizedType
(
Type
::
usym
,
8
);
else
err_
<<
"The func builtin can not be used with '"
<<
probe_
->
type
<<
"' probes"
<<
std
::
endl
;
}
else
if
(
!
builtin
.
ident
.
compare
(
0
,
3
,
"arg"
)
&&
builtin
.
ident
.
size
()
==
4
&&
builtin
.
ident
.
at
(
3
)
>=
'0'
&&
builtin
.
ident
.
at
(
3
)
<=
'9'
)
{
int
arg_num
=
atoi
(
builtin
.
ident
.
substr
(
3
).
c_str
());
...
...
@@ -309,6 +319,7 @@ void SemanticAnalyser::visit(Probe &probe)
{
// Clear out map of variable names - variables should be probe-local
variable_val_
.
clear
();
probe_
=
&
probe
;
if
(
probe
.
type
==
"kprobe"
||
probe
.
type
==
"kretprobe"
)
{
if
(
probe
.
attach_point
==
""
)
...
...
src/semantic_analyser.h
View file @
0e82af01
...
...
@@ -45,6 +45,7 @@ private:
bool
is_final_pass
()
const
;
Probe
*
probe_
;
std
::
map
<
std
::
string
,
SizedType
>
variable_val_
;
std
::
map
<
std
::
string
,
SizedType
>
map_val_
;
std
::
map
<
std
::
string
,
MapKey
>
map_key_
;
...
...
src/types.cpp
View file @
0e82af01
...
...
@@ -32,8 +32,27 @@ std::string typestr(Type t)
case
Type
:
:
stack
:
return
"stack"
;
break
;
case
Type
:
:
ustack
:
return
"ustack"
;
break
;
case
Type
:
:
string
:
return
"string"
;
break
;
case
Type
:
:
sym
:
return
"sym"
;
break
;
case
Type
:
:
usym
:
return
"usym"
;
break
;
default:
abort
();
}
}
ProbeType
probetype
(
const
std
::
string
&
type
)
{
if
(
type
==
"kprobe"
)
return
ProbeType
::
kprobe
;
else
if
(
type
==
"kretprobe"
)
return
ProbeType
::
kretprobe
;
else
if
(
type
==
"uprobe"
)
return
ProbeType
::
uprobe
;
else
if
(
type
==
"uretprobe"
)
return
ProbeType
::
uretprobe
;
else
if
(
type
==
"BEGIN"
)
return
ProbeType
::
uprobe
;
else
if
(
type
==
"END"
)
return
ProbeType
::
uprobe
;
return
ProbeType
::
invalid
;
}
}
// namespace bpftrace
src/types.h
View file @
0e82af01
...
...
@@ -21,6 +21,8 @@ enum class Type
stack
,
ustack
,
string
,
sym
,
usym
,
};
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
Type
type
);
...
...
@@ -40,6 +42,7 @@ std::ostream &operator<<(std::ostream &os, const SizedType &type);
enum
class
ProbeType
{
invalid
,
kprobe
,
kretprobe
,
uprobe
,
...
...
@@ -47,6 +50,7 @@ enum class ProbeType
};
std
::
string
typestr
(
Type
t
);
ProbeType
probetype
(
const
std
::
string
&
type
);
class
Probe
{
...
...
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