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
0e12b25b
Commit
0e12b25b
authored
Jun 10, 2017
by
Alastair Robertson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow different sized map keys (not just 64-bit ints)
parent
10dabe2b
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
161 additions
and
91 deletions
+161
-91
src/CMakeLists.txt
src/CMakeLists.txt
+1
-0
src/bpftrace.cpp
src/bpftrace.cpp
+20
-26
src/bpftrace.h
src/bpftrace.h
+1
-1
src/map.cpp
src/map.cpp
+6
-24
src/map.h
src/map.h
+3
-2
src/mapkey.cpp
src/mapkey.cpp
+68
-0
src/mapkey.h
src/mapkey.h
+25
-0
src/semantic_analyser.cpp
src/semantic_analyser.cpp
+12
-12
src/semantic_analyser.h
src/semantic_analyser.h
+1
-1
src/types.cpp
src/types.cpp
+11
-0
src/types.h
src/types.h
+12
-25
tests/CMakeLists.txt
tests/CMakeLists.txt
+1
-0
No files found.
src/CMakeLists.txt
View file @
0e12b25b
...
...
@@ -21,6 +21,7 @@ add_executable(bpftrace
lex.yy.cc
main.cpp
map.cpp
mapkey.cpp
parser.tab.cc
printer.cpp
semantic_analyser.cpp
...
...
src/bpftrace.cpp
View file @
0e12b25b
...
...
@@ -70,10 +70,10 @@ int BPFtrace::print_maps()
int
BPFtrace
::
print_map
(
Map
&
map
)
{
std
::
vector
<
uint
64
_t
>
old_key
;
std
::
vector
<
uint
8
_t
>
old_key
;
try
{
old_key
=
find_empty_key
(
map
,
map
.
args
_
.
size
());
old_key
=
find_empty_key
(
map
,
map
.
key
_
.
size
());
}
catch
(
std
::
runtime_error
&
e
)
{
...
...
@@ -85,7 +85,7 @@ int BPFtrace::print_map(Map &map)
while
(
bpf_get_next_key
(
map
.
mapfd_
,
old_key
.
data
(),
key
.
data
())
==
0
)
{
std
::
cout
<<
map
.
name_
<<
argument_list
(
key
,
map
.
args_
.
size
()
)
<<
": "
;
std
::
cout
<<
map
.
name_
<<
map
.
key_
.
argument_value_list
(
key
)
<<
": "
;
uint64_t
value
;
int
err
=
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
&
value
);
...
...
@@ -111,10 +111,10 @@ int BPFtrace::print_map_quantize(Map &map)
// e.g. A map defined as: @x[1, 2] = @quantize(3);
// would actually be stored with the key: [1, 2, 3]
std
::
vector
<
uint
64
_t
>
old_key
;
std
::
vector
<
uint
8
_t
>
old_key
;
try
{
old_key
=
find_empty_key
(
map
,
map
.
args_
.
size
()
+
1
);
old_key
=
find_empty_key
(
map
,
map
.
key_
.
size
()
+
8
);
}
catch
(
std
::
runtime_error
&
e
)
{
...
...
@@ -124,14 +124,14 @@ int BPFtrace::print_map_quantize(Map &map)
}
auto
key
(
old_key
);
std
::
map
<
std
::
vector
<
uint
64_t
>
,
std
::
vector
<
uint64_t
>>
values
;
std
::
map
<
std
::
vector
<
uint
8_t
>
,
std
::
vector
<
uint64_t
>>
values_by_key
;
while
(
bpf_get_next_key
(
map
.
mapfd_
,
old_key
.
data
(),
key
.
data
())
==
0
)
{
auto
key_prefix
=
std
::
vector
<
uint
64_t
>
(
map
.
args
_
.
size
());
int
bucket
=
key
.
at
(
map
.
args
_
.
size
());
auto
key_prefix
=
std
::
vector
<
uint
8_t
>
(
map
.
key
_
.
size
());
int
bucket
=
key
.
at
(
map
.
key
_
.
size
());
for
(
int
i
=
0
;
i
<
map
.
args
_
.
size
();
i
++
)
for
(
size_t
i
=
0
;
i
<
map
.
key
_
.
size
();
i
++
)
key_prefix
.
at
(
i
)
=
key
.
at
(
i
);
uint64_t
value
;
...
...
@@ -142,19 +142,19 @@ int BPFtrace::print_map_quantize(Map &map)
return
-
1
;
}
if
(
values
.
find
(
key_prefix
)
==
values
.
end
())
if
(
values
_by_key
.
find
(
key_prefix
)
==
values_by_key
.
end
())
{
// New key - create a list of buckets for it
values
[
key_prefix
]
=
std
::
vector
<
uint64_t
>
(
65
);
values
_by_key
[
key_prefix
]
=
std
::
vector
<
uint64_t
>
(
65
);
}
values
[
key_prefix
].
at
(
bucket
)
=
value
;
values
_by_key
[
key_prefix
].
at
(
bucket
)
=
value
;
old_key
=
key
;
}
for
(
auto
&
map_elem
:
values
)
for
(
auto
&
map_elem
:
values
_by_key
)
{
std
::
cout
<<
map
.
name_
<<
argument
_list
(
map_elem
.
first
)
<<
": "
<<
std
::
endl
;
std
::
cout
<<
map
.
name_
<<
map
.
key_
.
argument_value
_list
(
map_elem
.
first
)
<<
": "
<<
std
::
endl
;
print_quantize
(
map_elem
.
second
);
...
...
@@ -238,26 +238,20 @@ std::string BPFtrace::quantize_index_label(int power)
return
label
.
str
();
}
std
::
vector
<
uint
64_t
>
BPFtrace
::
find_empty_key
(
Map
&
map
,
int
num_elems
)
std
::
vector
<
uint
8_t
>
BPFtrace
::
find_empty_key
(
Map
&
map
,
size_t
size
)
{
if
(
num_elems
==
0
)
num_elems
=
1
;
auto
key
=
std
::
vector
<
uint
64_t
>
(
num_elems
);
uint
64
_t
value
;
if
(
size
==
0
)
size
=
8
;
auto
key
=
std
::
vector
<
uint
8_t
>
(
size
);
uint
8
_t
value
;
if
(
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
&
value
))
return
key
;
for
(
auto
&
elem
:
key
)
{
elem
=
0xffffffffffffffff
;
}
for
(
auto
&
elem
:
key
)
elem
=
0xff
;
if
(
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
&
value
))
return
key
;
for
(
auto
&
elem
:
key
)
{
elem
=
0x5555555555555555
;
}
for
(
auto
&
elem
:
key
)
elem
=
0x55
;
if
(
bpf_lookup_elem
(
map
.
mapfd_
,
key
.
data
(),
&
value
))
return
key
;
...
...
src/bpftrace.h
View file @
0e12b25b
...
...
@@ -31,7 +31,7 @@ private:
int
print_map_quantize
(
Map
&
map
);
int
print_quantize
(
std
::
vector
<
uint64_t
>
values
);
std
::
string
quantize_index_label
(
int
power
);
std
::
vector
<
uint
64_t
>
find_empty_key
(
Map
&
map
,
int
num_elems
);
std
::
vector
<
uint
8_t
>
find_empty_key
(
Map
&
map
,
size_t
size
);
};
}
// namespace bpftrace
src/map.cpp
View file @
0e12b25b
...
...
@@ -6,32 +6,14 @@
namespace
bpftrace
{
Map
::
Map
(
std
::
string
&
name
,
Type
type
,
std
::
vector
<
Type
>
&
args
)
:
name_
(
name
),
type_
(
type
),
args_
(
args
)
Map
::
Map
(
std
::
string
&
name
,
Type
type
,
MapKey
key
)
:
name_
(
name
),
type_
(
type
),
key_
(
key
)
{
int
key_size
=
0
;
if
(
args
.
size
()
>
0
)
{
for
(
auto
type
:
args
)
{
switch
(
type
)
{
case
Type
:
:
integer
:
key_size
+=
8
;
break
;
default:
abort
();
}
}
if
(
type
==
Type
::
quantize
)
{
key_size
+=
8
;
}
}
else
{
int
key_size
=
key
.
size
();
if
(
type
==
Type
::
quantize
)
key_size
+=
8
;
if
(
key_size
==
0
)
key_size
=
8
;
}
int
value_size
=
8
;
int
max_entries
=
128
;
...
...
src/map.h
View file @
0e12b25b
...
...
@@ -4,13 +4,14 @@
#include <string>
#include <vector>
#include "mapkey.h"
#include "types.h"
namespace
bpftrace
{
class
Map
{
public:
Map
(
std
::
string
&
,
Type
type
,
std
::
vector
<
Type
>
&
args
);
Map
(
std
::
string
&
name
,
Type
type
,
MapKey
key
);
~
Map
();
Map
(
const
Map
&
)
=
delete
;
Map
&
operator
=
(
const
Map
&
)
=
delete
;
...
...
@@ -18,7 +19,7 @@ public:
int
mapfd_
;
std
::
string
name_
;
Type
type_
;
std
::
vector
<
Type
>
args
_
;
MapKey
key
_
;
};
}
// namespace bpftrace
src/mapkey.cpp
0 → 100644
View file @
0e12b25b
#include "mapkey.h"
namespace
bpftrace
{
bool
MapKey
::
operator
!=
(
const
MapKey
&
k
)
const
{
return
args_
!=
k
.
args_
;
}
size_t
MapKey
::
size
()
const
{
size_t
size
=
0
;
for
(
auto
&
arg
:
args_
)
size
+=
arg
.
size
;
return
size
;
}
std
::
string
MapKey
::
argument_type_list
()
const
{
size_t
n
=
args_
.
size
();
if
(
n
==
0
)
return
"[]"
;
std
::
ostringstream
list
;
list
<<
"["
;
for
(
size_t
i
=
0
;
i
<
n
-
1
;
i
++
)
list
<<
args_
.
at
(
i
)
<<
", "
;
list
<<
args_
.
at
(
n
-
1
)
<<
"]"
;
return
list
.
str
();
}
std
::
string
MapKey
::
argument_value_list
(
const
std
::
vector
<
uint8_t
>
&
data
)
const
{
size_t
n
=
args_
.
size
();
if
(
n
==
0
)
return
""
;
std
::
ostringstream
list
;
list
<<
"["
;
int
offset
=
0
;
for
(
size_t
i
=
0
;
i
<
n
-
1
;
i
++
)
{
const
MapKeyArgument
&
arg
=
args_
.
at
(
i
);
list
<<
argument_value
(
arg
,
&
data
.
at
(
offset
))
<<
", "
;
offset
+=
arg
.
size
;
}
const
MapKeyArgument
&
arg
=
args_
.
at
(
n
-
1
);
list
<<
argument_value
(
arg
,
&
data
.
at
(
offset
))
<<
"]"
;
return
list
.
str
();
}
std
::
string
MapKey
::
argument_value
(
const
MapKeyArgument
&
arg
,
const
void
*
data
)
const
{
switch
(
arg
.
type
)
{
case
Type
:
:
integer
:
switch
(
arg
.
size
)
{
case
8
:
return
std
::
to_string
(
*
(
uint64_t
*
)
data
);
case
4
:
return
std
::
to_string
(
*
(
uint32_t
*
)
data
);
}
}
abort
();
}
}
// namespace bpftrace
src/mapkey.h
0 → 100644
View file @
0e12b25b
#pragma once
#include <string>
#include <vector>
#include "types.h"
namespace
bpftrace
{
class
MapKey
{
public:
std
::
vector
<
MapKeyArgument
>
args_
;
bool
operator
!=
(
const
MapKey
&
k
)
const
;
size_t
size
()
const
;
std
::
string
argument_type_list
()
const
;
std
::
string
argument_value_list
(
const
std
::
vector
<
uint8_t
>
&
data
)
const
;
private:
std
::
string
argument_value
(
const
MapKeyArgument
&
arg
,
const
void
*
data
)
const
;
};
}
// namespace bpftrace
src/semantic_analyser.cpp
View file @
0e12b25b
...
...
@@ -66,27 +66,27 @@ void SemanticAnalyser::visit(Call &call)
void
SemanticAnalyser
::
visit
(
Map
&
map
)
{
std
::
vector
<
Type
>
args
;
MapKey
key
;
if
(
map
.
vargs
)
{
for
(
Expression
*
expr
:
*
map
.
vargs
)
{
expr
->
accept
(
*
this
);
args
.
push_back
(
type_
);
key
.
args_
.
push_back
({
type_
,
8
}
);
}
}
auto
search
=
map_
args
_
.
find
(
map
.
ident
);
if
(
search
!=
map_
args
_
.
end
())
{
if
(
search
->
second
!=
args
)
{
auto
search
=
map_
key
_
.
find
(
map
.
ident
);
if
(
search
!=
map_
key
_
.
end
())
{
if
(
search
->
second
!=
key
)
{
err_
<<
"Argument mismatch for "
<<
map
.
ident
<<
": "
;
err_
<<
"trying to access with arguments: "
;
err_
<<
argument_list
(
args
,
true
);
err_
<<
key
.
argument_type_list
(
);
err_
<<
"
\n\t
when map expects arguments: "
;
err_
<<
argument_list
(
search
->
second
,
true
);
err_
<<
search
->
second
.
argument_type_list
(
);
err_
<<
"
\n
"
<<
std
::
endl
;
}
}
else
{
map_
args_
.
insert
({
map
.
ident
,
args
});
map_
key_
.
insert
({
map
.
ident
,
key
});
}
auto
search_val
=
map_val_
.
find
(
map
.
ident
);
...
...
@@ -237,12 +237,12 @@ int SemanticAnalyser::create_maps()
std
::
string
map_name
=
map_val
.
first
;
Type
type
=
map_val
.
second
;
auto
search_args
=
map_
args
_
.
find
(
map_name
);
if
(
search_args
==
map_
args
_
.
end
())
auto
search_args
=
map_
key
_
.
find
(
map_name
);
if
(
search_args
==
map_
key
_
.
end
())
abort
();
auto
&
args
=
search_args
->
second
;
auto
&
key
=
search_args
->
second
;
bpftrace_
.
maps_
[
map_name
]
=
std
::
make_unique
<
bpftrace
::
Map
>
(
map_name
,
type
,
args
);
bpftrace_
.
maps_
[
map_name
]
=
std
::
make_unique
<
bpftrace
::
Map
>
(
map_name
,
type
,
key
);
}
return
0
;
...
...
src/semantic_analyser.h
View file @
0e12b25b
...
...
@@ -47,7 +47,7 @@ private:
bool
is_final_pass
()
const
;
std
::
map
<
std
::
string
,
Type
>
map_val_
;
std
::
map
<
std
::
string
,
std
::
vector
<
Type
>>
map_args
_
;
std
::
map
<
std
::
string
,
MapKey
>
map_key
_
;
};
}
// namespace ast
...
...
src/types.cpp
View file @
0e12b25b
...
...
@@ -10,6 +10,17 @@ std::ostream &operator<<(std::ostream &os, Type type)
return
os
;
}
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
MapKeyArgument
arg
)
{
os
<<
arg
.
type
;
return
os
;
}
bool
MapKeyArgument
::
operator
==
(
const
MapKeyArgument
&
a
)
const
{
return
type
==
a
.
type
&&
size
==
a
.
size
;
}
std
::
string
typestr
(
Type
t
)
{
switch
(
t
)
...
...
src/types.h
View file @
0e12b25b
...
...
@@ -3,8 +3,8 @@
#include <ostream>
#include <sstream>
#include <string>
#include <unistd.h>
#include <vector>
#include <unistd.h>
#include "libbpf.h"
...
...
@@ -20,6 +20,17 @@ enum class Type
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
Type
type
);
class
MapKeyArgument
{
public:
Type
type
;
size_t
size
;
bool
operator
==
(
const
MapKeyArgument
&
a
)
const
;
};
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
MapKeyArgument
arg
);
enum
class
ProbeType
{
kprobe
,
...
...
@@ -38,28 +49,4 @@ public:
std
::
string
name
;
};
template
<
typename
T
>
std
::
string
argument_list
(
const
std
::
vector
<
T
>
&
items
,
size_t
n
,
bool
show_empty
=
false
)
{
if
(
n
==
0
)
{
if
(
show_empty
)
return
"[]"
;
return
""
;
}
std
::
ostringstream
list
;
list
<<
"["
;
for
(
size_t
i
=
0
;
i
<
n
-
1
;
i
++
)
list
<<
items
.
at
(
i
)
<<
", "
;
list
<<
items
.
at
(
n
-
1
)
<<
"]"
;
return
list
.
str
();
}
template
<
typename
T
>
std
::
string
argument_list
(
const
std
::
vector
<
T
>
&
items
,
bool
show_empty
=
false
)
{
return
argument_list
(
items
,
items
.
size
(),
show_empty
);
}
}
// namespace bpftrace
tests/CMakeLists.txt
View file @
0e12b25b
...
...
@@ -13,6 +13,7 @@ add_executable(bpftrace_test
${
CMAKE_SOURCE_DIR
}
/src/attached_probe.cpp
${
CMAKE_SOURCE_DIR
}
/src/bpftrace.cpp
${
CMAKE_SOURCE_DIR
}
/src/map.cpp
${
CMAKE_SOURCE_DIR
}
/src/mapkey.cpp
${
CMAKE_SOURCE_DIR
}
/src/semantic_analyser.cpp
${
CMAKE_SOURCE_DIR
}
/src/types.cpp
)
...
...
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