This is the mail archive of the gdb-patches@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]

Re: Move threads out of jumppad without single step


On 11/27/2015 10:54 AM, Yao Qi wrote:
> 
> Hi Pedro,
> Can we move threads out of jumppad without using single step?  I mean,
> supposing GDBserver can compute the next PCs of the instruction on which
> fast tracepoint is set, GDBserver can insert breakpoints at the next PCs
> of the instruction fast tracepoint is set on, and resume the thread
> which is in jumppad.
> 
> In the recent discussion about ARM fast tracepoint support, I pointed
> out that missing hardware single step may be a showstopper to ARM fast
> tracepoint support, but Simon wants to convince me that we can have a
> non-perfect fast tracepoint support on ARM with software single step.
> After I think about the possible issues of using software single step, I
> don't have any outcomes, but I wonder why do we need to single step
> thread out of jumppad?  Here is my understanding, in the jumppad, the
> instructions are like,
> 
>   saved registers
>   spin lock
>   call gdb_collect
>   spin unlock
>   restore registers
>   <----- [1]
>   relocated instructions
>   jump back
> 
> If PC is within the range above, GDBserver needs to move the thread
> out.  GDBserver can single step instructions one by one until PC is out
> of this range, but we have an optimization here that GDBserver can
> insert breakpoint and resume rather than single step one by one if PC
> doesn't point to the relocated instructions yet [1].  Afterwards,
> GDBserver will single step, but there aren't many instructions.  Unless
> I miss something, the code comments explain why do we move threads out
> of jumppad, but they do *not* explain why do we move threads out of
> jumppad in this way.  IMO, the reason is that instructions before [1]
> are sequentially executed (except call gdb_collect), but instructions
> after [1] may not.  We can safely insert breakpoint on [1], and thread
> must hit the breakpoint.  However, the original instruction on which the
> fast tracepoint is set may be a branch instruction, so the relocated
> instructions may jump back to the target address.

Correct.  But still, even if the relocated instruction does not jump back,
we need to execute the last "jump back" instruction then.

> At the moment we add
> fast tracepoint support (for x86), we rely on hardware single step so
> that we don't have to compute the next PCs (that is also the reason why
> qRelocInsn packet was added).
> 
> Now, the situation in GDBserver changed a little bit, as GDBserver will
> be able to accurately compute the next PCs.  Under this assumption,
> GDBserver can compute the next PCs of the original instruction, and set
> breakpoints there when threads are in jumppad.  In this way, we don't
> need to single step thread out jumppad at all for targets which support
> software single step in GDBserver.

I don't think we can determine the "next PCs" of the original instruction that
easily even with the new software single-step work.

E.g., if the instruction is an indirect branch, like "B r1", you need to
know the contents of register r1 to tell where the branch will take you.
But you can't compute offline what r1 will contain.

That's why the code that computes the next PCs (the gdbarch_software_single_step
implementations) assumes that the thread is currently stopped at the
instruction that we want to compute the next PCs for.

In the current arm_software_single_step implementation, you'll see the register
context also used to e.g., handle the conditions in conditional execution instructions,
based on state of registers and flags.

You may be able to handle this by retrieving state from the saved registers
buffer in the jump pad, similar to how gdb_collect cooks up a regcache, though
unlike gdb_collect, you'll have to handle the case of the thread stopping
midway through that register saving too (some registers already saved, some not
yet).

So I assume it's much simpler to just run to [1] as well, and then issue
a normal software single-step when you get there.

Also, not sure, but it's possible the stabilize threads machinery may
need work to handle the "wrong threads" hitting that "out of jump pad"
single-step breakpoint for another thread, and not have them start
a new start over, but instead have them be locked immediately.

Thanks,
Pedro Alves


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