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]

[RFA] s/PIOD_WRITE_D/PIOD_WRITE_I in inf-ptrace.c


OpenBSD 3.9 (to be released in may 2006) will slightly change the way
reading and write the inferior's memory through ptrace(2) works.  In
particular, PT_WRITE_D (and PT_IO with PIOD_WRITE_D) will no longer
bypass the memory protections that are in place for the memory page
that's being accessed.  Since most of the code segments are mapped
read-only, this means that inserting breakpoints with
PT_WRITE_D/PIOD_WRITE_D will no longer work.  For the PT_WRITE_D case
this is no problem since GDB will try again with PT_WRITE_I, but for
the PIOD_WRITE_D case I didn't see the need to implement that when I
wrote the code.  I still do not see the need to try both PIOD_WRITE_D
*and* PIOD_WRITE_I, since PIOD_WRITE_I should always succeed (but read
on).

The motivation for the change in OpenBSD is very much related to an
issue we had when using gdb to debug a nasty X problem.  The new
malloc(3) in OpenBSD 3.8 is pretty aggressive in inserting "guard
pages" before and after allocated memory to catch buffer overflows.
The guard pages actually do exists in the page map but have read,
write and execute permission removed from them.  At one point we were
tracking a problem in X where some code in X was accessing memory
beyond the allocated area, i.e. in the guard page.  The program would
segfault upon accessing that guard page, but when running in gdb, it
would appear if nothing was wrong.  Examining the memory (using "x" or
"print") in gdb happily returned the contents of the guard page
because ptrace(2) was temporarily lifting the page protections.

I'm still thinking about what needs to be changed in gdb to make
things work properly.  Somehow we must differentiate between access to
I-space and access to D-space.  But at least OpenBSD now provides the
low-level support to do that.  Meanwhile, this patch will do as a
stopgap.

I feel very confident about making this change.  It's in a code
fragment that's only used for systems with the PT_IO request: FreeBSD,
NetBSD and OpenBSD.  I've looked at the kernel code that handles this
code on FreeBSD and NetBSD, and I've verified that it works on those
two platforms.  The only real reason I've made this an RFA is that
this might not be clear immediately, and this file is used on a lot of
systems.

I'd really like to see this change in GDB 6.4, because otherwise it
will not work at all on OpenBSD 3.9.  But since the release of OpenBSD
3.9 is still months ahead, having a GDB 6.4.1 with this issue fixed
would be fine for me too.


Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>

	* inf-ptrace.c (inf_ptrace_xfer_partial): Use PIOD_WRITE_I instead
	of PIOD_WRITE_D.

Index: inf-ptrace.c
===================================================================
RCS file: /cvs/src/src/gdb/inf-ptrace.c,v
retrieving revision 1.26
diff -u -p -r1.26 inf-ptrace.c
--- inf-ptrace.c 10 Sep 2005 18:11:02 -0000 1.26
+++ inf-ptrace.c 20 Nov 2005 12:24:10 -0000
@@ -462,8 +462,12 @@ inf_ptrace_xfer_partial (struct target_o
 	struct ptrace_io_desc piod;
 
 	/* NOTE: We assume that there are no distinct address spaces
-	   for instruction and data.  */
-	piod.piod_op = writebuf ? PIOD_WRITE_D : PIOD_READ_D;
+	   for instruction and data.  However, on OpenBSD 3.9 and
+	   later, PIOD_WRITE_D doesn't allow changing memory that's
+	   mapped read-only.  Since most code segments will be
+	   read-only, using PIOD_WRITE_D will prevent us from
+	   inserting breakpoints, so we use PIOD_WRITE_I instead.  */
+	piod.piod_op = writebuf ? PIOD_WRITE_I : PIOD_READ_D;
 	piod.piod_addr = writebuf ? (void *) writebuf : readbuf;
 	piod.piod_offs = (void *) (long) offset;
 	piod.piod_len = len;


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