This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Instrcutions that must not be stepped.


On the PowerPC, there is a provision for an atomic read-modify-right
sequence that is implemented using the "lwarx" and "stwcx" instructions.
These do not guarantee an atomic operation, but will detect its failure.
If threads are being used, then glibc functions use this sequence to
implement a lock by looping back to the start of the sequence if it was
not atomic.

When gdb is stepping through a library function, which it does under
some circumstances if there is no source for the function, it gets stuck
in this loop because the sequence will never be recognized as atomic.

The only solution is to check each instruction about to be stepped to
see if it's an "lwarx".  If not, step as usual.  If it is, then analyze
the instructions that follow; set a temporary breakpoint after the loop,
do a 'continue' and then continue stepping normally after it's been hit.

Does there currently exist an arch. independent way to detect
instruction sequences that must not be single stepped?  Failing that, is
there some hook I can use to implement this for just the PowerPC?

Should there be a new gdbarch member like 'single_step_nonstepable' that
will detect and handle non-stepable sequences?.  Or maybe a gdbarch
member like 'find_end_of_nonstepable_sequence' that returns 0 if the
instruction about be be stepped is not the the start of a non-stepable
sequence and the address of the end of the sequence (where to set a
temp. break) if it is.

Thanks for your help,

-=# Paul #=-

PS: The following hack prevents single-stepping a "lwarx" instruction.
The user can then manually find the end of the sequence, put a temp.
break there, continue, and then go back to stepping as normal.  Before
you get upset, remember I did say it was a hack and it actually allowed
a teammate to make progress on an unrelated glibc bug.

--- inf-ptrace.c        2006-01-24 14:34:34.000000000 -0800
+++ new.inf-ptrace.c    2006-06-07 13:59:02.000000000 -0700
@@ -326,6 +326,14 @@
   if (step)
     {
+      /* Horrible hack:  See if we are about to step an "lwarx"
+         instruction and abort with an error message if so. */
+      long pc = (long) read_register (PC_REGNUM);
+      long inst = ptrace (PT_READ_I, pid, pc, 0);
+
+      if ((inst & 0xfc0007fe) == 0x7C000028)
+         perror_with_name (("(barf) lwarx (barf)"));
+
       /* If this system does not support PT_STEP, a higher level
          function will have called single_step() to transmute the step
          request into a continue request (by setting breakpoints on


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]