Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ jobs:
tsan:
name: Thread Sanitizer
runs-on: ubuntu-latest
if: false # Temporarily disabled

steps:
- name: Checkout code
Expand Down Expand Up @@ -254,10 +253,7 @@ jobs:
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
-DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_TARGET_TRIPLET=x64-linux-release \
-DCMAKE_CXX_FLAGS="-fsanitize=thread -g" \
-DCMAKE_C_FLAGS="-fsanitize=thread -g" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=thread" \
-DCMAKE_MODULE_LINKER_FLAGS="-fsanitize=thread"
-DENABLE_TSAN=ON

- name: Build
run: |
Expand All @@ -269,7 +265,7 @@ jobs:
run: |
ctest --output-on-failure --verbose
env:
TSAN_OPTIONS: halt_on_error=0
TSAN_OPTIONS: suppressions=${{ github.workspace }}/tsan.supp:halt_on_error=0

# Static Analysis with clang-tidy
static-analysis:
Expand Down
23 changes: 23 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,23 @@ option(BUILD_SHARED_LIBS "Build shared libraries (DLL)" ON)
option(REMOTE_PROFILER_INSTALL "Generate install target" ON)
option(REMOTE_PROFILER_BUILD_EXAMPLES "Build example programs" ON)
option(REMOTE_PROFILER_BUILD_TESTS "Build test programs" ON)
option(ENABLE_TSAN "Enable ThreadSanitizer for data race detection" OFF)

message(STATUS "Build options:")
message(STATUS " BUILD_SHARED_LIBS: ${BUILD_SHARED_LIBS}")
message(STATUS " REMOTE_PROFILER_INSTALL: ${REMOTE_PROFILER_INSTALL}")
message(STATUS " REMOTE_PROFILER_BUILD_EXAMPLES: ${REMOTE_PROFILER_BUILD_EXAMPLES}")
message(STATUS " REMOTE_PROFILER_BUILD_TESTS: ${REMOTE_PROFILER_BUILD_TESTS}")
message(STATUS " ENABLE_TSAN: ${ENABLE_TSAN}")

# ThreadSanitizer configuration
if(ENABLE_TSAN)
message(STATUS "ThreadSanitizer enabled")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -g -O1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread -g -O1")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=thread")
endif()

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down Expand Up @@ -137,6 +148,18 @@ if(REMOTE_PROFILER_BUILD_TESTS)
)

add_test(NAME FullFlowTest COMMAND test_full_flow)

# Set TSAN environment for tests if enabled
if(ENABLE_TSAN)
set(TSAN_SUPPRESSIONS_FILE "${PROJECT_SOURCE_DIR}/tsan.supp")
set_tests_properties(CPUProfileTest PROPERTIES
ENVIRONMENT "TSAN_OPTIONS=suppressions=${TSAN_SUPPRESSIONS_FILE}:halt_on_error=0"
)
set_tests_properties(FullFlowTest PROPERTIES
ENVIRONMENT "TSAN_OPTIONS=suppressions=${TSAN_SUPPRESSIONS_FILE}:halt_on_error=0"
)
endif()

message(STATUS "Tests will be built")
else()
message(STATUS "Tests disabled")
Expand Down
24 changes: 24 additions & 0 deletions cmake/tsan.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# TSAN (ThreadSanitizer) Configuration
# Usage: cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_TSAN=ON ..

option(ENABLE_TSAN "Enable ThreadSanitizer" OFF)

if(ENABLE_TSAN)
message(STATUS "ThreadSanitizer enabled")

# Add TSAN compiler/linker flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -g -O1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread -g -O1")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=thread")

# Set suppression file path
set(TSAN_SUPPRESSIONS_FILE "${PROJECT_SOURCE_DIR}/tsan.supp")

# Create test runner script with TSAN options
configure_file(
"${PROJECT_SOURCE_DIR}/cmake/tsan_test.sh.in"
"${CMAKE_BINARY_DIR}/tsan_test.sh"
@ONLY
)
endif()
15 changes: 15 additions & 0 deletions cmake/tsan_test.sh.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash
# TSAN Test Runner Script
# This script runs tests with ThreadSanitizer and suppression file

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TSAN_OPTIONS="suppressions=@TSAN_SUPPRESSIONS_FILE@:halt_on_error=0:report_bugs=1"

export TSAN_OPTIONS

echo "Running tests with TSAN suppression file: @TSAN_SUPPRESSIONS_FILE@"
echo "TSAN_OPTIONS: $TSAN_OPTIONS"
echo ""

# Run the test
exec "$@"
63 changes: 63 additions & 0 deletions tsan.supp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# ThreadSanitizer Suppressions for cpp-remote-profiler
# These suppress known issues in third-party dependencies (trantor, drogon)
# that are beyond our control.

# =============================================================================
# Trantor Library - Data Races
# =============================================================================

# Trantor EventLoop wakeup race condition
race:trantor::EventLoop::wakeup

# Trantor TimingWheel shared_ptr race
race:std::_Sp_counted_base*

# Trantor MpscQueue operations
race:trantor::MpscQueue*

# Trantor EventLoop internal
race:trantor::EventLoop::loop
race:trantor::EventLoop::updateChannel
race:trantor::EventLoop::removeChannel
race:trantor::EventLoop::queueInLoop

# =============================================================================
# Trantor Library - Signal-unsafe calls (known limitation)
# =============================================================================

# These occur when signal handlers interrupt trantor's event loop
# The signal handler in profiler_manager.cpp is signal-safe,
# but TSAN reports these because trantor was in the call stack

signal:trantor::Date::toFormattedString
signal:trantor::EpollPoller::poll
signal:trantor::Logger::formatTime
signal:trantor::MpscQueue*
signal:trantor::EventLoop::wakeup

# =============================================================================
# Drogon Framework - Data Races
# =============================================================================

# Drogon HttpServer shared_ptr issues
race:drogon::HttpServer
race:drogon::HttpAppFrameworkImpl

# =============================================================================
# libstdc++ / libc - Known false positives with shared_ptr
# =============================================================================

# These are known issues with std::shared_ptr reference counting
# under TSAN when used across threads
race:std::__shared_count*
race:std::_Sp_counted_base*

# =============================================================================
# gperftools / tcmalloc - Known TSAN issues
# =============================================================================

# gperftools has known TSAN issues that are by design
race:ProfilerStart
race:ProfilerStop
race:HeapProfilerStart
race:HeapProfilerStop
Loading