From ec7fcc43d854265b7906b8179141b146cb604103 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 16 Jan 2017 18:17:04 +0100 Subject: [PATCH] rec: Let valgrind know that we are switching stacks Enabled via the `--enable-valgrind` configure switch. --- m4/pdns_enable_valgrind.m4 | 24 ++++++++++++++++++++ pdns/mtasker.cc | 7 ++++++ pdns/mtasker_context.hh | 3 +++ pdns/mtasker_fcontext.cc | 11 +++++++++ pdns/mtasker_ucontext.cc | 12 ++++++++++ pdns/recursordist/configure.ac | 1 + pdns/recursordist/m4/pdns_enable_valgrind.m4 | 1 + 7 files changed, 59 insertions(+) create mode 100644 m4/pdns_enable_valgrind.m4 create mode 120000 pdns/recursordist/m4/pdns_enable_valgrind.m4 diff --git a/m4/pdns_enable_valgrind.m4 b/m4/pdns_enable_valgrind.m4 new file mode 100644 index 0000000000..40313b7038 --- /dev/null +++ b/m4/pdns_enable_valgrind.m4 @@ -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.]) ], + ) +]) diff --git a/pdns/mtasker.cc b/pdns/mtasker.cc index 51c81e08b2..4ae49c6cc8 100644 --- a/pdns/mtasker.cc +++ b/pdns/mtasker.cc @@ -27,6 +27,9 @@ #include #include +#ifdef PDNS_USE_VALGRIND +#include +#endif /* PDNS_USE_VALGRIND */ /** \page MTasker Simple system for implementing cooperative multitasking of functions, with @@ -260,6 +263,10 @@ templatevoid MTasker::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; diff --git a/pdns/mtasker_context.hh b/pdns/mtasker_context.hh index fdfc2bbe9c..d0f82e14cd 100644 --- a/pdns/mtasker_context.hh +++ b/pdns/mtasker_context.hh @@ -37,6 +37,9 @@ struct pdns_ucontext_t { pdns_ucontext_t* uc_link; std::vector> uc_stack; std::exception_ptr exception; +#ifdef PDNS_USE_VALGRIND + int valgrind_id; +#endif /* PDNS_USE_VALGRIND */ }; void diff --git a/pdns/mtasker_fcontext.cc b/pdns/mtasker_fcontext.cc index 8d96fa168f..cc945c16ee 100644 --- a/pdns/mtasker_fcontext.cc +++ b/pdns/mtasker_fcontext.cc @@ -32,6 +32,9 @@ using boost::context::make_fcontext; using boost::context::detail::make_fcontext; #endif /* BOOST_VERSION < 106100 */ +#ifdef PDNS_USE_VALGRIND +#include +#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 diff --git a/pdns/mtasker_ucontext.cc b/pdns/mtasker_ucontext.cc index 080e5c6d55..ea7d2a4edf 100644 --- a/pdns/mtasker_ucontext.cc +++ b/pdns/mtasker_ucontext.cc @@ -27,6 +27,10 @@ #include #include +#ifdef PDNS_USE_VALGRIND +#include +#endif /* PDNS_USE_VALGRIND */ + template 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(uc_mcontext); +#ifdef PDNS_USE_VALGRIND + if (valgrind_id != 0) { + VALGRIND_STACK_DEREGISTER(valgrind_id); + } +#endif /* PDNS_USE_VALGRIND */ } void diff --git a/pdns/recursordist/configure.ac b/pdns/recursordist/configure.ac index fe5e625612..64b3af7e3c 100644 --- a/pdns/recursordist/configure.ac +++ b/pdns/recursordist/configure.ac @@ -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 index 0000000000..9f78a23dae --- /dev/null +++ b/pdns/recursordist/m4/pdns_enable_valgrind.m4 @@ -0,0 +1 @@ +../../../m4//pdns_enable_valgrind.m4 \ No newline at end of file -- 2.47.2