Subject: ptrace informations
To: None <port-powerpc@netbsd.org>
From: Emmanuel Dreyfus <p99dreyf@criens.u-psud.fr>
List: port-powerpc
Date: 05/20/2001 21:51:32
Hello

I've debugged the ptrace() system call emulation enough to get Linux's
gdb running on NetBSD. I can run a program, set a breakpoint, but when
the traced program hits a breakpoint, it does not work yet: it gets a
SIGILL

In order to fix this, I would need some informations about the register
usages on the PowerPC.

Here is a trace, hellog has a breakpoint at main().


(hellog mmap's libc)
   931 hellog   CALL  close(0x5)
   931 hellog   RET   close 0
   931 hellog   CALL  getpid
   931 hellog   RET   getpid 931/0x3a3
   930 gdb      RET   rt_sigsuspend -1 errno 4 Interrupted system call
   930 gdb      PSIG  SIGCHLD caught handler=0x1004b2b0 mask=(20)
code=0x0
   930 gdb      CALL  sigreturn(0x7fffd970)
   930 gdb      RET   sigreturn JUSTRETURN
   930 gdb      CALL  wait4(0xffffffff,0x7fffdc9c,0x80000001,0)
   930 gdb      RET   wait4 -1 errno 10 No child processes
   930 gdb      CALL  wait4(0xffffffff,0x7fffdc9c,0x1,0)
   930 gdb      RET   wait4 931/0x3a3
   930 gdb      CALL  ptrace(PTRACE_PEEKUSER,0x3a3,0x80,0x7fffdabc)
   930 gdb      RET   ptrace 0
   930 gdb      CALL  rt_sigaction(0x16,0x7fffd948,0x7fffd9d8,0x8)
   930 gdb      RET   rt_sigaction 0
(some ioctl related to terminal handling)
   930 gdb      CALL  write(0x1,0x50374000,0x35)
   930 gdb      GIO   fd 1 wrote 53 bytes
       "Program received signal SIGILL, Illegal instruction.
       "
Here I assume that gdb got the process status using ptrace PEEKUSER
(this is PT_READ in NetBSD as far as I remember). At offset 0x80 is what
Linux calls nip, which I beleive to be pc (nip = Next Intruction
Pointer). I don't understand how gdb is able to find that a SIGILL
occured with this. Or does it get the information from another place? I
don't see any other system call that could give gdb the information.

Therefore I wonder if I don't have a problem here (mistranslation of the
offset 0x80?)

Then later, gdb tries to get the routine name using PEEKTEXT, but it
ends up with "0x0 in ?? ()", hence I think there must be another problem
here (except if the process trashed its stack). Here is the trace:

   930 gdb      RET   write 53/0x35
   930 gdb      CALL  ptrace(PTRACE_PEEKUSER,0x3a3,0x4,0x7fffdc3c)
   930 gdb      RET   ptrace 0
   930 gdb      CALL  ptrace(PTRACE_PEEKUSER,0x3a3,0x90,0x7fffdc0c)
   930 gdb      RET   ptrace 0
   930 gdb      CALL
ptrace(PTRACE_PEEKTEXT,0x3a3,0xfffffffc,0x7fffdc3c)
   930 gdb      RET   ptrace 0
   930 gdb      CALL  ptrace(PTRACE_PEEKTEXT,0x3a3,0,0x7fffdc3c)
   930 gdb      RET   ptrace -1 errno 22 Invalid argument
   930 gdb      CALL
ptrace(PTRACE_PEEKTEXT,0x3a3,0xfffffffc,0x7fffdc3c)
   930 gdb      RET   ptrace 0
   930 gdb      CALL  ptrace(PTRACE_PEEKTEXT,0x3a3,0,0x7fffdc3c)
   930 gdb      RET   ptrace -1 errno 22 Invalid argument
   930 gdb      CALL
ptrace(PTRACE_PEEKTEXT,0x3a3,0x1000043c,0x7fffdc34)
   930 gdb      RET   ptrace 2105675784/0x7d821008
   930 gdb      CALL
ptrace(PTRACE_PEEKTEXT,0x3a3,0xffffbca0,0x7fffdc34)
   930 gdb      RET   ptrace 0
   930 gdb      CALL  write(0x1,0x50374000,0xd)
   930 gdb      GIO   fd 1 wrote 13 bytes
       "0x0 in ?? ()

The first ptrace gets the value of GPR5. Why GPR5? For what is it
usually used? Then the second ptrace gets what linux calls the LINK
register (offical name?), and it starts digging in the process user
space. What is gdb doing exactly? Some hints would be useful (or at
least some URL of things to read)

-- 
Emmanuel Dreyfus
p99dreyf@criens.u-psud.fr