Debugging

There are several methods we typically use to debug issues in Castro. Some descriptions are given below.

Using the compiler and other tools

Compiler checks

Recompile the code in debug-mode by setting:

DEBUG := TRUE

in the GNUmakefile (or invoking make as make DEBUG=TRUE). This will create an executable with bounds checking and other compiler options enabled. Running this sometimes will show issues.

Check for invalid floating point exceptions

Compiling in debug mode also initializes uninitialized variables to NaN. For optimized code, the same can be done by setting:

TEST := TRUE

in the GNUmakefile. To capture the NaNs, use the runtime parameter:

amrex.fpe_trap_invalid=1

If the code crashes, it will produce one or more Backtrace.* files. Looking over these files should pinpoint where the FPE occurred allowing you to do further debugging.

You can output more information into the Backtrace.* files by pushing it to the backtrace stack as described here: Debugging.

Make sure your runtime options are valid

Castro can validate the runtime options specified in the inputs file by running with castro.abort_on_invalid_params = 1.

Valgrind

We frequently run Castro with valgrind to find illegal memory accesses. The valgrind documentation can give details on how to use it.

Clang-tidy

We run clang-tidy on all pull requests using a GitHub action. clang-tidy analyzes the source code, produces warnings for potential bugs and offers suggestions for performance improvements.

It can also be run locally. Support for this is enabled via the AMReX build system, and requires that you have clang-tidy installed locally. You build via:

make USE_CLANG_TIDY=TRUE

and this will use the clang-tidy options set in Castro/.clang-tidy. If you do a parallel build, you should use the -O flag to ensure that output is not mixed between files.

You can also use ask it to fix errors automatically via:

make USE_CLANG_TIDY=TRUE CLANG_TIDY="clang-tidy --fix-errors"

and you can treat warnings as errors by adding CLANG_TIDY_WARN_ERROR=TRUE.

Note

Building a Castro problem with clang-tidy will suppress the checks in AMReX and Microphysics sources and headers. This is set by the parameter CLANG_TIDY_IGNORE_SOURCES in Make.Castro, and the HeaderFilterRegex whitelist in .clang-tidy.

Thread sanitizer

Instrumenting the Code

Checking for NaNs

In the C++ code, you can check whether a FAB contains NaNs using the contains_nan() method:

for (MFIter mfi(S, True); mfi.isValid(); ++mfi) {

  const Box& bx = mf.tilebox()

  // do some operations on S[mfi]

  if (S[mfi].contains_nan()) {
    amrex::Abort("S has NaNs")
  }
}

There are other versions of contains_nan() that can take a Box to operate over.

Physics issues