Debugging Nim

!!! warning This auditors' handbook is frozen and obsolete; the Nim language manual alongside other Nim documentation, Status Nim style guide, Chronos guides, and Nim by Example supercede it.

Reference article: https://nim-lang.org/blog/2017/10/02/documenting-profiling-and-debugging-nim-code.html

GDB / LLDB

Nim can be instrumented with sourcemaps:

  • by passing --debugger:native to the compiler, so that the stacktraces in gdb shows the Nim source code
  • by passing --passC:"-g" to the compiler, so that the stacktraces in gdb shows the C source code

Sanitizers & Valgrind

LLVM and GCC sanitizers can be used with

nim c --cc:clang -r -d:release --debugger:native \
  --passC:"-fsanitize=address" --passL:"-fsanitize=address" \
  --outdir:build target_application.nim

Note on deactivating Nim memory allocator:

As mentioned in the memory management section, Nim has

  • a garbage collector, by default deferred reference counting + cycle detection via mark-and-sweep if the types can have cycles (and is not tagged {.acyclic.})
  • an allocator based on TLSF

Instead of Nim custom allocators, the sys malloc/free can be used by passing -d:useMalloc in the command-line

Some GC/versions might not properly accept the flag, this is a Nim bug and we can patch upstream and our own fork in that case

Fuzzers

TODO

Internal fuzzing

We are currently adding fuzzing to our repositories via libFuzzer and AFL.

External "Consensus" fuzzing

Sigma Prima is fuzzing all Ethereum 2 clients on the spec (Eth2 core/Validator core)

We provide them with a simple C API

That we implement:

And compile the nim code as a shared or static library.

On usage, the only extra limitation compared to a C library is the need to call NimMain() before calling any Nim function to initialize the Nim runtime.

Inspecting the generated intermediate code and objects

The intermediate C code and object files are stored in

  • $HOME/.cache/nim/compiled_target_d or $HOME/.cache/nim/compiled_target_r on UNIX (d for debug, r for release)
  • $HOME/nimcache/compiled_target_d or $HOME/.cache/nim/compiled_target_r on Windows

The cache directory can be set with the --nimcache=<targetdir> compiler flag.

Repositories vendoring nimbus-build-system do not use the default setting but generate directly in the (gitignored) nimcache folder of the repo.