Error 'invalid func 45'

I’m getting the following error message when trying to print a string from a function argument:

# bpftrace -e 'u:mybinary:foo{printf("%s %u\n", str(arg2), arg3)}' -v
Attaching 1 probe...

Error log: 
0: (bf) r6 = r1
1: (b7) r1 = 0
2: (7b) *(u64 *)(r10 -144) = r1
3: (7b) *(u64 *)(r10 -136) = r1
4: (7b) *(u64 *)(r10 -128) = r1
5: (7b) *(u64 *)(r10 -120) = r1
6: (7b) *(u64 *)(r10 -112) = r1
7: (7b) *(u64 *)(r10 -104) = r1
8: (7b) *(u64 *)(r10 -96) = r1
9: (7b) *(u64 *)(r10 -88) = r1
10: (7b) *(u64 *)(r10 -80) = r1
11: (7b) *(u64 *)(r10 -64) = r1
12: (7b) *(u64 *)(r10 -56) = r1
13: (7b) *(u64 *)(r10 -48) = r1
14: (7b) *(u64 *)(r10 -40) = r1
15: (7b) *(u64 *)(r10 -32) = r1
16: (7b) *(u64 *)(r10 -24) = r1
17: (7b) *(u64 *)(r10 -16) = r1
18: (7b) *(u64 *)(r10 -8) = r1
19: (79) r3 = *(u64 *)(r6 +96)
20: (bf) r1 = r10
21: (07) r1 += -64
22: (b7) r2 = 64
23: (85) call 45
invalid func 45

Per my previous post, this is on Debian Stretch. I see it with bpftrace 0.8 and 0.11.

Thanks,
Rafael

Can you share the output of bpftrace --info? Helper 45 is probe_read_str(). Maybe your kernel is too old to have that.

Sure. I’m also only seeing uprobes (no uretprobes) for my binary, don’t if that could be related.

# bpftrace --info
System
  OS: Linux 4.9.0-12-amd64 #1 SMP Debian 4.9.210-1 (2020-01-20)
  Arch: x86_64

Build
  version: v0.11.0-87-gbe56
  LLVM: 9
  foreach_sym: yes
  unsafe uprobe: no
  bfd: no
  bpf_attach_kfunc: no
  bcc_usdt_addsem: no
  libbpf: yes
  libbpf btf dump: no
  libbpf btf dump type decl: no

Kernel helpers
  probe_read: yes
  probe_read_str: yes
  probe_read_user: yes
  probe_read_user_str: yes
  probe_read_kernel: yes
  probe_read_kernel_str: yes
  get_current_cgroup_id: yes
  send_signal: yes
  override_return: yes

Kernel features
  Instruction limit: -1
  Loop support: no
  btf (depends on Build:libbpf): no

Map types
  hash: yes
  percpu hash: yes
  array: yes
  percpu array: yes
  stack_trace: yes
  perf_event_array: yes

Probe types
  kprobe: no
  tracepoint: yes
  perf_event: yes
  kfunc: no

Does Debian backport BPF functionalities?
According to this, the helper functions other than probe_read are introduced in kernel 4.11 or later.
I suspect that the output of bpftrace --info is incorrect for some reason.

How did you get bpftrace to build on stretch, seems like you need to update to get the required build tools and even then the kernel is missing all kinds of things.

Hmm… interesting, thanks for the info

It built fine with the alpine docker image. I manually installed libbpfcc_0.8.0 and libtinfo6_6.1 from Stretch’s pkg archives.

Ah ok, so you didn’t build directly on the host. That explains it :slight_smile:

I created 1479 to fix the feature detection on older kernels which you can try, it should now show correctly show probe-read_string as missing.

If you’re really stuck on stretch you could use the buf call with a fixed size like:

$ sudo bpftrace -e 't:syscalls:sys_enter_openat { printf("%r\n", buf(args->filename, 64)); }'
Attaching 1 probe...
/var/run/utmp\x00\x00\x00RTLD_NEXT used in code not dynamically loaded\x00\x00\x00
/usr/local/share/dbus-1/system-services\x00!\x00\x00\x00\x00\x00\x00\x00@O\x9f\xdf\x10V\x00\x00\xc0N\x9f\xdf\x10V\x00\x00
/usr/share/dbus-1/system-services\x00Found\x00A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
/lib/dbus-1/system-services\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00\x00H\x1c\x9f\xdf\x10V\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
/proc/interrupts\x00xen-dyn\x00MSI\x00CODE_LINE=328\x00CODE_FILE=procinterru
/proc/stat\x00CODE_LINE=441\x00CODE_LINE=448\x00CODE_LINE=497\x00\x00\x00\x00\x00WARNING

But as you can see that needs some output sanitizing.

Cool, thanks for looking into this. I’ll see if I can upgrade to a newer version of Debian.