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: [PATCH] Get frame after pull single-step breakpoints out


On 04/10/2014 04:46 AM, Yao Qi wrote:
> This patch fixes the fails I saw on nios2-linux testing.  Thanks.

Thanks, pushed:
https://sourceware.org/ml/gdb-patches/2014-04/msg00176.html

> 
> On 04/04/2014 08:49 PM, Pedro Alves wrote:
>> This is actually one thing that my v1 of the recent
>> "fix a bunch of run control bugs" series was fixing, because
>> it made sss breakpoints be regular breakpoints in the breakpoint
>> chain.  But I had to drop that in v2.
>>
>> For all kinds of breakpoints breakpoint_xfer_memory hides the
>> breakpoint instructions, but sss breakpoints aren't tracked like all
>> other breakpoints.
>>
>> So instead of making sss breakpoints regular breakpoints, go with
>> a simpler fix (at least for now) -- make breakpoint_xfer_memory
>> take software single-step breakpoints into account.  Something
>> like the patch below.  After the patch, I get the correct
>> disassemble output.
> 
> This will be complicated when we need per-thread software single step
> breakpoint.  

Hmm, what's the "this" you're referring to?  Either the single step
breakpoints remain separate from regular breakpoints, and breakpoint_xfer_memory
will iterate over sss breakpoints of all threads, or sss breakpoints
become regular breakpoints in the breakpoint location chain,
and breakpoint_xfer_memory doesn't need to care about them at all.

> IIRC, 'run all-stop mode on top of non-stop target' needs
> it.

Right, currently non-stop forces displaced stepping on software
single-step targets.

> The problem is sss breakpoint is there when frame unwinder sniffer
> reads memory.  

Well, that's _one_ manifestation of the issue.  The "disassemble"
one I've shown is another.  I've previously said that we may not
be able to trigger it today, but actually we can.  Native GNU/Linux
gdb can't read memory off a running thread, but I had forgotten
multi-threading and scheduler-locking.  With scheduler-locking
on, we can switch to a stopped thread, and disassemble the code
that is being stepped over.

E.g., setting one thread stepping over this inf loop in the
background:

void *thread_function0(void *arg) {

    while (1);

Like so:

(gdb) info threads
  Id   Target Id         Frame
  3    Thread 0x7ffff77ca700 (LWP 2644) "threads_inf_ste" 0x000000323d4ba6ed in nanosleep () at ../sysdeps/unix/syscall-template.S:82
  2    Thread 0x7ffff7fcb700 (LWP 2643) "threads_inf_ste" thread_function0 (arg=0x0) at threads_inf_step.c:60
* 1    Thread 0x7ffff7fcc740 (LWP 2639) "threads_inf_ste" 0x00000034cf408e60 in pthread_join (threadid=140737353922304, thread_return=0x7fffffffd9e8) at pthread_join.c:93
(gdb) t 2
[Switching to thread 2 (Thread 0x7ffff7fcb700 (LWP 2643))]
#0  thread_function0 (arg=0x0) at threads_inf_step.c:60
60          while (1);
(gdb) set scheduler-locking on
(gdb) s&

Now switch to a stopped thread:

(gdb) t 1
[Switching to thread 1 (Thread 0x7ffff7fcc740 (LWP 2639))]
#0  0x00000034cf408e60 in pthread_join (threadid=140737353922304, thread_return=0x7fffffffd9e8) at pthread_join.c:93
93          lll_wait_tid (pd->tid);

And disassemble the function thread 2 is running:

(gdb) disassemble thread_function0
Dump of assembler code for function thread_function0:
   0x0000000000400791 <+0>:     push   %rbp
   0x0000000000400792 <+1>:     mov    %rsp,%rbp
   0x0000000000400795 <+4>:     push   %rbx
   0x0000000000400796 <+5>:     mov    %rdi,-0x20(%rbp)
   0x000000000040079a <+9>:     mov    -0x20(%rbp),%rax
   0x000000000040079e <+13>:    mov    %eax,%ebx
   0x00000000004007a0 <+15>:    movslq %ebx,%rax
   0x00000000004007a3 <+18>:    shl    $0x2,%rax
   0x00000000004007a7 <+22>:    add    $0x600c70,%rax
   0x00000000004007ad <+28>:    mov    %rax,-0x10(%rbp)
   0x00000000004007b1 <+32>:    int3
   0x00000000004007b2 <+33>:    (bad)
End of assembler dump.

Notice "int3", and "(bad)".

So we should actually be able to turn this into a test case.
(one that disassembles the function before the step, and
compares that to the disassembly while the step is ongoing.)

And we may well have other manifestations of the same issue.
The root cause is that all breakpoints should be transparent to memory
reads, but these weren't because they use the
deprecated_insert_raw_breakpoint mechanism, _and_ nios2 gdbserver
doesn't support Z0 breakpoints.  With Z0 breakpoints, gdbserver
takes care of hiding the sss breakpoints from memory reads, because
from gdbserver's perspective, it's just another breakpoint.

> Your fix is to make sss breakpoint invisible, while mine
> is pull sss breakpoint out before sniffer reads memory.  I can't see
> anything wrong with my patch.  It is simple, and are you OK to consider
> it?

But after we fix the root issue, that change just looks pointless
to me?

-- 
Pedro Alves


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