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.
Signed-off-by: Mark Wielaard
---
ChangeLog | 4 +++
configure.ac | 6 ++--
libdwfl/ChangeLog | 11 +++
libdwfl/libdwflP.h | 14 -
libdwfl/linux-pid-attach.c | 74 +-
5 files changed, 105 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 279c3b2b..81542414 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-03-17 Mark Wielaard
+
+ * configure.ac (CHECK_FUNCS): Check for process_vm_readv.
+
2018-02-09 Joshua Watt
* configure.ac (HAVE_FALLTHROUGH): New define.
diff --git a/configure.ac b/configure.ac
index 4cdb12af..ab32cbc8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
dnl Process this file with autoconf to produce a configure script.
dnl Configure input file for elfutils. -*-autoconf-*-
dnl
-dnl Copyright (C) 1996-2017 Red Hat, Inc.
+dnl Copyright (C) 1996-2018 Red Hat, Inc.
dnl
dnl This file is part of elfutils.
dnl
@@ -41,7 +41,7 @@ fi
AC_CONFIG_AUX_DIR([config])
AC_CONFIG_FILES([config/Makefile])
-AC_COPYRIGHT([Copyright (C) 1996-2017 The elfutils developers.])
+AC_COPYRIGHT([Copyright (C) 1996-2018 The elfutils developers.])
AC_PREREQ(2.63)dnl Minimum Autoconf version required.
dnl We use GNU make extensions; automake 1.10 defaults to -Wportability.
@@ -370,6 +370,8 @@ AC_CHECK_DECLS([mempcpy],[],[],
[#define _GNU_SOURCE
#include ])
+AC_CHECK_FUNCS([process_vm_readv])
+
AC_CHECK_LIB([stdc++], [__cxa_demangle], [dnl
AC_DEFINE([USE_DEMANGLE], [1], [Defined if demangling is enabled])])
AM_CONDITIONAL(DEMANGLE, test "x$ac_cv_lib_stdcpp___cxa_demangle" = "xyes")
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 1515c410..9776f1cb 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,14 @@
+2018-03-17 Mark Wielaard
+
+ * libdwflP.h (struct __libdwfl_remote_mem_cache): New.
+ (struct __libdwfl_pid_arg): Add mem_cache field.
+ * linux-pid-attach.c (read_cached_memory): New function.
+ (clear_cached_memory): Likewise.
+ (pid_memory_read): Call read_cached_memory.
+ (pid_detach): Free mem_cache.
+ (pid_thread_detach): Call clear_cached_memory.
+ (dwfl_linux_proc_attach): Initialize mem_cache to NULL.
+
2018-03-05 Mark Wielaard
* dwfl_build_id_find_elf.c (__libdwfl_open_by_build_id): Use
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index 7d5f795c..15ca0a11 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -1,5 +1,5 @@
/* Internal definitions for libdwfl.
- Copyright (C) 2005-2015 Red Hat, Inc.
+ Copyright (C) 2005-2015, 2018 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -401,6 +401,14 @@ struct dwfl_arange
size_t arange; /* Index in Dwarf_Aranges. */
};
+#define __LIBDWFL_REMOTE_MEM_CACHE_SIZE 4096
+/* Structure for caching remote memory reads as used by __libdwfl_pid_arg. */
+struct __libdwfl_remote_mem_cache
+{
+ Dwarf_Addr addr; /* Remote address. */
+ Dwarf_Off len; /* Zero if cleared, otherwise likely 4K. */
+ unsigned char buf[__LIBDWFL_REMOTE_MEM_CACHE_SIZE]; /* The actual cache. */
+};
/* Structure used for keeping track of ptrace attaching a thread.
Shared by linux-pid-attach and linux-proc-maps. If it has been setup
@@ -411,6 +419,10 @@ struct __libdwfl_pid_arg
DIR *dir;
/* Elf for /proc/PID/exe. Set to NULL if it couldn't be opened. */
Elf *elf;
+ /* Remote memory cache, NULL if there is no memory cached.
+ Should be cleared on detachment (because that makes the thread
+ runnable and the cache invalid). */
+ struct __libdwfl_remote_mem_cache *mem_cache;
/* fd for /proc/PID/exe. Set to -1 if it couldn't be opened. */
int elf_fd;
/* It is 0 if not used. */
diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c
index 2ab4109c..ea65618f 100644
--- a/libdwfl/linux-pid-attach.c
+++ b/libdwfl/linux-pid-attach.c
@@ -1,5 +1,5 @@
/* Get Dwarf Frame state for target live PID process.
- Copyright (C) 2013, 2014, 2015 Red Hat, Inc.
+ Copyright (C) 2013, 2014, 2015, 2018 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -34,6 +34,7 @@
#include "libdwflP.h"
#include
#include
+#include
#include
#include
#include
@@ -115,12 +116,80 @@ __libdwfl_ptrace_attach (pid_t tid, bool
*tid_was_stoppedp)
return true;
}
+#ifdef HAVE_PROCESS_VM_READV
+static bool
+read_cached_memory (struct __libdwfl_pid_arg