Add memory checker support in CMake

If ENABLE_TESTING is ON, you can now use memory checking tools to run the test
suite and check for memory leaks. By default CMake will try to find valgrind in
your path and set some default options.

To customize this behavior use the MEMORYCHECK_COMMAND and
MEMORYCHECK_COMMAND_OPTIONS variables. To run tests with the memory checker,
use the MemCheck action in ctest:

Run entire test suite:

ctest -T MemCheck

Run single test:

ctest -T MemCheck -R TESTNAME

Run test in verbose mode:

ctest -V -T MemCheck -R TESTNAME
This commit is contained in:
Richard Berger
2020-06-23 13:23:11 -04:00
parent 5d1d406e01
commit 8cec13a038
4 changed files with 397 additions and 0 deletions

View File

@ -3,6 +3,26 @@
###############################################################################
option(ENABLE_TESTING "Enable testing" OFF)
if(ENABLE_TESTING)
find_program(VALGRIND_BINARY NAMES valgrind)
set(VALGRIND_DEFAULT_OPTIONS "--leak-check=full --show-leak-kinds=all --track-origins=yes")
if(BUILD_MPI)
set(VALGRIND_DEFAULT_OPTIONS "${VALGRIND_DEFAULT_OPTIONS} --suppressions=${LAMMPS_TOOLS_DIR}/valgrind/OpenMP.supp")
endif()
if(BUILD_OMP)
set(VALGRIND_DEFAULT_OPTIONS "${VALGRIND_DEFAULT_OPTIONS} --suppressions=${LAMMPS_TOOLS_DIR}/valgrind/OpenMP.supp")
endif()
if(PKG_PYTHON)
set(VALGRIND_DEFAULT_OPTIONS "${VALGRIND_DEFAULT_OPTIONS} --suppressions=${LAMMPS_TOOLS_DIR}/valgrind/Python3.supp")
endif()
set(MEMORYCHECK_COMMAND "${VALGRIND_BINARY}" CACHE FILEPATH "Memory Check Command")
set(MEMORYCHECK_COMMAND_OPTIONS "${VALGRIND_DEFAULT_OPTIONS}" CACHE STRING "Memory Check Command Options")
include(CTest)
enable_testing()
get_filename_component(LAMMPS_UNITTEST_DIR ${LAMMPS_SOURCE_DIR}/../unittest ABSOLUTE)
get_filename_component(LAMMPS_UNITTEST_BIN ${CMAKE_BINARY_DIR}/unittest ABSOLUTE)

View File

@ -0,0 +1,74 @@
{
OpenMP_cuda_init_part1
Memcheck:Leak
match-leak-kinds: reachable
fun:calloc
fun:_dlerror_run
fun:dlopen*
obj:*/lib*/libcuda.so.*
obj:*
...
fun:call_init.part.0
fun:_dl_init
obj:/usr/lib*/ld-2.*.so
}
{
OpenMP_init_part1
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
...
obj:/usr/lib*/libgomp.so.1*
fun:call_init.part.0
fun:_dl_init
}
{
OpenMP_init_part2
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
...
obj:/usr/lib*/libgomp.so.1*
fun:GOMP_parallel
...
fun:main
}
{
OpenMP_init_part3
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
...
obj:/usr/lib*/libgomp.so.1*
fun:omp_set_num_threads
...
fun:main
}
{
OpenMP_init_part4
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
...
fun:GOMP_parallel
...
}
{
OpenMP_init_part5
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
...
obj:/usr/lib*/libgomp.so.1*
fun:omp_set_num_threads
...
}
{
OpenMP_init_part6
Memcheck:Leak
match-leak-kinds: possible
fun:calloc
...
fun:GOMP_parallel
...
}

158
tools/valgrind/OpenMPI.supp Normal file
View File

