From 3482637ab5b81d77b7b37d752c1719cbeb626a51 Mon Sep 17 00:00:00 2001 From: Brendan Gregg Date: Fri, 13 Jan 2017 14:02:02 -0800 Subject: [PATCH] add some error hints --- src/cc/libbpf.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c index 4d34c6201b40..f0dd01befc35 100644 --- a/src/cc/libbpf.c +++ b/src/cc/libbpf.c @@ -137,6 +137,37 @@ int bpf_get_next_key(int fd, void *key, void *next_key) return syscall(__NR_bpf, BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr)); } +void bpf_print_hints(char *log) +{ + if (log == NULL) + return; + + // The following error strings will need maintenance to match LLVM. + + // stack busting + if (strstr(log, "invalid stack off=-") != NULL) { + fprintf(stderr, "HINT: Looks like you exceeded the BPF stack limit. " + "This can happen if you allocate too much local variable storage. " + "For example, if you allocated a 1 Kbyte struct (maybe for " + "BPF_PERF_OUTPUT), busting a max stack of 512 bytes.\n\n"); + } + + // didn't check NULL on map lookup + if (strstr(log, "invalid mem access 'map_value_or_null'") != NULL) { + fprintf(stderr, "HINT: The 'map_value_or_null' error can happen if " + "you dereference a pointer value from a map lookup without first " + "checking if that pointer is NULL.\n\n"); + } + + // lacking a bpf_probe_read + if (strstr(log, "invalid mem access 'inv'") != NULL) { + fprintf(stderr, "HINT: The invalid mem access 'inv' error can happen " + "if you try to dereference memory without first using " + "bpf_probe_read() to copy it to the BPF stack. Sometimes the " + "bpf_probe_read is automatic by the bcc rewriter, other times " + "you'll need to be explicit.\n\n"); + } +} #define ROUND_UP(x, n) (((x) + (n) - 1u) & ~((n) - 1u)) int bpf_prog_load(enum bpf_prog_type prog_type, @@ -221,6 +252,7 @@ int bpf_prog_load(enum bpf_prog_type prog_type, } fprintf(stderr, "bpf: %s\n%s\n", strerror(errno), bpf_log_buffer); + bpf_print_hints(bpf_log_buffer); free(bpf_log_buffer); }