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]

[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)


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