Roland,
Thanks for the quick response. I am aware of some of the special instructions that need special care when single stepping on the PPC (but can't say I really understand the details).
Don't you think this is the sort of thing that utrace single-stepping should 
handle so that every utrace client doesn't have to figure this out? gdb 
identifies certain non-steppable instr sequences and does some flow analysis to 
set a bpt at the first steppable instr.

Or, perhaps this should be done in the kernel, arch/<arch>/kernel/traps.c.  In 
the arch=powerpc cash it looks like there is code there to emulate single stepping in 
certain scenarios.  Paul?

Thanks,
Dave


Roland McGrath wrote:
Yes, I see the problem too and have figured it out.  You were seeing only
the hits after system calls, and the first hit.  It's fixed by the
following patch.  I'm going to ask some ppc folks about this before
deciding for sure this is the right change.

With the fix, your test will go into an infinite loop.  That is "correct"
behavior, not any bug (but a known issue for single-stepping in general).
This is because some stdio functions use locking (even if the program is
not multithreaded), so there is a lwarx, stwcx., bne sequence.  A
single-step always breaks the lwarx+stwcx. sequence so it has to repeat.

This is a known issue for stepping atomic sequences on several kinds of
processor.  I have some thoughts relating to that, but it's not an issue
with any quick fixes.  If you want to discuss that, please do so on the
utrace-devel@redhat.com mailing list.


Thanks,
Roland


diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index d8502e3..0000000 100644 --- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -525,7 +525,8 @@ void RunModeException(struct pt_regs *re

 void __kprobes single_step_exception(struct pt_regs *regs)
 {
-       regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */
+       if (!test_thread_flag(TIF_SINGLESTEP))
+               regs->msr &= ~(MSR_SE | MSR_BE);  /* Turn off 'trace' bits */

        if (notify_die(DIE_SSTEP, "single_step", regs, 5,
                                        5, SIGTRAP) == NOTIFY_STOP)
@@ -545,7 +546,8 @@ void __kprobes single_step_exception(str
 static void emulate_single_step(struct pt_regs *regs)
 {
        if (single_stepping(regs)) {
-               clear_single_step(regs);
+               if (!test_thread_flag(TIF_SINGLESTEP))
+                       clear_single_step(regs);
                _exception(SIGTRAP, regs, TRAP_TRACE, 0);
        }
 }


--
Dave Nomura
LTC Linux Power Toolchain


Reply via email to