Add Valgrind stack instrumentation

Our coroutine system can make debugging memory issues harder by not
following a standard stack allocation system.  We can get around this by
using valgrind's built-in stack instrumentation.  Each coroutine
registers a stack allocation allowing memcheck to recognize when
accesses are bounded.
This commit is contained in:
Seth Hillbrand 2019-08-10 08:26:23 -07:00
parent c836cc9cf8
commit 0b80c00678
2 changed files with 28 additions and 2 deletions

View File

@ -125,6 +125,10 @@ option( KICAD_BUILD_PARALLEL_CL_MP
"Build in parallel using the /MP compiler option (default OFF for safety reasons)"
OFF )
option( KICAD_USE_VALGRIND
"Build KiCad with valgrind stack tracking enabled."
OFF )
# when option KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES is enabled:
# PYTHON_EXECUTABLE can be defined when invoking cmake
# ( use -DPYTHON_EXECUTABLE=<python path>/python.exe or python2 )
@ -161,6 +165,10 @@ set( CMAKE_POSITION_INDEPENDENT_CODE ON )
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Enable additional valgrind instrumentation for stack tracking in libcontext
if( KICAD_USE_VALGRIND )
add_definitions( -DKICAD_USE_VALGRIND )
endif()
# CMP0063: CMake < 3.3 does not handle hidden visibility for static libraries,
# and 3.3 is backwards compatible when the minimum version is smaller than 3.3.

View File

@ -31,6 +31,10 @@
#include <type_traits>
#ifdef KICAD_USE_VALGRIND
#include <valgrind/valgrind.h>
#endif
#include <system/libcontext.h>
#include <memory>
@ -65,8 +69,8 @@ private:
{
enum
{
FROM_ROOT, // a stub was called/a corutine was resumed from the main-stack context
FROM_ROUTINE, // a stub was called/a coroutine was resumed fron a coroutine context
FROM_ROOT, // a stub was called/a coroutine was resumed from the main-stack context
FROM_ROUTINE, // a stub was called/a coroutine was resumed from a coroutine context
CONTINUE_AFTER_ROOT // a function sent a request to invoke a function on the main
// stack context
} type; // invocation type
@ -140,11 +144,17 @@ public:
m_callContext( nullptr ),
m_callee( nullptr ),
m_retVal( 0 )
#ifdef KICAD_USE_VALGRIND
,valgrind_stack( 0 )
#endif
{
}
~COROUTINE()
{
#ifdef KICAD_USE_VALGRIND
VALGRIND_STACK_DEREGISTER( valgrind_stack );
#endif
}
public:
@ -306,6 +316,10 @@ private:
// correct the stack size
stackSize -= size_t( ( (ptrdiff_t) m_stack.get() + stackSize ) - (ptrdiff_t) sp );
#ifdef KICAD_USE_VALGRIND
valgrind_stack = VALGRIND_STACK_REGISTER( sp, m_stack.get() );
#endif
#endif
m_callee = libcontext::make_fcontext( sp, stackSize, callerStub );
@ -389,6 +403,10 @@ private:
CALLEE_STORAGE m_callee;
ReturnType m_retVal;
#ifdef KICAD_USE_VALGRIND
uint32_t valgrind_stack;
#endif
};
#endif