base: If valgrind is available, tell it about Fiber stacks.
authorGabe Black <gabeblack@google.com>
Wed, 22 Aug 2018 23:49:22 +0000 (16:49 -0700)
committerGabe Black <gabeblack@google.com>
Fri, 24 Aug 2018 18:15:09 +0000 (18:15 +0000)
Valgrind can get confused when  switching stacks between different
Fibers. If valgrind (and its headers) are available, this change adds
calls to some hooks so valgrind knows where the new stacks are and
doesn't report a bunch of false positives.

Change-Id: I00aefe60372be6de7371dec29427d7182dbee7b6
Reviewed-on: https://gem5-review.googlesource.com/12227
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Gabe Black <gabeblack@google.com>

SConstruct
src/base/fiber.cc
src/base/fiber.hh

index 5209aa6d447ea0eb95642c334dd25d99ef6e4003..79522e46f8a5d67b8e04bfc45075422e18bca006 100755 (executable)
@@ -783,6 +783,10 @@ main['HAVE_PROTOBUF'] = main['PROTOC'] and \
     conf.CheckLibWithHeader('protobuf', 'google/protobuf/message.h',
                             'C++', 'GOOGLE_PROTOBUF_VERIFY_VERSION;')
 
+# Valgrind gets much less confused if you tell it when you're using
+# alternative stacks.
+main['HAVE_VALGRIND'] = conf.CheckCHeader('valgrind/valgrind.h')
+
 # If we have the compiler but not the library, print another warning.
 if main['PROTOC'] and not main['HAVE_PROTOBUF']:
     print(termcap.Yellow + termcap.Bold +
@@ -1012,8 +1016,8 @@ sticky_vars.AddVariables(
 # These variables get exported to #defines in config/*.hh (see src/SConscript).
 export_vars += ['USE_FENV', 'SS_COMPATIBLE_FP', 'TARGET_ISA', 'TARGET_GPU_ISA',
                 'CP_ANNOTATE', 'USE_POSIX_CLOCK', 'USE_KVM', 'USE_TUNTAP',
-                'PROTOCOL', 'HAVE_PROTOBUF', 'HAVE_PERF_ATTR_EXCLUDE_HOST',
-                'USE_PNG']
+                'PROTOCOL', 'HAVE_PROTOBUF', 'HAVE_VALGRIND',
+                'HAVE_PERF_ATTR_EXCLUDE_HOST', 'USE_PNG']
 
 ###################################################
 #
index f10f1fbfddfba9e0acea1269ea78f5717433beb7..eac1d9394cfe9ec38a4403c1183e72bf712ce3c0 100644 (file)
 
 #include "base/fiber.hh"
 
+#if HAVE_VALGRIND
+#include <valgrind/valgrind.h>
+#endif
+
 #include <cerrno>
 #include <cstring>
 
@@ -71,7 +75,11 @@ Fiber::Fiber(size_t stack_size) :
     link(primaryFiber()),
     stack(stack_size ? new uint8_t[stack_size] : nullptr),
     stackSize(stack_size), started(false), _finished(false)
-{}
+{
+#if HAVE_VALGRIND
+    valgrindStackId = VALGRIND_STACK_REGISTER(stack, stack + stack_size);
+#endif
+}
 
 Fiber::Fiber(Fiber *link, size_t stack_size) :
     link(link), stack(stack_size ? new uint8_t[stack_size] : nullptr),
@@ -81,6 +89,9 @@ Fiber::Fiber(Fiber *link, size_t stack_size) :
 Fiber::~Fiber()
 {
     panic_if(stack && _currentFiber == this, "Fiber stack is in use.");
+#if HAVE_VALGRIND
+    VALGRIND_STACK_DEREGISTER(valgrindStackId);
+#endif
     delete [] stack;
 }
 
index 5f7285b297551de2c9c7222aa3547fcef82f2004..3d82075f0b6f24ad49f81f59dd02fc16eef80003 100644 (file)
@@ -44,6 +44,8 @@
 #include <cstddef>
 #include <cstdint>
 
+#include "config/have_valgrind.hh"
+
 /**
  * This class represents a fiber, which is a light weight sort of thread which
  * is cooperatively scheduled and runs sequentially with other fibers, swapping
@@ -106,6 +108,9 @@ class Fiber
     // The stack for this context, or a nullptr if allocated elsewhere.
     uint8_t *stack;
     size_t stackSize;
+#if HAVE_VALGRIND
+    unsigned valgrindStackId;
+#endif
 
     bool started;
     bool _finished;