Commit ec0afc40 authored by Alastair Robertson's avatar Alastair Robertson

Allow character classes in probe names

e.g. kprobe:[Ss]y[Ss]_read { ... }
parent 35b49f6b
...@@ -6,6 +6,29 @@ For instructions on building BPFtrace, see [INSTALL.md](INSTALL.md) ...@@ -6,6 +6,29 @@ For instructions on building BPFtrace, see [INSTALL.md](INSTALL.md)
## Examples ## Examples
Count system calls:
```
kprobe:[Ss]y[Ss]_*
{
@[func] = count()
}
```
```
Attaching 376 probes...
^C
...
@[sys_open]: 579
@[SyS_ioctl]: 686
@[sys_bpf]: 730
@[sys_close]: 779
@[SyS_read]: 825
@[sys_write]: 1031
@[sys_poll]: 1796
@[sys_futex]: 2237
@[sys_recvmsg]: 2634
```
Produce a histogram of amount of time (in nanoseconds) spent in the `read()` system call: Produce a histogram of amount of time (in nanoseconds) spent in the `read()` system call:
``` ```
kprobe:sys_read kprobe:sys_read
...@@ -45,25 +68,25 @@ Attaching 2 probes... ...@@ -45,25 +68,25 @@ Attaching 2 probes...
[64k, 128k) 5 | | [64k, 128k) 5 | |
``` ```
Record the names of files that any bash process opens: Print paths of any files opened along with the name of process which opened them:
``` ```
kprobe:sys_open / comm == "bash" / kprobe:sys_open
{ {
@[str(arg0)] = count() printf("%s: %s\n", comm, str(arg0))
} }
``` ```
``` ```
Attaching 1 probe... Attaching 1 probe...
git: .git/objects/70
git: .git/objects/pack
git: .git/objects/da
git: .git/objects/pack
git: /etc/localtime
systemd-journal: /var/log/journal/72d0774c88dc4943ae3d34ac356125dd
DNS Res~ver #15: /etc/hosts
DNS Res~ver #16: /etc/hosts
DNS Res~ver #15: /etc/hosts
^C ^C
@[/usr/lib/libnsl.so.1]: 1
@[/etc/passwd]: 1
@[/usr/lib/libnss_nis.so.2]: 1
@[/usr/lib/libreadline.so.7]: 1
@[/dev/tty]: 1
@[/usr/lib/libncursesw.so.6]: 1
@[/etc/ld.so.cache]: 3
...
``` ```
Whole system profiling (TODO make example check if kernel is on-cpu before recording): Whole system profiling (TODO make example check if kernel is on-cpu before recording):
......
...@@ -43,7 +43,9 @@ int BPFtrace::add_probe(ast::Probe &p) ...@@ -43,7 +43,9 @@ int BPFtrace::add_probe(ast::Probe &p)
} }
std::vector<std::string> attach_funcs; std::vector<std::string> attach_funcs;
if (attach_point->func.find("*") != std::string::npos) if (attach_point->func.find("*") != std::string::npos ||
attach_point->func.find("[") != std::string::npos &&
attach_point->func.find("]") != std::string::npos)
{ {
std::string file_name; std::string file_name;
switch (probetype(attach_point->provider)) switch (probetype(attach_point->provider))
......
...@@ -124,9 +124,11 @@ attach_point : IDENT { $$ = new ast::AttachPoint($1); } ...@@ -124,9 +124,11 @@ attach_point : IDENT { $$ = new ast::AttachPoint($1); }
| IDENT PATH INT { $$ = new ast::AttachPoint($1, $2.substr(1, $2.size()-2), $3); } | IDENT PATH INT { $$ = new ast::AttachPoint($1, $2.substr(1, $2.size()-2), $3); }
; ;
wildcard : wildcard IDENT { $$ = $1 + $2; } wildcard : wildcard IDENT { $$ = $1 + $2; }
| wildcard MUL { $$ = $1 + "*"; } | wildcard MUL { $$ = $1 + "*"; }
| { $$ = ""; } | wildcard LBRACKET { $$ = $1 + "["; }
| wildcard RBRACKET { $$ = $1 + "]"; }
| { $$ = ""; }
; ;
pred : DIV expr ENDPRED { $$ = new ast::Predicate($2); } pred : DIV expr ENDPRED { $$ = new ast::Predicate($2); }
......
...@@ -126,6 +126,32 @@ TEST(bpftrace, add_probes_multiple) ...@@ -126,6 +126,32 @@ TEST(bpftrace, add_probes_multiple)
check_kprobe(bpftrace.get_probes().at(1), "sys_write", probe_prog_name); check_kprobe(bpftrace.get_probes().at(1), "sys_write", probe_prog_name);
} }
TEST(bpftrace, add_probes_character_class)
{
ast::AttachPoint a1("kprobe", "[Ss]y[Ss]_read");
ast::AttachPoint a2("kprobe", "sys_write");
ast::AttachPointList attach_points = { &a1, &a2 };
ast::Probe probe(&attach_points, nullptr, nullptr);
StrictMock<MockBPFtrace> bpftrace;
std::set<std::string> matches = { "SyS_read", "sys_read" };
ON_CALL(bpftrace, find_wildcard_matches(_, _, _))
.WillByDefault(Return(matches));
EXPECT_CALL(bpftrace,
find_wildcard_matches("", "[Ss]y[Ss]_read",
"/sys/kernel/debug/tracing/available_filter_functions"))
.Times(1);
EXPECT_EQ(0, bpftrace.add_probe(probe));
EXPECT_EQ(3, bpftrace.get_probes().size());
EXPECT_EQ(0, bpftrace.get_special_probes().size());
std::string probe_prog_name = "kprobe:[Ss]y[Ss]_read,kprobe:sys_write";
check_kprobe(bpftrace.get_probes().at(0), "SyS_read", probe_prog_name);
check_kprobe(bpftrace.get_probes().at(1), "sys_read", probe_prog_name);
check_kprobe(bpftrace.get_probes().at(2), "sys_write", probe_prog_name);
}
TEST(bpftrace, add_probes_wildcard) TEST(bpftrace, add_probes_wildcard)
{ {
ast::AttachPoint a1("kprobe", "sys_read"); ast::AttachPoint a1("kprobe", "sys_read");
......
...@@ -247,6 +247,14 @@ TEST(Parser, multiple_attach_points_kprobe) ...@@ -247,6 +247,14 @@ TEST(Parser, multiple_attach_points_kprobe)
" int: 1\n"); " int: 1\n");
} }
TEST(Parser, character_class_attach_point)
{
test("kprobe:[Ss]y[Ss]_read { 1 }",
"Program\n"
" kprobe:[Ss]y[Ss]_read\n"
" int: 1\n");
}
TEST(Parser, wildcard_attach_points) TEST(Parser, wildcard_attach_points)
{ {
test("kprobe:sys_* { 1 }", test("kprobe:sys_* { 1 }",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment