[RFC] kprobes with thumb2 conditional code

Dave Martin dave.martin at linaro.org
Thu Mar 17 09:48:43 EDT 2011


On Fri, Mar 11, 2011 at 5:01 PM, Tixy <tixy at yxit.co.uk> wrote:
> Hello All
>
> I'm about to start work on getting kprobes working with thumb2.
>
> One of the issues I have is that when probes are placed onto
> conditionally executed instructions in a IT block, they may not fire if
> the condition is not met. This is because on ARM we use invalid
> instructions for breakpoints, and the ARM ARM says:
>
>  "it is IMPLEMENTATION DEFINED whether the instruction executes as a
>   NOP or causes an Undefined Instruction exception"
>
> This is a similar issue to that already encountered by GDB [1][2]
>
> If we take this code as an example...
>
> probe1:
> if(condition) {
> probe2:
>    some_code;
> }
>
> It seams reasonable at first sight that probe2 would only fire if the
> condition is true. This will always be the case if the compiler
> generates test-and-branch code, but if it generates conditionally
> executed instructions for 'some_code' then it gets complicated...
>
> The current arm kprobes implementation will always fire probe2 because

Well, actually it's somewhat unpredictable whether/when a probe on
probe2 will fire, because it depends on the code generated by the
compiler.  The compiler could choose to use a conditional instruction
at probe2, or it could conditionally branch round it, even in ARM.
Or, the whole conditional might disappear to be replaced with an
unconditional instruction sequence that has the same overall effect.

> it uses unconditional instructions for its breakpoints. With thumb
> instructions we can't force unconditional execution, so we would have an
> 'implementation defined' situation whether it would fire or not when the
> condition is false. (Thought you would hope it would be consistent on a
> particular device.)
>
> Some options for dealing with this, in increasing order of
> complexity...
>
> 1. Accept the situation as described.
>
> 2. Change arm probes to use conditional instructions so we would
> (hopefully) have consistent undefined behaviour in both arm and thumb
> code. (If that isn't an oxymoron :-)
>
> 3. Do 2, and modify kprobe_handler to test for false firings (breakpoint
> when condition false) and not execute the probe's callback functions in
> these cases. E.g. consistently make probe2 appear to not fire when
> condition is false.

My preference would be for option (1) or (3).  For (3), we could
choose to extend this behaviour to cover the existing ARM
implementation as well as Thumb, which could be a tidier and more
consistent approach.  This seems to be the "right" thing, since it
means kprobes never fire for real on instructions which are logically
not executed, no matter how the compiler (or human) implemented the
conditionality.  Currently, ARM kprobes can fire on instructions which
would fail their condition check, which might be considered wrong.

Alternatively, we could avoid fixing what isn't broken and leave the
ARM implementation unchanged.  Since the compiler will implement some
different instruction-level optimisations in Thumb compared with ARM,
it may not make sense to try to make the kprobe firing behaviour
behave exactly the same around conditional code in both instruction
sets -- because the code generation differences may always cause the
observed behaviour to be different anyway, just as might happen if you
switch to a newer compiler or use a different -march/-mtune
combination.

For the same reasons described above, I'd advise against the more
complex routes in (4).  The extra complexity probably doesn't bring
any useful consistency.


Has anyone made use of kprobes in a way where the precise firing
behaviour for conditional code would be important?

Cheers
---Dave

>
> 4. Make thumb probes fire unconditionally like current arm
> implementation...
>
> 4a. Use breakpoint instructions rather than undefined instructions for
> kprobes. Apparently this doesn't play nicely with hardware debuggers [2]
> though I don't have enough experience in this area to otherwise comment.
>
> 4b. Rewrite IT blocks when probes are inserted into them to make the
> breakpoint unconditional. This would require parsing backwards through
> the instruction stream to find the IT instruction, which I don't believe
> is possible with variable length thumb instructions. Or, another
> possibility which was suggested to me, use the unwind table to find the
> start of the containing function and parse forwards to find the IT
> instruction. Though the kernel doesn't currently have enough information
> to skip things like inline data that may be the function.
>
> The effort, complexity and bloat involved in 4b seems to be rather
> excessive to me, even before getting into the book-keeping required to
> handle multiple probes in the same IT block. So 4b is a bit of a straw
> man.
>
> BTW, does anyone know of any test code for kprobes, particularly with
> regard to checking emulation/single-stepping of the different CPU
> instructions?
>
> Thanks for any feedback
>
> --
> Tixy
>
>
> [1] http://permalink.gmane.org/gmane.comp.gdb.patches/54862
> [2]
> http://thread.gmane.org/gmane.linux.ports.arm.kernel/72199/focus=73489
>
>
>
> _______________________________________________
> linaro-dev mailing list
> linaro-dev at lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/linaro-dev
>



More information about the linux-arm-kernel mailing list