I've waited to reply, not wanting to clog the mailing list, but I thought it
would be beneficial to follow up on the same topic with kprobes in addition to
tracepoints. The main issue I had with tracepoints was not understanding the
8-byte alignment in the arguments. Once that was sorted, getting information
was actually really simple.
At this point I've moved to kprobes, kretprobes, and raw tracepoints. From what
I understand, if not using CO-RE or vmlinux.h, to access data from kprobes or
kretprobes you must access the cpu registers in which those values live?
For example, if I'm porting Brenden Gregg's bpftrace tool "elfsnoop" to libbpf,
I'd want to trace "load_elf_binary()." load_elf_binary() only has one argument:
"struct linux_binrprm *bprm." So if I want to read that struct, I'd have to
access the register with that argument. I think in bpf_tracing.h that macro
would be PT_REGS_PARAM1(x). I don't have the greatest understanding of asm and
cpu registers, but I believe that would be the %rdi register?
With that in mind, here's my code and build.
#include <linux/bpf.h>
#include "bpf_helpers.h"
#include "bpf_tracing.h"
#include <linux/ptrace.h>
#include <linux/types.h>
SEC("kprobe/load_elf_binary")
int trace_entry(struct pt_regs *ctx) {
char msg[] = "hello world\n"; // for verification that the bpf program is
running at all
bpf_trace_printk(msg, sizeof(msg));
struct linux_binprm *arg = (struct linux_binprm *) PT_REGS_PARM1(ctx);
return 0;
}
char _license[] SEC("license") = "GPL";
//// And the build command.
// Target arch and kernel are defined to get the correct macros
// in bpf_tracing.h
$ clang -O3 -Wall -target bpf \
-D__TARGET_ARCH_x86 \
-D__KERNEL__ -c \
elfsnoop.bpf.c \
-I/home/vagrant/libbpf/src/ \
-o elfsnoop.bpf.o
Unfortunately, as Andrii mentioned previously in this topic, I think there are
different definitions of pt_regs and my /usr/include/linux/ptrace.h does not
have the correct one, as evidenced by the error I get when trying to build.
elfsnoop.bpf.c:89:54: error: no member named 'di' in 'struct pt_regs'
struct linux_binprm *arg = (struct linux_binprm *) PT_REGS_PARM1(ctx);
^~~~~~~~~~~~~~~~~~
/home/vagrant/libbpf/src/bpf_tracing.h:54:32: note: expanded from macro
'PT_REGS_PARM1'
#define PT_REGS_PARM1(x) ((x)->di)
Is this the correct way to access data in kprobes? Most of the information I've
found explicitly talking about accessing kprobe data is pretty old (2012-2015).
selftests/bpf/ seems to not have examples of accessing kprobe data, and, from
my understanding, libbpf-tools is CO-RE dependent which I'm trying to avoid for
now just because most default kernels aren't BTF enabled yet (I will definitely
be voicing my opinion to distros that this should change since the average user
likely isn't keen on recompiling and installing a kernel). I also looked at the
brief C Appendix of "BPF Performace Tools" and "Linux Observability with BPF"
to try and understand, but I still haven't been able to extract data from the
kprobes or raw tracepoints yet.
I think the final question that may (or may not) solve this issue is which
pt_regs should be used?
Also, assuming this is the correct way, is this generalizable to raw
tracepoints and kretprobes as well?
After I have these things figured out with some working examples, I think I
will publish a github repo with a tutorial as discussed with Andrii in a few
messages above.
Appreciate any feedback and help.
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#1839): https://lists.iovisor.org/g/iovisor-dev/message/1839
Mute This Topic: https://lists.iovisor.org/mt/72496365/21656
Group Owner: [email protected]
Unsubscribe: https://lists.iovisor.org/g/iovisor-dev/unsub
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-