Skip to content

Commit 511ae0a

Browse files
authored
Merge pull request #1484 from LLNL/feature/white238/enable_asan
Add `AXOM_ENABLE_ASAN` CMake option
2 parents 379e875 + 01a5102 commit 511ae0a

File tree

6 files changed

+143
-0
lines changed

6 files changed

+143
-0
lines changed

src/cmake/AxomOptions.cmake

+7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
# Defines CMake options for Axom's build system
77
#------------------------------------------------------------------------------
88

9+
option(AXOM_ENABLE_ASAN "Enable AddressSanitizer for memory checking (Clang or GCC only)" OFF)
10+
if(AXOM_ENABLE_ASAN)
11+
if(NOT (C_COMPILER_FAMILY_IS_CLANG OR C_COMPILER_FAMILY_IS_GNU))
12+
message(FATAL_ERROR "AXOM_ENABLE_ASAN only supports Clang and GCC")
13+
endif()
14+
endif()
15+
916
option(AXOM_ENABLE_SPARSEHASH "Enables Sparsehash." ON)
1017
option(AXOM_ENABLE_ALL_COMPONENTS "Enables all components by default" ON)
1118
option(AXOM_USE_64BIT_INDEXTYPE "Use 64-bit integers for axom::IndexType" OFF)

src/cmake/CMakeBasics.cmake

+7
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ blt_append_custom_compiler_flag(FLAGS_VAR AXOM_NINJA_FLAGS
189189
CLANG "-fcolor-diagnostics"
190190
)
191191

192+
if(AXOM_ENABLE_ASAN)
193+
message(STATUS "AddressSanitizer is ON (ENABLE_ASAN)")
194+
foreach(_flagvar CMAKE_C_FLAGS CMAKE_CXX_FLAGS CMAKE_EXE_LINKER_FLAGS)
195+
string(APPEND ${_flagvar} " -fsanitize=address -fno-omit-frame-pointer")
196+
endforeach()
197+
endif()
198+
192199
if(${AXOM_ENABLE_EXPORTS})
193200
set(CMAKE_ENABLE_EXPORTS ON)
194201
endif()

src/docs/sphinx/dev_guide/index.rst

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ changes are made, this guide should be updated accordingly.
5151
testing
5252
updating_tpls
5353
gpu_porting
54+
memory_checking
5455
misc_tasks
5556

