Re: kprobe: __blkdev_put probe is missed

From: Steven Rostedt
Date: Fri Jun 19 2020 - 20:59:49 EST


On Sat, 20 Jun 2020 07:28:20 +0800
Ming Lei <ming.lei@xxxxxxxxxx> wrote:

> Thanks for your investigation.
>
> Some trace tools can just trace on function entry, such as bcc, and some
> user script always trace on function entry.
>
> I guess the issue should belong to kprobe implementation:

The issue is that kprobes is to dynamically add trace events into an
already compiled kernel. I'm guessing you would get the same result
from ftrace's function tracer. That's because the compiler has no idea
about what or where you intend to add these dynamically created trace
events (that's basically the point of kprobes). But if you add static
events (and this includes trace_printk()), the compiler knows about
them, because they exist at compile time, and will make sure they
execute the number of times the code shows it. But if you don't have
these events at compile time, the compiler is free to modify the code
in such a way it doesn't make sense if you add a probe at run time.

gdb suffers the same problem on user space debugging if you let the
compiler aggressively optimize the code. If you step through highly
optimized user space code with gdb, the position jumps all over the
place. This is basically the same effect.

>
> 1) __blkdev_put() is capable of being kprobed, so from user view, the
> probe on entry of __blkdev_put() should be triggered
>
> 2) from implementation view, I understand exception should be trapped
> on the entry of __blkdev_put(), looks it isn't done.

But it is done! But the compiler removed the second call and basically
just inlined it. So that entry no longer exists. When you added a
"trace_printk()" in there, the compiler is not allowed to skip that
trace call. But because there's nothing in here to tell the compiler
that it can't just remove the second call (which it did, and the kprobe
is just showing you what the compiler did!) then there's nothing
kprobes can do about it.

>
> Correct me if the above is wrong, and is it possible to fix it in kprobe?

No.

-- Steve