Commit 651d690a authored by Sandipan Das's avatar Sandipan Das

Add support for attaching kprobes at custom offsets

Currently, attach_kprobe() only allows kprobes to be attached
to an arch-dependent default location usually in the prologue
of the function corresponding to the event.

With these changes, one can attach a kprobe at a custom offset
from the start of the function.
Signed-off-by: default avatarSandipan Das <sandipan@linux.vnet.ibm.com>
parent b50c7251
......@@ -161,6 +161,7 @@ StatusTuple BPF::detach_all() {
StatusTuple BPF::attach_kprobe(const std::string& kernel_func,
const std::string& probe_func,
uint64_t kernel_func_offset,
bpf_probe_attach_type attach_type) {
std::string probe_event = get_kprobe_event(kernel_func, attach_type);
if (kprobes_.find(probe_event) != kprobes_.end())
......@@ -170,7 +171,7 @@ StatusTuple BPF::attach_kprobe(const std::string& kernel_func,
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(),
kernel_func.c_str());
kernel_func.c_str(), kernel_func_offset);
if (res_fd < 0) {
TRY2(unload_func(probe_func));
......
......@@ -58,6 +58,7 @@ class BPF {
StatusTuple attach_kprobe(const std::string& kernel_func,
const std::string& probe_func,
uint64_t kernel_func_offset = 0,
bpf_probe_attach_type = BPF_PROBE_ENTRY);
StatusTuple detach_kprobe(
const std::string& kernel_func,
......
......@@ -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,
const char *ev_name, const char *fn_name)
const char *ev_name, const char *fn_name, uint64_t fn_offset)
{
int kfd, pfd = -1;
char buf[256];
......@@ -802,7 +802,7 @@ int bpf_attach_kprobe(int progfd, enum bpf_probe_attach_type attach_type,
static char *event_type = "kprobe";
// 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);
// If failed, most likely Kernel doesn't support the new perf_event_open API
// yet. Try create the event using debugfs.
......@@ -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(buf, sizeof(buf), "%c:%ss/%s %s", attach_type==BPF_PROBE_ENTRY ? 'p' : 'r',
event_type, event_alias, fn_name);
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);
if (write(kfd, buf, strlen(buf)) < 0) {
if (errno == ENOENT)
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);
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,
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_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type,
......
......@@ -550,7 +550,7 @@ class BPF(object):
def get_syscall_fnname(self, 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)
fn_name = _assert_is_bytes(fn_name)
event_re = _assert_is_bytes(event_re)
......@@ -569,7 +569,7 @@ class BPF(object):
self._check_probe_quota(1)
fn = self.load_func(fn_name, BPF.KPROBE)
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:
raise Exception("Failed to attach BPF to kprobe")
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