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

[Bug gdb/19675] New: GDB doesn't set PC correctly with displaced stepping over clone syscall


https://sourceware.org/bugzilla/show_bug.cgi?id=19675

            Bug ID: 19675
           Summary: GDB doesn't set PC correctly with displaced stepping
                    over clone syscall
           Product: gdb
           Version: HEAD
            Status: NEW
          Severity: normal
          Priority: P2
         Component: gdb
          Assignee: unassigned at sourceware dot org
          Reporter: qiyao at gcc dot gnu.org
  Target Milestone: ---

When GDB displaced step a syscall instruction which creates new thread, such as
fork, vfork and clone, GDB needs to adjust the the PC of child.  GDB has
already done that for fork and vfork, see this snippet in infrun.c:

            /* GDB has got TARGET_WAITKIND_FORKED or TARGET_WAITKIND_VFORKED,
               indicating that the displaced stepping of syscall instruction
               has been done.  Perform cleanup for parent process here.  Note
               that this operation also cleans up the child process for vfork,
               because their pages are shared.  */

but it doesn't for clone, so the PC of child is set in scratch pad, which is
wrong.  See the reproducer below,

(gdb) b clone
Breakpoint 1 at 0x400490
(gdb) run
Starting program: /tmp/2.exe 

Breakpoint 1, 0x00007ffff7b0f410 in clone () from
/lib/x86_64-linux-gnu/libc.so.6
(gdb) disassemble 
Dump of assembler code for function clone:
=> 0x00007ffff7b0f410 <+0>:     mov    $0xffffffffffffffea,%rax
   0x00007ffff7b0f417 <+7>:     test   %rdi,%rdi
...
   0x00007ffff7b0f43a <+42>:    mov    $0x38,%eax
   0x00007ffff7b0f43f <+47>:    syscall      // the syscall call insn doing
clone
   0x00007ffff7b0f441 <+49>:    test   %rax,%rax
   0x00007ffff7b0f444 <+52>:    jl     0x7ffff7b0f485 <clone+117>
...
   0x00007ffff7b0f495 <+133>:   retq   
End of assembler dump.
(gdb) b *0x00007ffff7b0f43f
Breakpoint 2 at 0x7ffff7b0f43f
(gdb) c
Continuing.

Breakpoint 2, 0x00007ffff7b0f43f in clone () from
/lib/x86_64-linux-gnu/libc.so.6
(gdb) set displaced-stepping on
(gdb) si
[New LWP 13375]

Thread 2 received signal SIGSEGV, Segmentation fault.
[Switching to LWP 13375]
0x00000000004004e5 in _start ()
(gdb) info threads 
  Id   Target Id         Frame 
  1    LWP 13370 "2.exe" 0x00007ffff7b0f441 in clone () from
/lib/x86_64-linux-gnu/libc.so.6
* 2    LWP 13375         0x00000000004004e5 in _start ()

$ cat /tmp/2.c 
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>

static void
marker () {}

#define STACK_SIZE 0x1000

static int
clone_fn (void *unused)
{
  return 0;
}

int
main (void)
{
  int i, pid;
  unsigned char *stack;

  stack = malloc (STACK_SIZE);

  pid = clone (clone_fn, stack + STACK_SIZE, CLONE_FILES | CLONE_VM,
               NULL);

  free (stack);
  marker ();
}
-------------------------------

-- 
You are receiving this mail because:
You are on the CC list for the bug.

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