iovisor / bcc

BCC - Tools for BPF-based Linux IO analysis, networking, monitoring, and more
Apache License 2.0
20.34k stars 3.86k forks source link

String literal cause failure to load with "unknown insn class" #1710

Open shartse opened 6 years ago

shartse commented 6 years ago

Discovered when trying to use to print a string literal:

from bcc import BPF
prog="""
#include <uapi/linux/ptrace.h>

int read_entry(struct pt_regs *ctx)
{
        bpf_trace_printk("name: %s", "a");
        return 0;
}
"""

b = BPF(text = prog)
b.attach_kprobe(event="vfs_read", fn_name="read_entry")

while (1):
    b.trace_print()

Fails with:

bpf: Failed to load program: Invalid argument
0: (b7) r1 = 115
1: (6b) *(u16 *)(r10 -4) = r1
2: (b7) r1 = 622869093
3: (63) *(u32 *)(r10 -8) = r1
4: (18) r1 = 0x6d616e206c6f6f70
6: (7b) *(u64 *)(r10 -16) = r1
7: (bf) r1 = r10
8: (07) r1 += -16
9: (b7) r2 = 14
10: (0e) BUG
unknown insn class 6

But replacing "a" with a char[] variable reference allows it to compile and print the value as expected:

char foo[] = "a";
bpf_trace_printk("name: %s\n", foo);
yonghong-song commented 6 years ago

The reason is the string "a" as in bpf_trace_printk("name: %s", "a") is put into the string table and the bpf program has a relocation record for it. This is not allowed. BPF program does not allow global variable yet.

In 4.17 kernel, I got

BPF_LDX uses reserved fields    

Actually, bcc can be improved to catch this. BCC can examine the relocation records and if it found anything there against the text, it should signal the error and goes out, does not even need to go to kernel.

ahrens commented 6 years ago

@yonghong-song we also saw the uses reserved fields error when the program was slightly different (on 4.15 kernel).

Great to hear that it's possible to improve the error message to make it easier to understand how to work around this. Perhaps we can leave this issue open as a request to improve the error message.

yonghong-song commented 6 years ago

Yes. Make sense. Let us leave it open until we do generate better error messages.