]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Let valgrind know that we are switching stacks 4916/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 16 Jan 2017 17:17:04 +0000 (18:17 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 17 Jan 2017 09:12:58 +0000 (10:12 +0100)
Enabled via the `--enable-valgrind` configure switch.

m4/pdns_enable_valgrind.m4 [new file with mode: 0644]
pdns/mtasker.cc
pdns/mtasker_context.hh
pdns/mtasker_fcontext.cc
pdns/mtasker_ucontext.cc
pdns/recursordist/configure.ac
pdns/recursordist/m4/pdns_enable_valgrind.m4 [new symlink]

diff --git a/m4/pdns_enable_valgrind.m4 b/m4/pdns_enable_valgrind.m4
new file mode 100644 (file)
index 0000000..40313b7
--- /dev/null
@@ -0,0 +1,24 @@
+AC_DEFUN([PDNS_ENABLE_VALGRIND],[
+  AC_MSG_CHECKING([whether to enable Valgrind support])
+  AC_ARG_ENABLE([valgrind],
+    AS_HELP_STRING([--enable-valgrind],[enable Valgrind support @<:@default=no@:>@]),
+    [enable_valgrind=$enableval],
+    [enable_valgrind=no],
+  )
+  AC_MSG_RESULT([$enable_valgrind])
+
+  AS_IF([test "x$enable_valgrind" != "xno"], [
+    AS_IF([test "x$enable_valgrind" = "xyes" -o "x$enable_valgrind" = "xauto"], [
+      AC_CHECK_HEADERS([valgrind/valgrind.h], valgrind_headers=yes, valgrind_headers=no)
+    ])
+  ])
+  AS_IF([test "x$enable_valgrind" = "xyes"], [
+    AS_IF([test x"$valgrind_headers" = "no"], [
+      AC_MSG_ERROR([Valgrind support requested but required Valgrind headers were not found])
+    ])
+  ])
+  AM_CONDITIONAL([PDNS_USE_VALGRIND], [test x"$valgrind_headers" = "xyes" ])
+  AS_IF([test x"$valgrind_headers" = "xyes" ],
+    [ AC_DEFINE([PDNS_USE_VALGRIND], [1], [Define if using Valgrind.]) ],
+  )
+])
index 51c81e08b2c8e211d12b53b31030f5d33fcd04cf..4ae49c6cc8e039c38f10f3cfcaddbfc7b9de1641 100644 (file)
@@ -27,6 +27,9 @@
 #include <stdio.h>
 #include <iostream>
 
+#ifdef PDNS_USE_VALGRIND
+#include <valgrind/valgrind.h>
+#endif /* PDNS_USE_VALGRIND */
 
 /** \page MTasker
     Simple system for implementing cooperative multitasking of functions, with 
@@ -260,6 +263,10 @@ template<class Key, class Val>void MTasker<Key,Val>::makeThread(tfunc_t *start,
   
   uc->uc_link = &d_kernel; // come back to kernel after dying
   uc->uc_stack.resize (d_stacksize);
+#ifdef PDNS_USE_VALGRIND
+  uc->valgrind_id = VALGRIND_STACK_REGISTER(&uc->uc_stack[0],
+                                            &uc->uc_stack[uc->uc_stack.size()]);
+#endif /* PDNS_USE_VALGRIND */
 
   auto& thread = d_threads[d_maxtid];
   auto mt = this;
index fdfc2bbe9c311e3b042b662fd0cd4d4e2604949f..d0f82e14cda277df7af169e551867af1ae1f3b06 100644 (file)
@@ -37,6 +37,9 @@ struct pdns_ucontext_t {
     pdns_ucontext_t* uc_link;
     std::vector<char, lazy_allocator<char>> uc_stack;
     std::exception_ptr exception;
+#ifdef PDNS_USE_VALGRIND
+    int valgrind_id;
+#endif /* PDNS_USE_VALGRIND */
 };
 
 void
index 8d96fa168f5d274d9d9484f40f6c806d5a7fb204..cc945c16ee86992f134a3c3643f416090c110bfd 100644 (file)
@@ -32,6 +32,9 @@ using boost::context::make_fcontext;
 using boost::context::detail::make_fcontext;
 #endif /* BOOST_VERSION < 106100 */
 
+#ifdef PDNS_USE_VALGRIND
+#include <valgrind/valgrind.h>
+#endif /* PDNS_USE_VALGRIND */
 
 #if BOOST_VERSION < 105600
 /* Note: This typedef means functions taking fcontext_t*, like jump_fcontext(),
@@ -153,6 +156,9 @@ threadWrapper (transfer_t const t) {
 
 pdns_ucontext_t::pdns_ucontext_t
 (): uc_mcontext(nullptr), uc_link(nullptr) {
+#ifdef PDNS_USE_VALGRIND
+  valgrind_id = 0;
+#endif /* PDNS_USE_VALGRIND */
 }
 
 pdns_ucontext_t::~pdns_ucontext_t
@@ -160,6 +166,11 @@ pdns_ucontext_t::~pdns_ucontext_t
     /* There's nothing to delete here since fcontext doesn't require anything
      * to be heap allocated.
      */
+#ifdef PDNS_USE_VALGRIND
+  if (valgrind_id != 0) {
+    VALGRIND_STACK_DEREGISTER(valgrind_id);
+  }
+#endif /* PDNS_USE_VALGRIND */
 }
 
 void
index 080e5c6d554e208c2bf4a7b4e7e372e9dc91e937..ea7d2a4edf3384e08f7f8bc98d06254d1e719842 100644 (file)
 #include <signal.h>
 #include <ucontext.h>
 
+#ifdef PDNS_USE_VALGRIND
+#include <valgrind/valgrind.h>
+#endif /* PDNS_USE_VALGRIND */
+
 template <typename Message> static __attribute__((noinline, cold, noreturn))
 void
 throw_errno (Message&& msg) {
@@ -84,10 +88,18 @@ threadWrapper (int const ctx0, int const ctx1, int const fun0, int const fun1) {
 pdns_ucontext_t::pdns_ucontext_t() {
     uc_mcontext = new ::ucontext_t();
     uc_link = nullptr;
+#ifdef PDNS_USE_VALGRIND
+    valgrind_id = 0;
+#endif /* PDNS_USE_VALGRIND */
 }
 
 pdns_ucontext_t::~pdns_ucontext_t() {
     delete static_cast<ucontext_t*>(uc_mcontext);
+#ifdef PDNS_USE_VALGRIND
+    if (valgrind_id != 0) {
+      VALGRIND_STACK_DEREGISTER(valgrind_id);
+    }
+#endif /* PDNS_USE_VALGRIND */
 }
 
 void
index fe5e6256121c6f0edd856ab27cbaee2d721299cb..64b3af7e3c2b6867ce70d687ef83fcd4da7e74d5 100644 (file)
@@ -144,6 +144,7 @@ AS_IF([test "x$enable_hardening" != "xno"], [
 
 PDNS_ENABLE_SANITIZERS
 PDNS_ENABLE_MALLOC_TRACE
+PDNS_ENABLE_VALGRIND
 AX_AVAILABLE_SYSTEMD
 AM_CONDITIONAL([HAVE_SYSTEMD], [ test x"$systemd" = "xy" ])
 PDNS_CHECK_PANDOC
diff --git a/pdns/recursordist/m4/pdns_enable_valgrind.m4 b/pdns/recursordist/m4/pdns_enable_valgrind.m4
new file mode 120000 (symlink)
index 0000000..9f78a23
--- /dev/null
@@ -0,0 +1 @@
+../../../m4//pdns_enable_valgrind.m4
\ No newline at end of file