Robustify gdbserver's linux_write_memory a bit

Pedro Alves pedro@codesourcery.com
Sun Mar 14 19:45:00 GMT 2010


When working on (fast) tracepoints support in gdbserver a few months
ago, I found myself debugging a rather weird and racy scenario,
where gdbserver managed to (almost silently) fail to reinsert a fast
tracepoint (after stepping over it), but while doing so, clobbered
half the memory it was writing to with garbage.  This resulted
in some mistifying inferior crashes.  The reason gdbserver wrote
garbage in the inferior, was that peeking memory to build the
word aligned buffer was silently failing on the low end, leaving
garbage in the buffer, but writing the buffer back to memory
was suceeding.  I eventually fixed the problem somewhere else,
but, it would have saved me time if we didn't just ignore the
fact that peeking memory was failing in the first place.
Hence this patch.  Tested on x86-64-linux gdbserver, and
applied to mainline.

-- 
Pedro Alves

2010-03-14  Pedro Alves  <pedro@codesourcery.com>

	gdb/gdbserver/
	* linux-low.c (linux_write_memory): Bail out early if peeking
	memory failed.

---
 gdb/gdbserver/linux-low.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

Index: src/gdb/gdbserver/linux-low.c
===================================================================
--- src.orig/gdb/gdbserver/linux-low.c	2010-03-14 19:12:54.000000000 +0000
+++ src/gdb/gdbserver/linux-low.c	2010-03-14 19:28:29.000000000 +0000
@@ -2556,9 +2556,8 @@ linux_read_memory (CORE_ADDR memaddr, un
   return 0;
 }
 
-/* Copy LEN bytes of data from debugger memory at MYADDR
-   to inferior's memory at MEMADDR.
-   On failure (cannot write the inferior)
+/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
+   memory at MEMADDR.  On failure (cannot write to the inferior)
    returns the value of errno.  */
 
 static int
@@ -2590,13 +2589,17 @@ linux_write_memory (CORE_ADDR memaddr, c
 
   /* Fill start and end extra bytes of buffer with existing memory data.  */
 
+  errno = 0;
   /* Coerce the 3rd arg to a uintptr_t first to avoid potential gcc warning
      about coercing an 8 byte integer to a 4 byte pointer.  */
   buffer[0] = ptrace (PTRACE_PEEKTEXT, pid,
 		      (PTRACE_ARG3_TYPE) (uintptr_t) addr, 0);
+  if (errno)
+    return errno;
 
   if (count > 1)
     {
+      errno = 0;
       buffer[count - 1]
 	= ptrace (PTRACE_PEEKTEXT, pid,
 		  /* Coerce to a uintptr_t first to avoid potential gcc warning
@@ -2604,9 +2607,11 @@ linux_write_memory (CORE_ADDR memaddr, c
 		  (PTRACE_ARG3_TYPE) (uintptr_t) (addr + (count - 1)
 						  * sizeof (PTRACE_XFER_TYPE)),
 		  0);
+      if (errno)
+	return errno;
     }
 
-  /* Copy data to be written over corresponding part of buffer */
+  /* Copy data to be written over corresponding part of buffer.  */
 
   memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len);
 



More information about the Gdb-patches mailing list