This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[commit] Fix gdbserver on x86_64/NPTL
- From: Daniel Jacobowitz <drow at false dot org>
- To: gdb-patches at sourceware dot org
- Date: Wed, 15 Feb 2006 09:41:14 -0500
- Subject: [commit] Fix gdbserver on x86_64/NPTL
This patch causes us to use PTRACE_GETREGS on a target register set,
then fill it from gdbserver's register cache, and then pass it to
PTRACE_SETREGS. GDB has to do this because it may only store cached
registers and in theory it's possible for not all general registers
to be cached; gdbserver formerly did not need to because it always
fetched all registers eagerly.
Except that, matching the GDB remote interface, gdbserver knows about fs and
gs but not about fs_base and gs_base. So they were being filled with
garbage values. So the next time someone tried to read a thread-relative
errno, they got some most distressing results.
Tested on x86_64-pc-linux-gnu, where my test results go from horrifying
to merely depressing:
# of expected passes 10160
# of unexpected failures 358
# of expected failures 44
# of known failures 36
# of unresolved testcases 16
Particular bad guys are checkpoint.exp, fileio.exp, multi-forks.exp,
sigstep.exp, tls.exp. tls.exp needs a gdbserver implementation of
qGetTLSAddr, I don't know what's wrong with sigstep.exp, and the other three
should probably be turned off for gdbserver...
--
Daniel Jacobowitz
CodeSourcery
2006-02-15 Daniel Jacobowitz <dan@codesourcery.com>
* linux-low.c (regsets_store_inferior_registers): Read the regset
from the target before filling it.
Index: gdbserver/linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.42
diff -u -p -r1.42 linux-low.c
--- gdbserver/linux-low.c 23 Dec 2005 18:11:55 -0000 1.42
+++ gdbserver/linux-low.c 15 Feb 2006 14:35:37 -0000
@@ -1,5 +1,6 @@
/* Low level interface to ptrace, for the remote server for GDB.
- Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ 2006
Free Software Foundation, Inc.
This file is part of GDB.
@@ -1286,8 +1287,21 @@ regsets_store_inferior_registers ()
}
buf = malloc (regset->size);
- regset->fill_function (buf);
- res = ptrace (regset->set_request, inferior_pid, 0, buf);
+
+ /* First fill the buffer with the current register set contents,
+ in case there are any items in the kernel's regset that are
+ not in gdbserver's regcache. */
+ res = ptrace (regset->get_request, inferior_pid, 0, buf);
+
+ if (res == 0)
+ {
+ /* Then overlay our cached registers on that. */
+ regset->fill_function (buf);
+
+ /* Only now do we write the register set. */
+ res = ptrace (regset->set_request, inferior_pid, 0, buf);
+ }
+
if (res < 0)
{
if (errno == EIO)