forked from iovisor/bcc
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKFuncExample.cc
More file actions
127 lines (109 loc) · 2.87 KB
/
KFuncExample.cc
File metadata and controls
127 lines (109 loc) · 2.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
* Copyright (c) Facebook, Inc.
* Licensed under the Apache License, Version 2.0 (the "License")
*
* Usage:
* ./KFunc
* A sample output:
* Started tracing, hit Ctrl-C to terminate.
* FD FNAME
* NONE /proc/stat
* 87 /proc/stat
* NONE /proc/8208/status
* 36 /proc/8208/status
* NONE /proc/8208/status
* 36 /proc/8208/status
* ...
*
* KFunc support is only available at kernel version 5.5 and later.
* This example only works for x64.
*/
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include "bcc_version.h"
#include "BPF.h"
const std::string BPF_PROGRAM = R"(
#include <linux/ptrace.h>
struct info_t {
char name[64];
int fd;
int is_ret;
};
BPF_PERF_OUTPUT(events);
KFUNC_PROBE(__x64_sys_openat, struct pt_regs *regs)
{
const char __user *filename = (char *)PT_REGS_PARM2(regs);
struct info_t info = {};
bpf_probe_read_user_str(info.name, sizeof(info.name), filename);
info.is_ret = 0;
events.perf_submit(ctx, &info, sizeof(info));
return 0;
}
KRETFUNC_PROBE(__x64_sys_openat, struct pt_regs *regs, int ret)
{
const char __user *filename = (char *)PT_REGS_PARM2(regs);
struct info_t info = {};
bpf_probe_read_user_str(info.name, sizeof(info.name), filename);
info.fd = ret;
info.is_ret = 1;
events.perf_submit(ctx, &info, sizeof(info));
return 0;
}
)";
struct info_t {
char name[64];
int fd;
int is_ret;
};
void handle_output(void *cb_cookie, void *data, int data_size) {
auto info = static_cast<info_t *>(data);
if (info->is_ret)
std::cout << std::setw(5) << info->fd << " " << info->name << std::endl;
else
std::cout << " NONE " << info->name << std::endl;
}
int main() {
ebpf::BPF bpf;
auto res = bpf.init(BPF_PROGRAM);
if (res.code() != 0) {
std::cerr << res.msg() << std::endl;
return 1;
}
int prog_fd;
res = bpf.load_func("kfunc____x64_sys_openat", BPF_PROG_TYPE_TRACING, prog_fd);
if (res.code() != 0) {
std::cerr << res.msg() << std::endl;
return 1;
}
int ret = bpf_attach_kfunc(prog_fd);
if (ret < 0) {
std::cerr << "bpf_attach_kfunc failed: " << ret << std::endl;
return 1;
}
res = bpf.load_func("kretfunc____x64_sys_openat", BPF_PROG_TYPE_TRACING, prog_fd);
if (res.code() != 0) {
std::cerr << res.msg() << std::endl;
return 1;
}
ret = bpf_attach_kfunc(prog_fd);
if (ret < 0) {
std::cerr << "bpf_attach_kfunc failed: " << ret << std::endl;
return 1;
}
auto open_res = bpf.open_perf_buffer("events", &handle_output);
if (open_res.code() != 0) {
std::cerr << open_res.msg() << std::endl;
return 1;
}
std::cout << "Started tracing, hit Ctrl-C to terminate." << std::endl;
std::cout << " FD FNAME" << std::endl;
auto perf_buffer = bpf.get_perf_buffer("events");
if (perf_buffer) {
while (true)
// 100ms timeout
perf_buffer->poll(100);
}
return 0;
}