From 6c16de174a6d3fc42a26cc8131b45ab7abda8d63 Mon Sep 17 00:00:00 2001 From: jolavillette Date: Thu, 9 Jul 2026 23:51:44 +0200 Subject: [PATCH] docs(BUILD): add Debug build section for Linux (gdb symbols + ASan) New 'Debug build (Linux)' subsection: CMAKE_BUILD_TYPE=Debug with -g3 -O0 -fno-omit-frame-pointer for full symbols and exact backtraces, a Qt6 note, a RelWithDebInfo caveat, the gdb invocation with the real binary path (Build-cmake/retroshare-gui/retroshare), and an AddressSanitizer variant for use-after-free / heap bugs. Co-Authored-By: Claude Opus 4.8 --- BUILD-cmake.md | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/BUILD-cmake.md b/BUILD-cmake.md index cbc7497b6..96ee02f06 100644 --- a/BUILD-cmake.md +++ b/BUILD-cmake.md @@ -121,6 +121,83 @@ cmake -G Ninja -B Build-cmake -S . \ cmake --build Build-cmake -j$(nproc) ``` +### Debug build (Linux) + +The commands above build `Release` (`-O3 -DNDEBUG`): aggressive inlining, assertions +stripped. Fine for daily use, wrong under a debugger — backtraces land on +misattributed lines and locals read ``. To step through code or +investigate a crash with `gdb`, build `Debug` instead. + +Two changes to the Qt5 configure above: +- swap `-DCMAKE_BUILD_TYPE=Release` for `-DCMAKE_BUILD_TYPE=Debug` (gives `-g -O0`); +- pin explicit debug flags so every symbol is emitted and nothing is inlined: + `-DCMAKE_CXX_FLAGS_DEBUG` / `-DCMAKE_C_FLAGS_DEBUG` = `-g3 -O0 -fno-omit-frame-pointer`. + +`-g3` emits full debug info **including macro definitions**; `-O0` disables inlining so +backtrace line numbers are exact; `-fno-omit-frame-pointer` keeps stack unwinding +reliable. + +```bash +rm -rf Build-cmake +cmake -G Ninja -B Build-cmake -S . \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_CXX_FLAGS_DEBUG="-g3 -O0 -fno-omit-frame-pointer" \ + -DCMAKE_C_FLAGS_DEBUG="-g3 -O0 -fno-omit-frame-pointer" \ + -DCMAKE_DISABLE_FIND_PACKAGE_Qt6=ON \ + -DRS_RNPLIB=ON -DRS_JSON_API=ON -DRS_WEBUI=ON -DRS_SERVICE_TERMINAL_WEBUI_PASSWORD=ON \ + -DRS_GUI=ON -DRS_SERVICE=ON -DRS_FRIENDSERVER=ON -DRS_PLUGINS=ON -DRS_FORUM_DEEP_INDEX=OFF \ + -DRS_USE_I2P_SAM3=ON -DRS_BITDHT=ON -DRS_MINIUPNPC=ON \ + -DRS_BRODCAST_DISCOVERY=ON -DRS_SQLCIPHER=ON +cmake --build Build-cmake -j$(nproc) +``` + +> For a **Qt6** debug build, drop `-DCMAKE_DISABLE_FIND_PACKAGE_Qt6=ON` and set +> `-DRS_PLUGINS=OFF` (as in the Release Qt6 command); the debug flags are identical. + +> A Debug build compiles slower and produces a much larger binary — expected. +> `RelWithDebInfo` (`-O2 -g`) is a middle ground with usable symbols, but because it +> still optimizes it gives approximate backtraces; prefer `Debug` when chasing a crash. + +Run the GUI under gdb (the binary lands at `Build-cmake/retroshare-gui/retroshare`): + +```bash +gdb ./Build-cmake/retroshare-gui/retroshare +``` + +then `run`, reproduce the issue, and `bt` at the crash for a full symbolized stack. + +#### AddressSanitizer (use-after-free / heap bugs) + +For memory-corruption bugs (use-after-free, heap overflow, double free), an ASan build +reports the fault **at the moment of the bad access**, with three stacks — allocation, +free, and the offending access — instead of a bare `SIGSEGV` after the fact. Add +`-fsanitize=address` to both the compile and the link flags: + +```bash +rm -rf Build-cmake +cmake -G Ninja -B Build-cmake -S . \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_CXX_FLAGS_DEBUG="-g3 -O1 -fno-omit-frame-pointer -fsanitize=address" \ + -DCMAKE_C_FLAGS_DEBUG="-g3 -O1 -fno-omit-frame-pointer -fsanitize=address" \ + -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" \ + -DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address" \ + -DCMAKE_MODULE_LINKER_FLAGS="-fsanitize=address" \ + -DCMAKE_DISABLE_FIND_PACKAGE_Qt6=ON \ + -DRS_RNPLIB=ON -DRS_JSON_API=ON -DRS_WEBUI=ON -DRS_SERVICE_TERMINAL_WEBUI_PASSWORD=ON \ + -DRS_GUI=ON -DRS_SERVICE=ON -DRS_FRIENDSERVER=ON -DRS_PLUGINS=ON -DRS_FORUM_DEEP_INDEX=OFF \ + -DRS_USE_I2P_SAM3=ON -DRS_BITDHT=ON -DRS_MINIUPNPC=ON \ + -DRS_BRODCAST_DISCOVERY=ON -DRS_SQLCIPHER=ON +cmake --build Build-cmake -j$(nproc) +``` + +> Needs the ASan runtime: `sudo apt-get install -y libasan8`. Run with leak detection +> **off** — RetroShare allocates plenty at startup that would otherwise bury the report: +> ```bash +> ASAN_OPTIONS=abort_on_error=1:detect_leaks=0 ./Build-cmake/retroshare-gui/retroshare +> ``` +> `-O1` (not `-O0`) is deliberate: ASan needs light optimization for acceptable runtime +> and cleaner reports, and the sanitizer preserves accurate line numbers regardless. + --- ## macOS (Homebrew, Apple Silicon)