feat: add sanitizer support in CMake and linux-eic-shell CI#50
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds CMake sanitizer toggles (ASAN, TSAN, UBSAN) to the top-level build configuration, aligned with the EICrecon approach.
Changes:
- Introduces
USE_ASAN,USE_TSAN, andUSE_UBSANCMake options with corresponding compile/link flag wiring. - Includes
CheckCXXCompilerFlagfor conditional UBSAN sub-sanitizer detection. - Iterates through UBSAN-related sanitizer modes, enabling only those supported by the compiler.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
9621af0 to
9d62380
Compare
|
@copilot Avoid the issues with DD4hep's ist_component in https://github.com/eic/npsim/actions/runs/25996995581/job/76413142608?pr=50 implementing a similar bypass function as in https://github.com/eic/epic/blob/317fdbbd02a739f102990c96d40e99ca5e4e944f/CMakeLists.txt#L74 |
Implemented in 1810fd3: added a local |
|
@copilot In addition to enabling ASAN and UBSAN, also set the environment variables as in https://github.com/eic/epic/blob/317fdbbd02a739f102990c96d40e99ca5e4e944f/.github/workflows/linux-eic-shell.yml#L17-20, including for the currently unused TSAN, and create stubs for the suppression files (currently empty, i.e. with a comment only). |
Implemented in e4be85c: added top-level linux-eic-shell workflow env vars for |
72b8c54 to
1384adf
Compare
Capybara summary for PR 50
|
Agent-Logs-Url: https://github.com/eic/npsim/sessions/5b409afc-ca7a-42b0-8990-c05f6a716532 Co-authored-by: wdconinc <4656391+wdconinc@users.noreply.github.com>
Agent-Logs-Url: https://github.com/eic/npsim/sessions/9352f408-2848-4e2f-a0a7-34240b8926d2 Co-authored-by: wdconinc <4656391+wdconinc@users.noreply.github.com>
Agent-Logs-Url: https://github.com/eic/npsim/sessions/7ef95df0-f2f7-48c5-80df-ee2e00eed7bf Co-authored-by: wdconinc <4656391+wdconinc@users.noreply.github.com>
Agent-Logs-Url: https://github.com/eic/npsim/sessions/9eaadfe1-70e9-410d-af73-be8a35f440da Co-authored-by: wdconinc <4656391+wdconinc@users.noreply.github.com>
With Clang, -fsanitize=address on a shared/module library only links the bootstrap stubs (libclang_rt.asan_static), not the full ASAN runtime DSO. The stubs forward calls to __asan_report_load* etc., which must come from the full runtime. Since DD4hep binaries are not ASAN-instrumented, those symbols are never loaded, causing link failures in NPDetPlugins.so. Fix: add -shared-libasan for USE_ASAN and -shared-libsan for USE_UBSAN/ USE_TSAN to CMAKE_SHARED_LINKER_FLAGS and CMAKE_MODULE_LINKER_FLAGS when the compiler is Clang. GCC already links -lasan/-lubsan/-ltsan as shared DSOs via -fsanitize=..., so no change is needed there. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
With -shared-libasan/-shared-libsan, Clang shared/module libs get
explicit dynamic dependencies on architecture-suffixed runtime DSOs:
libclang_rt.asan-x86_64.so
libclang_rt.ubsan_standalone-x86_64.so
libclang_rt.tsan-x86_64.so
The existing execute_process calls used -print-file-name=libasan.so
etc., which are GCC library names and do not resolve to the Clang
runtimes. This caused libNPDetPlugins.so to fail loading during
the dd4hep_listcomponents build step.
Fix: branch on CMAKE_CXX_COMPILER_ID and use the Clang-specific
architecture-qualified names (libclang_rt.<san>-${CMAKE_SYSTEM_PROCESSOR}.so)
for LD_PRELOAD; keep GCC names on the else branch.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three issues found and fixed through local reproduction in the eic-shell container (clang++ 20, DD4hep 1.36): 1. CMAKE_BUILD_RPATH: embed the sanitizer runtime directory in all built shared libraries so the linker finds transitive dependencies (e.g. libGeoCad.so -> libclang_rt.asan-x86_64.so) without a warning. 2. LD_PRELOAD + detect_leaks=0: ASAN must be loaded before any allocation occurs (i.e. via LD_PRELOAD, not lazily via dlopen/RPATH). Loading it late after DD4hep/ROOT have already allocated memory causes a segfault. However LD_PRELOAD with the default detect_leaks=1 causes LeakSanitizer to scan the entire DD4hep/ROOT/Geant4 heap at listcomponents exit, hanging the build. We override ASAN_OPTIONS=detect_leaks=0 and LSAN_OPTIONS=detect_leaks=0 for this one helper invocation only, using cmake -E env to set the environment cleanly with generator expression support. verify_asan_link_order=0 is also set because LD_PRELOAD loads ASAN after the system libraries already mapped by listcomponents. 3. UBSAN standalone conflict with ASAN: when both USE_ASAN and USE_UBSAN are active with Clang, preloading libclang_rt.ubsan_standalone alongside libclang_rt.asan causes a CPU-spinning hang because both runtimes provide overlapping interceptors. Clang's ASAN runtime already integrates UBSAN, so libclang_rt.ubsan_standalone must not be added to PRELOAD_SANITIZER_LIB in this combination (confirmed via ldd: the plugin only depends on libclang_rt.asan, not ubsan_standalone). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Added options for address, thread, and undefined behavior sanitizers in CMake.
7f8f111 to
33a7867
Compare
This PR adds sanitizer support to
npsimand aligns CI/runtime behavior with theepicapproach to avoid DD4hep component-generation failures under sanitizer-enabled builds.Changes Made
USE_ASANUSE_TSANUSE_UBSANCheckCXXCompilerFlag.CMAKE_MODULE_LINKER_FLAGS) to cover plugin/module targets.dd4hep_generate_rootmap()bypass (similar toepic) that runsDD4hep::listcomponentswith sanitizer runtime preloads to avoidis_component-related failures..github/workflows/linux-eic-shell.ymlbuild configuration to enable:-DUSE_ASAN=ON-DUSE_UBSAN=ONfor all current matrix builds.
ASAN_OPTIONSLSAN_OPTIONSUBSAN_OPTIONSTSAN_OPTIONS.github/asan.supp.github/lsan.supp.github/ubsan.supp.github/tsan.supp