@ -0,0 +1,158 @@
{
OpenMPI_MPI_init1
Memcheck:Leak
match-leak-kinds: indirect
fun:malloc
obj:*
...
fun:ompi_mpi_init
fun:PMPI_Init
fun:main
}
{
OpenMPI_MPI_init2
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
...
fun:mca_pml_base_select
}
{
OpenMPI_MPI_init3
Memcheck:Leak
match-leak-kinds: indirect
fun:malloc
...
fun:mca_pml_base_select
}
{
OpenMPI_MPI_init3
Memcheck:Leak
match-leak-kinds: definite
fun:?alloc
...
fun:ompi_mpi_init
fun:PMPI_Init
fun:main
}
{
OpenMPI_MPI_init4
Memcheck:Leak
match-leak-kinds: reachable
fun:?alloc
...
fun:ompi_mpi_init
fun:PMPI_Init
fun:main
}
{
OpenMPI_MPI_init5
Memcheck:Leak
match-leak-kinds: reachable
fun:?alloc
obj:*/libopen-pal.so.*
fun:mca_base_framework_components_open
fun:mca_base_framework_open
...
fun:ompi_mpi_init
fun:PMPI_Init
}
{
OpenMPI_MPI_init6
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:realloc
obj:*/libopen-pal.so.*
...
fun:opal_progress
fun:ompi_mpi_init
fun:PMPI_Init
fun:main
}
{
OpenMPI_MPI_init7
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:realloc
obj:*/libopen-pal.so.*
...
fun:orte_init
fun:ompi_mpi_init
}
{
OpenMPI_MPI_init8
Memcheck:Leak
match-leak-kinds: reachable
fun:?alloc
...
fun:orte_init
fun:ompi_mpi_init
}
{
OpenMPI_MPI_thread1
Memcheck:Leak
match-leak-kinds: definite
fun:?alloc
...
fun:start_thread
fun:clone
}
{
OpenMPI_MPI_thread2
Memcheck:Leak
match-leak-kinds: reachable
fun:?alloc
...
fun:start_thread
fun:clone
}
{
OpenMPI_comm_init1
Memcheck:Leak
match-leak-kinds: definite
fun:?alloc
...
fun:ompi_comm_enable
fun:mca_topo_base_cart_create
fun:PMPI_Cart_create
}
{
OpenMPI_comm_init2
Memcheck:Leak
match-leak-kinds: reachable
fun:?alloc
...
fun:ompi_comm_enable
fun:mca_topo_base_cart_create
fun:PMPI_Cart_create
}
{
OpenMPI_comm_init3
Memcheck:Leak
match-leak-kinds: reachable
fun:realloc
...
fun:mca_topo_base_comm_select
fun:PMPI_Cart_create
}
{
OpenMPI_comm_init4
Memcheck:Leak
match-leak-kinds: reachable
fun:?alloc
...
fun:mca_topo_base_comm_select
fun:PMPI_Cart_create
}
{
OpenMPI_dlopen_strdup1
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:strdup
obj:*
...
fun:dlopen*
}

145
tools/valgrind/Python3.supp Normal file
View File

@ -0,0 +1,145 @@
{
Python3_main_1
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:PyObject_Malloc
...
fun:_Py_UnixMain
}
{
Python3_main_2
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:PyObject_Malloc
fun:PyUnicode_New
...
fun:_Py_Init_posix
...
}
{
Python3_main_3
Memcheck:Leak
match-leak-kinds: possible
fun:malloc
fun:PyObject_Malloc
...
fun:_Py_UnixMain
...
}
{
Python3_main_4
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:PyObject_Malloc
fun:PyUnicode_New
...
fun:PyInit_posix
...
}
{
Python3_eval_1
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:PyObject_Malloc
...
fun:_PyEval_EvalFrameDefault
}
{
Python3_eval_2
Memcheck:Leak
match-leak-kinds: possible
fun:malloc
fun:PyObject_Malloc
...
fun:_PyEval_EvalFrameDefault
}
{
Python3_eval_3
Memcheck:Leak
match-leak-kinds: possible
fun:malloc
fun:PyObject_Malloc
...
fun:_PyEval_EvalCodeWithName
fun:PyEval_EvalCodeEx
}
{
Python3_call_1
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:PyObject_Malloc
fun:PyCode_New
...
fun:_PyCFunction_FastCallKeywords
}
{
Python3_call_2
Memcheck:Leak
match-leak-kinds: possible
fun:malloc
fun:PyObject_Malloc
fun:PyUnicode_New
...
fun:_PyMethodDef_RawFastCallKeywords
fun:_PyCFunction_FastCallKeywords
}
{
Python3_call_3
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:PyObject_Malloc
fun:PyBytes_FromStringAndSize
...
fun:_PyMethodDef_RawFastCallKeywords
}
{
Python3_call_4
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:PyObject_Malloc
fun:_PyObject_GC_Malloc
fun:PyType_GenericAlloc
...
fun:_PyMethodDef_RawFastCallKeywords
fun:_PyCFunction_FastCallKeywords
...
}
{
Python3_call_5
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:PyObject_Malloc
fun:_PyObject_GC_Malloc
fun:PyType_GenericAlloc
...
fun:_PyMethodDef_RawFastCallKeywords
}
{
Python3_tuple_1
Memcheck:Leak
match-leak-kinds: possible
fun:malloc
fun:PyObject_Malloc
fun:_PyObject_GC_Malloc
fun:_PyObject_GC_NewVar
fun:PyTuple_New
...
}
{
Python3_unicode_1
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:PyObject_Malloc
fun:PyUnicode_New
fun:PyUnicode_FromKindAndData
...
}