5657

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
.. ## Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and
2+
.. ## other Axom Project Developers. See the top-level LICENSE file for details.
3+
.. ##
4+
.. ## SPDX-License-Identifier: (BSD-3-Clause)
5+
6+
.. _memorychecking-label:
7+
8+
===============
9+
Memory Checking
10+
===============
11+
12+
There are two commonly available memory checkers available to use with Axom on LC:
13+
`AddressSanitizer <https://github.com/google/sanitizers/wiki/AddressSanitizer>`_
14+
and `Valgrind <https://valgrind.org/>`_.
15+
16+
AddressSanitizer
17+
----------------
18+
19+
AddressSanitizer (aka Asan) is memory error detection tool that is a part of LLVM. It
20+
very fast and easy to use but doesn't seem as robust as Valgrind. It requires compile
21+
and link flags which are enabled via the CMake option ``AXOM_ENABLE_ASAN``. Anything in our CMake
22+
system will get those flags after that is enabled but our third-party libraries (like MFEM)
23+
will not. After that just run your built executable and Asan will output a log to the screen
24+
after your program is done running. Asan's behavior can be modified with a set of
25+
`environment variables <https://github.com/google/sanitizers/wiki/AddressSanitizerFlags>`_ .
26+
27+
.. note::
28+
Asan only works with the Clang and GCC compiler chains. Our build system will throw
29+
an error if you try to build with anything else while ``AXOM_ENABLE_ASAN`` is ``ON``.
30+
31+
Here is a recommended workflow:
32+
33+
.. code-block:: bash
34+
35+
./config-build.py -hc host-configs/[email protected] -DAXOM_ENABLE_ASAN=ON
36+
37+
srun -N1 --exclusive --mpi-bind=off make -j
38+
LSAN_OPTIONS=suppressions=../suppressions.asan ASAN_OPTIONS=log_path=asan.out:log_exe_name=true srun -n2 <path to test>
39+
40+
This will output files in the current directory for each process that follow the pattern:
41+
``asan.out.<exe name>.<pid>``. It also sets your return code to a non-zero value if there
42+
were any non-suppressed memory errors.
43+
44+
``LSAN_OPTIONS`` and ``ASAN_OPTIONS`` are delimited by ':'.
45+
46+
Here is an explanation of the given options (all should be added to ``ASAN_OPTIONS`` unless noted):
47+
48+
* ``suppressions``: Location of memory leak suppression file (``LSAN_OPTIONS``)
49+
* ``log_path``: Logs to the given file instead of to the screen. This is very helpful
50+
to avoid intermingled lines on the screen from every process
51+
* ``log_exe_name``: Adds executable name to log_path
52+
53+
Helpful options:
54+
55+
* ``fast_unwind_on_malloc=0``: This improves Asan's stack tracing ability but also greatly slows
56+
down the run
57+
* ``exitcode=0``: This stops Asan from returning a a non-zero exit code from your executable
58+
(defaults to 23) (``LSAN_OPTIONS``)
59+
60+
61+
Valgrind
62+
--------
63+
64+
Valgrind is a very powerful set of tools that help with dynamic analysis tools. We will
65+
focus on `memcheck <https://valgrind.org/docs/manual/mc-manual.html>`_ which is a memory
66+
error detection tool.
67+
68+
Unlike Asan, valgrind does not need any special compiler flags. Just build your executable
69+
and run your executable with ``valgrind``. Valgrind's suppression files are easily generated by
70+
valgrind with ``--gen-suppressions=all`` and are more customizable than Asan's.
71+
72+
Here is a recommended workflow:
73+
74+
.. code-block:: bash
75+
76+
./config-build.py -hc host-configs/[email protected]
77+
78+
srun -N1 --exclusive --mpi-bind=off make -j
79+
srun -n2 valgrind --tool=memcheck --log-file=valgrind.out --leak-check=yes --show-leak-kinds=all --num-callers=20 --suppressions=../suppressions.valgrind <path to test>
80+
81+
This will produce a file called ``valgrind.out`` in the current directory with a valgrind report.
82+
83+
Here is an explanation of the given options:
84+
85+
* ``--tool=memcheck``: valgrind is a tool-suite so this runs the memcheck tool
86+
* ``--log-file=valgrind.out``: Logs report to the given file
87+
* ``--leak-check=yes``: Enables memory leak checks
88+
* ``--show-leak-kinds=all```: Enables showing all memory leak kinds
89+
* ``--num-callers=20``: Limits the size of the stack traces to 20
90+
* ``--suppressions=../suppressions.valgrind``: Location of memory leak suppression file

suppressions.asan

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Library that isn't built by us
2+
leak:libpsm2.so.2

suppressions.valgrind

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
<mpi_init_leak>
3+
Memcheck:Leak
4+
...
5+
fun:PMPI_Init
6+
fun:main
7+
}
8+
9+
{
10+
<mpi_init_leak2>
11+
Memcheck:Leak
12+
...
13+
fun:PMPI_Init
14+
}
15+
16+
{
17+
<mpi_init_param>
18+
Memcheck:Param
19+
rt_sigaction(act->sa_mask)
20+
fun:__libc_sigaction
21+
obj:/usr/lib64/libpsm2.so.2.1
22+
obj:/usr/lib64/libpsm2.so.2.1
23+
fun:psm2_ep_open
24+
fun:psm_doinit
25+
fun:MPID_Init
26+
fun:MPIR_Init_thread
27+
fun:PMPI_Init
28+
fun:main
29+
}
30+
31+
{
32+
<psm2_lib>
33+
Memcheck:Leak
34+
...
35+
obj:/usr/lib64/libpsm2.so.2.1
36+
}

0 commit comments

Comments
 (0)