[PATCH] libdwfl: Use process_vm_readv when available.

Mark Wielaard mark@klomp.org
Tue Mar 20 22:32:00 GMT 2018


On Sun, Mar 18, 2018 at 01:43:23AM +0100, Mark Wielaard wrote:
> If possible use process_vm_readv to read 4K blocks instead of fetching
> each word individually with ptrace. For unwinding this often means we
> only have to do one process_vm_readv of the stack instead of dozens of
> ptrace calls. There is one 4K cache per process, cleared whenever a
> thread is detached.

It seems to work well, but the GCC undefined sanitizer
(configure --enable-sanitize-undefined) found an issue in the
run-backtrace-native-biarch.sh testcase (from x86_64 to i686)
when reading unaligned data. To fix that don't assign to the
Dwarf_Word directly when unaligned, but use memcpy (which gcc
seems to inline).

diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c
index ea65618f..6295e391 100644
--- a/libdwfl/linux-pid-attach.c
+++ b/libdwfl/linux-pid-attach.c
@@ -144,7 +144,10 @@ read_cached_memory (struct __libdwfl_pid_arg *pid_arg,
   if (addr >= mem_cache->addr && addr - mem_cache->addr < mem_cache->len)
     {
       d = &mem_cache->buf[addr - mem_cache->addr];
-      *result = *(unsigned long *) d;
+      if ((((uintptr_t) d) & (sizeof (unsigned long) - 1)) == 0)
+	*result = *(unsigned long *) d;
+      else
+	memcpy (result, d, sizeof (unsigned long));
       return true;
     }

@@ -165,7 +168,10 @@ read_cached_memory (struct __libdwfl_pid_arg *pid_arg,

   mem_cache->len = res;
   d = &mem_cache->buf[addr - mem_cache->addr];
-  *result = *((unsigned long *) d);
+  if ((((uintptr_t) d) & (sizeof (unsigned long) - 1)) == 0)
+    *result = *(unsigned long *) d;
+  else
+    memcpy (result, d, sizeof (unsigned long));
   return true;
 }
 #endif /* HAVE_PROCESS_VM_READV */



More information about the Elfutils-devel mailing list