@@ -19,6 +19,7 @@ concurrency:
1919env :
2020 BITCOIN_REPO : bitcoin/bitcoin
2121 LLVM_VERSION : 22
22+ LIBCXX_DIR : /tmp/libcxx-build/
2223
2324jobs :
2425 bitcoin-core :
@@ -160,3 +161,184 @@ jobs:
160161 with :
161162 path : ${{ env.CCACHE_DIR }}
162163 key : ccache-${{ matrix.name }}-${{ github.ref }}-${{ github.sha }}
164+
165+ bitcoin-core-tsan :
166+ name : TSan
167+ runs-on : ubuntu-24.04
168+ timeout-minutes : 180
169+
170+ env :
171+ CCACHE_MAXSIZE : 400M
172+ CCACHE_DIR : ${{ github.workspace }}/.ccache
173+ LIBCXX_FLAGS : >-
174+ -fsanitize=thread
175+ -nostdinc++
176+ -nostdlib++
177+ -isystem /tmp/libcxx-build/include/c++/v1
178+ -L/tmp/libcxx-build/lib
179+ -Wl,-rpath,/tmp/libcxx-build/lib
180+ -lc++
181+ -lc++abi
182+ -lpthread
183+ -Wno-unused-command-line-argument
184+ TSAN_OPTIONS : suppressions=${{ github.workspace }}/test/sanitizer_suppressions/tsan:halt_on_error=1:second_deadlock_stack=1
185+
186+ steps :
187+ - name : Checkout Bitcoin Core
188+ uses : actions/checkout@v4
189+ with :
190+ repository : ${{ env.BITCOIN_REPO }}
191+ fetch-depth : 1
192+
193+ - name : Add LLVM apt repository
194+ run : |
195+ curl -s "https://apt.llvm.org/llvm-snapshot.gpg.key" | sudo tee "/etc/apt/trusted.gpg.d/apt.llvm.org.asc" > /dev/null
196+ source /etc/os-release
197+ echo "deb http://apt.llvm.org/${VERSION_CODENAME}/ llvm-toolchain-${VERSION_CODENAME}-${LLVM_VERSION} main" | sudo tee "/etc/apt/sources.list.d/llvm.list"
198+ sudo apt-get update
199+
200+ - name : Install packages
201+ run : |
202+ sudo apt-get install --no-install-recommends -y \
203+ "clang-${LLVM_VERSION}" \
204+ "llvm-${LLVM_VERSION}" \
205+ "llvm-${LLVM_VERSION}-dev" \
206+ "libclang-${LLVM_VERSION}-dev" \
207+ "libclang-rt-${LLVM_VERSION}-dev" \
208+ ninja-build \
209+ pkgconf \
210+ python3-pip \
211+ bison
212+ sudo update-alternatives --install /usr/bin/clang++ clang++ "/usr/bin/clang++-${LLVM_VERSION}" 100
213+ sudo update-alternatives --install /usr/bin/clang clang "/usr/bin/clang-${LLVM_VERSION}" 100
214+ sudo update-alternatives --install /usr/bin/llvm-symbolizer llvm-symbolizer "/usr/bin/llvm-symbolizer-${LLVM_VERSION}" 100
215+ pip3 install --break-system-packages pycapnp
216+
217+ - name : Restore instrumented libc++ cache
218+ id : libcxx-cache
219+ uses : actions/cache@v4
220+ with :
221+ path : ${{ env.LIBCXX_DIR }}
222+ key : libcxx-Thread-llvmorg-${{ env.LLVM_VERSION }}.1.0
223+
224+ - name : Build instrumented libc++
225+ if : steps.libcxx-cache.outputs.cache-hit != 'true'
226+ run : |
227+ git clone --depth=1 https://github.com/llvm/llvm-project -b "llvmorg-${LLVM_VERSION}.1.0" /tmp/llvm-project
228+ cmake -G Ninja -B "$LIBCXX_DIR" \
229+ -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
230+ -DCMAKE_BUILD_TYPE=Release \
231+ -DLLVM_USE_SANITIZER=Thread \
232+ -DCMAKE_C_COMPILER=clang \
233+ -DCMAKE_CXX_COMPILER=clang++ \
234+ -DLLVM_TARGETS_TO_BUILD=Native \
235+ -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \
236+ -DLIBCXX_INCLUDE_TESTS=OFF \
237+ -DLIBCXXABI_INCLUDE_TESTS=OFF \
238+ -DLIBUNWIND_INCLUDE_TESTS=OFF \
239+ -DLIBCXXABI_USE_LLVM_UNWINDER=OFF \
240+ -S /tmp/llvm-project/runtimes
241+ ninja -C "$LIBCXX_DIR" "-j$(nproc)"
242+ rm -rf /tmp/llvm-project
243+
244+ - name : Determine host
245+ id : host
246+ run : echo "host=$(./depends/config.guess)" >> "$GITHUB_OUTPUT"
247+
248+ - name : Restore depends cache
249+ id : depends-cache
250+ uses : actions/cache/restore@v4
251+ with :
252+ path : |
253+ depends/built
254+ depends/${{ steps.host.outputs.host }}
255+ key : depends-tsan-${{ hashFiles('depends/packages/*.mk') }}-${{ env.LLVM_VERSION }}
256+
257+ - name : Build depends (stage 1, without IPC)
258+ if : steps.depends-cache.outputs.cache-hit != 'true'
259+ run : |
260+ make -C depends "-j$(nproc)" \
261+ CC=clang \
262+ CXX=clang++ \
263+ CXXFLAGS="${LIBCXX_FLAGS}" \
264+ NO_QT=1 \
265+ NO_ZMQ=1 \
266+ NO_USDT=1 \
267+ NO_QR=1 \
268+ NO_IPC=1
269+
270+ - name : Save depends cache
271+ uses : actions/cache/save@v4
272+ if : steps.depends-cache.outputs.cache-hit != 'true'
273+ with :
274+ path : |
275+ depends/built
276+ depends/${{ steps.host.outputs.host }}
277+ key : depends-tsan-${{ hashFiles('depends/packages/*.mk') }}-${{ env.LLVM_VERSION }}
278+
279+ - name : Checkout libmultiprocess
280+ uses : actions/checkout@v4
281+ with :
282+ path : _libmultiprocess
283+
284+ - name : Replace libmultiprocess subtree
285+ run : |
286+ rm -rf src/ipc/libmultiprocess
287+ mv _libmultiprocess src/ipc/libmultiprocess
288+
289+ - name : Build depends (stage 2, IPC packages including libmultiprocess)
290+ run : |
291+ make -C depends "-j$(nproc)" \
292+ CC=clang \
293+ CXX=clang++ \
294+ CXXFLAGS="${LIBCXX_FLAGS}" \
295+ NO_QT=1 \
296+ NO_ZMQ=1 \
297+ NO_USDT=1 \
298+ NO_QR=1
299+
300+ - name : Restore ccache
301+ id : ccache-restore
302+ uses : actions/cache/restore@v4
303+ with :
304+ path : ${{ env.CCACHE_DIR }}
305+ key : ccache-TSan-${{ github.ref }}-${{ github.sha }}
306+ restore-keys : |
307+ ccache-TSan-${{ github.ref }}-
308+ ccache-TSan-
309+
310+ - name : CMake configure
311+ run : |
312+ cmake -S . -B build \
313+ --preset=dev-mode \
314+ -DCMAKE_BUILD_TYPE=Debug \
315+ -DBUILD_GUI=OFF \
316+ -DBUILD_GUI_TESTS=OFF \
317+ -DWITH_ZMQ=OFF \
318+ -DWITH_USDT=OFF \
319+ -DBUILD_BENCH=OFF \
320+ -DBUILD_FUZZ_BINARY=OFF \
321+ -DWITH_QRENCODE=OFF \
322+ -DSANITIZERS=thread \
323+ -DAPPEND_CPPFLAGS='-DARENA_DEBUG -DDEBUG_LOCKCONTENTION -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES' \
324+ -DCMAKE_TOOLCHAIN_FILE=depends/${{ steps.host.outputs.host }}/toolchain.cmake \
325+ -G Ninja
326+
327+ - name : Build
328+ run : cmake --build build "-j$(nproc)"
329+
330+ - name : Run IPC and miner unit tests
331+ run : |
332+ ctest --test-dir build -R "ipc|miner_tests" --output-on-failure --timeout 480
333+
334+ - name : Run IPC functional tests
335+ run : |
336+ LD_LIBRARY_PATH="depends/${{ steps.host.outputs.host }}/lib" \
337+ build/test/functional/test_runner.py --filter interface_ipc --timeout-factor=8
338+
339+ - name : Save ccache
340+ uses : actions/cache/save@v4
341+ if : github.ref == 'refs/heads/master' || steps.ccache-restore.outputs.cache-hit != 'true'
342+ with :
343+ path : ${{ env.CCACHE_DIR }}
344+ key : ccache-TSan-${{ github.ref }}-${{ github.sha }}
0 commit comments