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]

Avoid mprotect in the IPA


I see the all the fast tracepoints tests failing on my (basically default) install
of Fedora 16.  The symptom for all of them is:

 FAIL: gdb.trace/change-loc.exp: 1 ftrace: Can't run to main
 spawn /home/pedro/gdb/mygit/build-nonative/gdb/testsuite/../../gdb/gdb -nw -nx -data-directory /home/pedro/gdb/mygit/build-nonative/gdb/testsuite/../data-directory
 ipa: initialize_tracepoint: mprotect(0x602000, 81920, PROT_READ|PROT_EXEC) failed with Permission denied

(The fatal message is wrong, it is actually PROT_READ|PROT_WRITE|PROT_EXEC)

We are trying to give some pages execution permissions, which isn't
allowed by default for security reasons.  Mapping the memory as executable
with mmap to begin with instead works, with a twist.  Unlike for memalign,
if we let it choose, the kernel likes to mmap memory at high addresses, which
is way too far from the executable for fast tracepoint jumps to work on x86_64,
so we need to look for low addresses with MAP_FIXED.

Tested on x86_64 / fedora 16, with local gdbserver, and checked in.

-- 
Pedro Alves

2012-01-17  Pedro Alves  <palves@redhat.com>

	* tracepoint.c (initialize_tracepoint): Use mmap instead of
	memalign plus mprotect to allocate the scratch buffer.
---
 gdb/gdbserver/tracepoint.c |   28 ++++++++++++++++++++--------
 1 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 3e6dac0..3dc0073 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -8251,23 +8251,35 @@ initialize_tracepoint (void)

 #ifdef IN_PROCESS_AGENT
   {
+    uintptr_t addr;
     int pagesize;
+
     pagesize = sysconf (_SC_PAGE_SIZE);
     if (pagesize == -1)
       fatal ("sysconf");

     gdb_tp_heap_buffer = xmalloc (5 * 1024 * 1024);

-    /* Allocate scratch buffer aligned on a page boundary.  */
-    gdb_jump_pad_buffer = memalign (pagesize, pagesize * 20);
-    gdb_jump_pad_buffer_end = gdb_jump_pad_buffer + pagesize * 20;
+#define SCRATCH_BUFFER_NPAGES 20
+
+    /* Allocate scratch buffer aligned on a page boundary, at a low
+       address (close to the main executable's code).  */
+    for (addr = pagesize; addr != 0; addr += pagesize)
+      {
+	gdb_jump_pad_buffer = mmap ((void *) addr, pagesize * SCRATCH_BUFFER_NPAGES,
+				    PROT_READ | PROT_WRITE | PROT_EXEC,
+				    MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
+				    -1, 0);
+	if (gdb_jump_pad_buffer != MAP_FAILED)
+	  break;
+      }

-    /* Make it writable and executable.  */
-    if (mprotect (gdb_jump_pad_buffer, pagesize * 20,
-		  PROT_READ | PROT_WRITE | PROT_EXEC) != 0)
+    if (addr == 0)
       fatal ("\
-initialize_tracepoint: mprotect(%p, %d, PROT_READ|PROT_EXEC) failed with %s",
-	     gdb_jump_pad_buffer, pagesize * 20, strerror (errno));
+initialize_tracepoint: mmap'ing jump pad buffer failed with %s",
+	     strerror (errno));
+
+    gdb_jump_pad_buffer_end = gdb_jump_pad_buffer + pagesize * SCRATCH_BUFFER_NPAGES;
   }

   gdb_trampoline_buffer = gdb_trampoline_buffer_end = 0;


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