Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add some error hints #904

Merged
merged 1 commit into from
Jan 13, 2017
Merged

add some error hints #904

merged 1 commit into from
Jan 13, 2017

Conversation

brendangregg
Copy link
Member

Beginners are hitting these errors, so I tried adding some hints to the output. What do we think? More hints can be added (there's also the list in Documentation/networking/filter.txt).

Eg, sample output:

[...]
61: (7b) *(u64 *)(r10 -480) = r1
62: (7b) *(u64 *)(r10 -488) = r1
63: (7b) *(u64 *)(r10 -496) = r1
64: (7b) *(u64 *)(r10 -504) = r1
65: (7b) *(u64 *)(r10 -512) = r1
66: (7b) *(u64 *)(r10 -520) = r1
invalid stack off=-520 size=8

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.

Traceback (most recent call last):
  File "./bashreadline-stack.py", line 52, in <module>
    b.attach_uretprobe(name="/bin/bash", sym="readline", fn_name="printret")
  File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 812, in attach_uretprobe
    fn = self.load_func(fn_name, BPF.KPROBE)
  File "/usr/lib/python2.7/dist-packages/bcc/__init__.py", line 290, in load_func
    raise Exception("Failed to load BPF program %s: %s" % (func_name, errstr))
Exception: Failed to load BPF program printret: Permission denied

@4ast
Copy link
Member

4ast commented Jan 13, 2017

awesome. we were thinking to add such hints to kernel verifier directly and to llvm.

@4ast 4ast merged commit 23e0de7 into iovisor:master Jan 13, 2017
@brendangregg
Copy link
Member Author

Thanks. We can keep an eye out for common beginner errors and keep adding hints.

What was the way to get the kernel verifier errors again? Should they be in dmesg if I set something?

@brendangregg
Copy link
Member Author

brendangregg commented Jan 13, 2017

Oh, and the bpf_log_buffer I'm parsing misses some errors, like:

LLVM ERROR: Cannot select: 0x152c068: ch,glue = BPFISD::CALL 0x152b3d0, 0x152be18 [ORD=3] [ID=10]
  0x152be18: i64 = TargetExternalSymbol'abort' [ID=4]
In function: printret

Happened when trying to dereference an local pointer to an unallocated struct. Maybe there's another place I can catch it in bcc, if not, then we might need hints in LLVM too.

@4ast
Copy link
Member

4ast commented Jan 14, 2017

bpf_log_buffer is what verifier returns. It's verification log plus all errors.
llvm prints come from stderr. Unless we're doing fd redirect. need to check...

@4ast
Copy link
Member

4ast commented Jan 17, 2017

@brendangregg
pushed the first error detector into llvm backend.
It will no longer generate output that will for sure be rejected by the verifier due to stack size:
$ ./bin/clang -O2 -target bpf warn_stack.c -c -o a.o
warn_stack.c:7:6: error: Looks like the BPF stack limit of 512 bytes is exceeded. Please move large on stack variables into BPF per-cpu array map.
void warn(void)
^
1 error generated.

Planing to add more warnings/errors.
so far I'm thinking of the following list:

  • call to non-helper
  • loop is present
  • inline asm is present
    other ideas?

@4ast
Copy link
Member

4ast commented Jan 17, 2017

pushed few more errors:

$ ./bin/clang -O2 -g -target bpf warn_call.c -S -o a.o
warn_call.c:6:2: error: A call to built-in function 'memcpy' is not supported.
        memcpy(dst, src, len);
        ^
warn_call.c:7:2: error: A call to global function 'foo' is not supported. Only calls to predefined BPF helpers are allowed.
        foo(dst, src, len);
        ^
warn_call.c:8:9: error: A call to global function 'bar' is not supported. Please use __attribute__((always_inline) to make sure this function is inlined.
        return bar(dst, src, len);

pls give it a try and suggest wording improvements.

@qmonnet
Copy link
Contributor

qmonnet commented Jan 18, 2017

Hi all, @4ast, hints in bcc / llvm (/ verifier, hopefully) look great and really helpful, thanks!

I'm being curious here about the errors produced by llvm backend. Will there be a pragma or another way to opt out? I'm thinking about BPF virtual machines other than the one in the kernel. As far as I remember, uBPF has its own stack size for example (which is in fact lower: 128 bytes, but it could as well be set to more than 512 instead), or allows for up to 2^16 instructions. If I ever wish to use different parameters from the ones of the kernel, will I still be able to compile my program from C code?

@4ast
Copy link
Member

4ast commented Jan 19, 2017

it shouldn't be too difficult to add backend flags and relax these checks.
I actually thought about reusing existing -warn-stack-size llc flag, but it cannot be set from the backend and it's only a warning, hence I went with bpf backend specific errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants