Commit 0ec552a2 authored by yonghong-song's avatar yonghong-song Committed by GitHub

Merge pull request #1787 from sandip4n/dev

Add support for attaching kprobes at custom offsets
parents 84900f82 651d690a
...@@ -161,6 +161,7 @@ StatusTuple BPF::detach_all() { ...@@ -161,6 +161,7 @@ StatusTuple BPF::detach_all() {
StatusTuple BPF::attach_kprobe(const std::string& kernel_func, StatusTuple BPF::attach_kprobe(const std::string& kernel_func,
const std::string& probe_func, const std::string& probe_func,
uint64_t kernel_func_offset,
bpf_probe_attach_type attach_type) { bpf_probe_attach_type attach_type) {
std::string probe_event = get_kprobe_event(kernel_func, attach_type); std::string probe_event = get_kprobe_event(kernel_func, attach_type);
if (kprobes_.find(probe_event) != kprobes_.end()) if (kprobes_.find(probe_event) != kprobes_.end())
...@@ -170,7 +171,7 @@ StatusTuple BPF::attach_kprobe(const std::string& kernel_func, ...@@ -170,7 +171,7 @@ StatusTuple BPF::attach_kprobe(const std::string& kernel_func,
TRY2(load_func(probe_func, BPF_PROG_TYPE_KPROBE, probe_fd)); TRY2(load_func(probe_func, BPF_PROG_TYPE_KPROBE, probe_fd));
int res_fd = bpf_attach_kprobe(probe_fd, attach_type, probe_event.c_str(), int res_fd = bpf_attach_kprobe(probe_fd, attach_type, probe_event.c_str(),
kernel_func.c_str()); kernel_func.c_str(), kernel_func_offset);
if (res_fd < 0) { if (res_fd < 0) {
TRY2(unload_func(probe_func)); TRY2(unload_func(probe_func));
......
...@@ -58,6 +58,7 @@ class BPF { ...@@ -58,6 +58,7 @@ class BPF {
StatusTuple attach_kprobe(const std::string& kernel_func, StatusTuple attach_kprobe(const std::string& kernel_func,
const std::string& probe_func, const std::string& probe_func,
uint64_t kernel_func_offset = 0,
bpf_probe_attach_type = BPF_PROBE_ENTRY); bpf_probe_attach_type = BPF_PROBE_ENTRY);
StatusTuple detach_kprobe( StatusTuple detach_kprobe(
const std::string& kernel_func, const std::string& kernel_func,
......
...@@ -794,7 +794,7 @@ static int bpf_attach_tracing_event(int progfd, const char *event_path, int pid, ...@@ -794,7 +794,7 @@ static int bpf_attach_tracing_event(int progfd, const char *event_path, int pid,
} }
int bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type, int bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type,
const char *ev_name, const char *fn_name) const char *ev_name, const char *fn_name, uint64_t fn_offset)
{ {
int kfd, pfd = -1; int kfd, pfd = -1;
char buf[256]; char buf[256];
...@@ -802,7 +802,7 @@ int bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type, ...@@ -802,7 +802,7 @@ int bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type,
static char *event_type = "kprobe"; static char *event_type = "kprobe";
// Try create the kprobe Perf Event with perf_event_open API. // Try create the kprobe Perf Event with perf_event_open API.
pfd = bpf_try_perf_event_open_with_probe(fn_name, 0, -1, event_type, pfd = bpf_try_perf_event_open_with_probe(fn_name, fn_offset, -1, event_type,
attach_type != BPF_PROBE_ENTRY); attach_type != BPF_PROBE_ENTRY);
// If failed, most likely Kernel doesn't support the new perf_event_open API // If failed, most likely Kernel doesn't support the new perf_event_open API
// yet. Try create the event using debugfs. // yet. Try create the event using debugfs.
...@@ -815,8 +815,15 @@ int bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type, ...@@ -815,8 +815,15 @@ int bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type,
} }
snprintf(event_alias, sizeof(event_alias), "%s_bcc_%d", ev_name, getpid()); snprintf(event_alias, sizeof(event_alias), "%s_bcc_%d", ev_name, getpid());
snprintf(buf, sizeof(buf), "%c:%ss/%s %s", attach_type==BPF_PROBE_ENTRY ? 'p' : 'r',
if (fn_offset > 0 && attach_type == BPF_PROBE_ENTRY)
snprintf(buf, sizeof(buf), "p:%ss/%s %s+%"PRIu64,
event_type, event_alias, fn_name, fn_offset);
else
snprintf(buf, sizeof(buf), "%c:%ss/%s %s",
attach_type == BPF_PROBE_ENTRY ? 'p' : 'r',
event_type, event_alias, fn_name); event_type, event_alias, fn_name);
if (write(kfd, buf, strlen(buf)) < 0) { if (write(kfd, buf, strlen(buf)) < 0) {
if (errno == ENOENT) if (errno == ENOENT)
fprintf(stderr, "cannot attach kprobe, probe entry may not exist\n"); fprintf(stderr, "cannot attach kprobe, probe entry may not exist\n");
......
...@@ -69,7 +69,7 @@ typedef void (*perf_reader_raw_cb)(void *cb_cookie, void *raw, int raw_size); ...@@ -69,7 +69,7 @@ typedef void (*perf_reader_raw_cb)(void *cb_cookie, void *raw, int raw_size);
typedef void (*perf_reader_lost_cb)(void *cb_cookie, uint64_t lost); typedef void (*perf_reader_lost_cb)(void *cb_cookie, uint64_t lost);
int bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type, int bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type,
const char *ev_name, const char *fn_name); const char *ev_name, const char *fn_name, uint64_t fn_offset);
int bpf_detach_kprobe(const char *ev_name); int bpf_detach_kprobe(const char *ev_name);
int bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type, int bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type,
......
...@@ -550,7 +550,7 @@ class BPF(object): ...@@ -550,7 +550,7 @@ class BPF(object):
def get_syscall_fnname(self, name): def get_syscall_fnname(self, name):
return self.get_syscall_prefix() + name return self.get_syscall_prefix() + name
def attach_kprobe(self, event=b"", fn_name=b"", event_re=b""): def attach_kprobe(self, event=b"", event_off=0, fn_name=b"", event_re=b""):
event = _assert_is_bytes(event) event = _assert_is_bytes(event)
fn_name = _assert_is_bytes(fn_name) fn_name = _assert_is_bytes(fn_name)
event_re = _assert_is_bytes(event_re) event_re = _assert_is_bytes(event_re)
...@@ -569,7 +569,7 @@ class BPF(object): ...@@ -569,7 +569,7 @@ class BPF(object):
self._check_probe_quota(1) self._check_probe_quota(1)
fn = self.load_func(fn_name, BPF.KPROBE) fn = self.load_func(fn_name, BPF.KPROBE)
ev_name = b"p_" + event.replace(b"+", b"_").replace(b".", b"_") ev_name = b"p_" + event.replace(b"+", b"_").replace(b".", b"_")
fd = lib.bpf_attach_kprobe(fn.fd, 0, ev_name, event) fd = lib.bpf_attach_kprobe(fn.fd, 0, ev_name, event, event_off)
if fd < 0: if fd < 0:
raise Exception("Failed to attach BPF to kprobe") raise Exception("Failed to attach BPF to kprobe")
self._add_kprobe_fd(ev_name, fd) self._add_kprobe_fd(ev_name, fd)
......
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