-
Notifications
You must be signed in to change notification settings - Fork 164
Enable ASAN/UBSAN and fix issues detected by ASAN/UBSAN #1649
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
…gs for schema names
…be loaded in the LD_PRELOAD
| } | ||
|
|
||
| /* Adjust pointers */ | ||
| newpos += ctrl[1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH I'm not really sure what's going on in this file, but should newpos and oldpos be updated in the if block?
| include(cmake/depthaiOptions.cmake) | ||
| if(CMAKE_TOOLCHAIN_FILE) | ||
| message(STATUS "Including toolchain file: ${CMAKE_TOOLCHAIN_FILE}") | ||
| include("${CMAKE_TOOLCHAIN_FILE}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary? Isn't CMAKE_TOOLCHAIN_FILE automatically included?
asahtik
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments. I'm not an expert in cmake so feel free to push back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR enables ASAN (AddressSanitizer) and UBSAN (UndefinedBehaviorSanitizer) in the CI/CD workflow and fixes multiple issues detected by these sanitizers. The changes include bug fixes for undefined behavior, CMake configuration updates to support sanitizer toolchains, test infrastructure updates to suppress false positives and known external library leaks, and dependency updates to sanitizer-enabled versions.
Changes:
- Fixed undefined behavior issues in core code (integer overflow in readIntLE, incorrect OpenCV template type usage, logic issues in bspatch)
- Updated CMake configuration to support ASAN/UBSAN/TSAN toolchains with proper flag management
- Added test infrastructure for leak detection suppressions and ASAN options configuration
- Updated dependencies (XLink, RVC4 device firmware) to versions compatible with sanitizers
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/src/onhost_tests/replay_test.cpp | Added ASAN options to disable container overflow detection for protobuf false positives |
| tests/src/ondevice_tests/neural_depth_node_test.cpp | Added ASAN options to disable container overflow detection for protobuf false positives |
| tests/run_tests.py | Added LSAN suppressions file loading for test execution |
| tests/lsan.supp | Created suppressions file for known external library leaks (Mesa, GLib) |
| tests/Dockerfile | Fixed CMAKE_TOOLCHAIN_FILE variable name typo |
| src/utility/ProtoSerialize.cpp | Replaced descriptor()->full_name() calls with hardcoded strings to avoid ASAN issues |
| src/pipeline/datatype/StreamMessageParser.cpp | Fixed readIntLE to use proper unsigned casts and bit operations instead of multiplication |
| src/bspatch/bspatch.c | Added NULL check before memcpy in extra block handling |
| examples/cpp/SpatialLocationCalculator/spatial_location_calculator.cpp | Fixed OpenCV template type from float to uint16_t for depth frame access |
| cmake/toolchain/tsan.cmake | Added sanitizer flag configuration and debug message |
| cmake/toolchain/asan-ubsan.cmake | Added sanitizer flag configuration |
| cmake/sanitizers/FindTSan.cmake | Removed extra blank line |
| cmake/sanitizers/FindASan.cmake | Added debug messages for sanitizer configuration |
| cmake/depthaiDependencies.cmake | Updated XLink dependency to sanitizer-compatible version |
| cmake/Depthai/DepthaiDeviceRVC4Config.cmake | Updated RVC4 device firmware version |
| bindings/python/CMakeLists.txt | Added libstdc++ to LD_PRELOAD for GCC ASAN support |
| CMakeLists.txt | Added early toolchain file inclusion and removed redundant sanitizer flag settings |
| .github/workflows/test_child.yml | Minor comment spacing adjustment |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if(CMAKE_TOOLCHAIN_FILE) | ||
| message(STATUS "Including toolchain file: ${CMAKE_TOOLCHAIN_FILE}") | ||
| include("${CMAKE_TOOLCHAIN_FILE}") | ||
| else() | ||
| message(STATUS "No toolchain file specified, skipping include.") | ||
| endif() |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Manually including the toolchain file before the project() command is problematic. CMake automatically processes the toolchain file specified via CMAKE_TOOLCHAIN_FILE before the project() command runs. This manual include() will cause the toolchain file to be processed twice: once here via include(), and once automatically by CMake when project() is called. This can lead to flags being set multiple times and unexpected behavior. The toolchain file should only be specified via -DCMAKE_TOOLCHAIN_FILE= on the command line or in presets, and never manually included.
| if(CMAKE_TOOLCHAIN_FILE) | |
| message(STATUS "Including toolchain file: ${CMAKE_TOOLCHAIN_FILE}") | |
| include("${CMAKE_TOOLCHAIN_FILE}") | |
| else() | |
| message(STATUS "No toolchain file specified, skipping include.") | |
| endif() |
| if(ctrl[1] > 0 && p_decompressed_block[EXTRA_BLOCK] != NULL) { | ||
| memcpy(new + newpos, p_decompressed_block[EXTRA_BLOCK], ctrl[1]); | ||
| p_decompressed_block[EXTRA_BLOCK] += ctrl[1]; | ||
| } | ||
|
|
||
| /* Adjust pointers */ | ||
| newpos += ctrl[1]; |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a logic inconsistency with the NULL check. If ctrl[1] > 0 but p_decompressed_block[EXTRA_BLOCK] is NULL, the memcpy and pointer increment at line 218 are skipped. However, at line 222, newpos is unconditionally incremented by ctrl[1]. This means the output position advances even though no data was copied, potentially leaving uninitialized data in the output buffer. Either the NULL check should be removed (as the bounds check at line 210 should catch any issues), or the position adjustment at line 222 should be moved inside the conditional block at line 216.
| if(schemaName == "dai.proto.encoded_frame.EncodedFrame") { | ||
| return DatatypeEnum::EncodedFrame; | ||
| } else if(schemaName == proto::imu_data::IMUData::descriptor()->full_name()) { | ||
| } else if(schemaName == "dai.proto.imu_data.IMUData") { | ||
| return DatatypeEnum::IMUData; | ||
| } else if(schemaName == proto::image_annotations::ImageAnnotations::descriptor()->full_name()) { | ||
| } else if(schemaName == "dai.proto.image_annotations.ImageAnnotations") { | ||
| return DatatypeEnum::ImgAnnotations; | ||
| } else if(schemaName == proto::img_detections::ImgDetections::descriptor()->full_name()) { | ||
| } else if(schemaName == "dai.proto.img_detections.ImgDetections") { | ||
| return DatatypeEnum::ImgDetections; | ||
| } else if(schemaName == proto::img_frame::ImgFrame::descriptor()->full_name()) { | ||
| } else if(schemaName == "dai.proto.img_frame.ImgFrame") { | ||
| return DatatypeEnum::ImgFrame; | ||
| } else if(schemaName == proto::point_cloud_data::PointCloudData::descriptor()->full_name()) { | ||
| } else if(schemaName == "dai.proto.point_cloud_data.PointCloudData") { | ||
| return DatatypeEnum::PointCloudData; | ||
| } else if(schemaName == proto::spatial_img_detections::SpatialImgDetections::descriptor()->full_name()) { | ||
| } else if(schemaName == "dai.proto.spatial_img_detections.SpatialImgDetections") { | ||
| return DatatypeEnum::SpatialImgDetections; |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replacing descriptor()->full_name() with hardcoded string literals. While this may fix an ASAN/UBSAN issue (likely related to static initialization order or descriptor lifetime), it makes the code more fragile. If the protobuf schema names change in the future, these hardcoded strings will not be updated automatically by the compiler, potentially causing runtime failures. Consider whether there's a safer alternative, such as caching the descriptor names after initialization or using constexpr string constants defined alongside the proto definitions.
| message(STATUS "SANITIZE_THREAD = ${SANITIZE_THREAD}") | ||
| message(STATUS "SANITIZE_ADDRESS = ${SANITIZE_ADDRESS}") |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These debug STATUS messages were added but should be removed before merging to production. Debug messages like these are useful during development but add noise to the build output in production builds. Consider using CMAKE_MESSAGE_LOG_LEVEL or removing these messages once the sanitizer configuration is verified to work correctly.
| message(STATUS "SANITIZE_THREAD = ${SANITIZE_THREAD}") | |
| message(STATUS "SANITIZE_ADDRESS = ${SANITIZE_ADDRESS}") |
| @@ -1,3 +1,4 @@ | |||
| message(STATUS ">>> Toolchain loaded: ${CMAKE_CURRENT_LIST_FILE}") | |||
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This debug STATUS message was added but should be removed before merging to production. Debug messages like this are useful during development but add noise to the build output in production builds.
| message(STATUS ">>> Toolchain loaded: ${CMAKE_CURRENT_LIST_FILE}") |
Purpose
ASAN/UBSAN were disabled. Enabling them made the tests fail, as multiple issues were detected. The underlying issues had to be fixed. This PR makes #1485 obsolete.
Specification
ASAN/UBSAN is enabled in the workflow, detected issues are fixed.
Dependencies & Potential Impact
None / not applicable
Deployment Plan
None / not applicable
Testing & Validation
This was tested using HIL tests with enabled ASAN/UBSAN.