Skip to content

Commit 08e8449

Browse files
committed
Merge bitcoin#34952: Update libmultiprocess subtree in 31.x branch to fix race conditions on disconnects
2478a15 Squashed 'src/ipc/libmultiprocess/' changes from 1868a84451f..70f632bda8f (Ryan Ofsky) Pull request description: This PR is a backport of bitcoin#34804 to the 31.x branch. (Both PR's point to the same source branch, they just have different target branches.) Some previous discussion about whether these changes should be merged into 31.x happened in bitcoin-core/libmultiprocess#249 (comment). The changes fix some IPC crashes that can happen with broken clients and unlucky thread timing that have only been seen in tests and antithesis runs, but the fixes are fairly simple and seem unlikely to cause new problems. The other changes in the PR are mostly CI/documentation/test changes and should also be safe. Includes: - bitcoin-core/libmultiprocess#246 - bitcoin-core/libmultiprocess#242 - bitcoin-core/libmultiprocess#247 - bitcoin-core/libmultiprocess#251 - bitcoin-core/libmultiprocess#255 - bitcoin-core/libmultiprocess#258 - bitcoin-core/libmultiprocess#262 - bitcoin-core/libmultiprocess#253 - bitcoin-core/libmultiprocess#263 - bitcoin-core/libmultiprocess#256 - bitcoin-core/libmultiprocess#264 - bitcoin-core/libmultiprocess#249 - bitcoin-core/libmultiprocess#265 The main change is bitcoin-core/libmultiprocess#249 which fixes 3 intermittent race conditions detected in bitcoin core CI and antithesis: bitcoin#34711/bitcoin#34756, bitcoin#34777, and bitcoin#34782. The changes can be verified by running `test/lint/git-subtree-check.sh src/ipc/libmultiprocess` as described in [developer notes](https://github.com/bitcoin/bitcoin/blob/master/doc/developer-notes.md#subtrees) and [lint instructions](https://github.com/bitcoin/bitcoin/tree/master/test/lint#git-subtree-checksh) ACKs for top commit: Sjors: ACK 85c016b Tree-SHA512: 54358428dc5a9cea84c3e816136ab828e702fc04b5af03cfd81c60522f1de491bf4867aed2e6c6791da2725dff2004b398ebbf42dd882cc22a5912bc5945cb6e
2 parents b212378 + 85c016b commit 08e8449

28 files changed

Lines changed: 1049 additions & 167 deletions
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
# Copyright (c) The Bitcoin Core developers
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or https://opensource.org/license/mit.
4+
5+
# Test libmultiprocess inside Bitcoin Core by replacing the subtree copy
6+
# with the version from this PR, then building and running IPC-related
7+
# unit & functional tests.
8+
9+
name: Bitcoin Core CI
10+
11+
on:
12+
push:
13+
pull_request:
14+
15+
concurrency:
16+
group: ${{ github.workflow }}-${{ github.ref }}
17+
cancel-in-progress: true
18+
19+
env:
20+
BITCOIN_REPO: bitcoin/bitcoin
21+
LLVM_VERSION: 22
22+
LIBCXX_DIR: /tmp/libcxx-build/
23+
24+
jobs:
25+
bitcoin-core:
26+
name: ${{ matrix.name }}
27+
runs-on: ${{ matrix.runner }}
28+
timeout-minutes: 120
29+
30+
strategy:
31+
fail-fast: false
32+
matrix:
33+
include:
34+
- name: 'ASan + UBSan'
35+
unit_test_runs: 15
36+
functional_test_runs: 20
37+
nproc_multiplier: 2
38+
functional_timeout_factor: 40
39+
runner: ubuntu-24.04
40+
apt-llvm: true
41+
packages: >-
42+
ccache
43+
clang-22
44+
llvm-22
45+
libclang-rt-22-dev
46+
libevent-dev
47+
libboost-dev
48+
libsqlite3-dev
49+
libcapnp-dev
50+
capnproto
51+
ninja-build
52+
pkgconf
53+
python3-pip
54+
pip-packages: --break-system-packages pycapnp
55+
cmake-args: |-
56+
-DSANITIZERS=address,float-divide-by-zero,integer,undefined
57+
-DCMAKE_C_COMPILER=clang
58+
-DCMAKE_CXX_COMPILER=clang++
59+
-DCMAKE_C_FLAGS=-ftrivial-auto-var-init=pattern
60+
-DCMAKE_CXX_FLAGS=-ftrivial-auto-var-init=pattern
61+
62+
- name: 'macOS'
63+
unit_test_runs: 50
64+
functional_test_runs: 20
65+
nproc_multiplier: 2
66+
functional_timeout_factor: 40
67+
runner: macos-15
68+
brew-packages: ccache capnp boost libevent sqlite pkgconf ninja
69+
pip-packages: --break-system-packages pycapnp
70+
cmake-args: |-
71+
-DREDUCE_EXPORTS=ON
72+
73+
env:
74+
CCACHE_MAXSIZE: 400M
75+
CCACHE_DIR: ${{ github.workspace }}/.ccache
76+
77+
steps:
78+
- name: Checkout Bitcoin Core
79+
uses: actions/checkout@v4
80+
with:
81+
repository: ${{ env.BITCOIN_REPO }}
82+
fetch-depth: 1
83+
84+
- name: Checkout libmultiprocess
85+
uses: actions/checkout@v4
86+
with:
87+
path: _libmultiprocess
88+
89+
- name: Replace libmultiprocess subtree
90+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh replace_subtree
91+
92+
- name: Add LLVM apt repository
93+
if: matrix.apt-llvm
94+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh add_llvm_apt_repository
95+
96+
- name: Install APT packages
97+
if: matrix.packages
98+
run: _libmultiprocess/ci/scripts/ci_helpers.sh install_apt_packages ${{ matrix.packages }}
99+
100+
- name: Configure LLVM alternatives
101+
if: matrix.packages
102+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh install_llvm_alternatives
103+
104+
- name: Install Homebrew packages
105+
if: matrix.brew-packages
106+
run: _libmultiprocess/ci/scripts/ci_helpers.sh install_homebrew_packages ${{ matrix.brew-packages }}
107+
108+
- name: Install pip packages
109+
if: matrix.pip-packages
110+
run: _libmultiprocess/ci/scripts/ci_helpers.sh install_pip_packages ${{ matrix.pip-packages }}
111+
112+
- name: Determine parallelism
113+
run: _libmultiprocess/ci/scripts/ci_helpers.sh determine_parallelism "${{ matrix.nproc_multiplier }}"
114+
115+
- name: Restore ccache
116+
id: ccache-restore
117+
uses: actions/cache/restore@v4
118+
with:
119+
path: ${{ env.CCACHE_DIR }}
120+
key: ccache-${{ matrix.name }}-${{ github.ref }}-${{ github.sha }}
121+
restore-keys: |
122+
ccache-${{ matrix.name }}-${{ github.ref }}-
123+
ccache-${{ matrix.name }}-
124+
125+
- name: Reset ccache stats
126+
if: matrix.packages || matrix.brew-packages
127+
run: _libmultiprocess/ci/scripts/ci_helpers.sh reset_ccache_stats
128+
129+
- name: CMake configure
130+
env:
131+
BITCOIN_CORE_CMAKE_ARGS: ${{ matrix.cmake-args }}
132+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh configure_bitcoin_core
133+
134+
- name: Build
135+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_bitcoin_core
136+
137+
- name: Show ccache stats
138+
if: matrix.packages || matrix.brew-packages
139+
run: _libmultiprocess/ci/scripts/ci_helpers.sh show_ccache_stats
140+
141+
- name: Run IPC unit tests
142+
env:
143+
ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
144+
LSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/lsan
145+
UBSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1
146+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_unit_tests "${{ matrix.unit_test_runs }}"
147+
148+
- name: Run IPC functional tests
149+
env:
150+
ASAN_OPTIONS: detect_leaks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1
151+
LSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/lsan
152+
UBSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1
153+
CI_FAILFAST_TEST_LEAVE_DANGLING: 1
154+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_functional_tests "${{ matrix.functional_test_runs }}" "${{ matrix.functional_timeout_factor }}"
155+
156+
- name: Save ccache
157+
uses: actions/cache/save@v4
158+
if: github.ref == 'refs/heads/master' || steps.ccache-restore.outputs.cache-hit != 'true'
159+
with:
160+
path: ${{ env.CCACHE_DIR }}
161+
key: ccache-${{ matrix.name }}-${{ github.ref }}-${{ github.sha }}
162+
163+
bitcoin-core-tsan:
164+
name: ${{ matrix.name }}
165+
runs-on: ubuntu-24.04
166+
timeout-minutes: 180
167+
168+
strategy:
169+
matrix:
170+
include:
171+
- name: TSan
172+
unit_test_runs: 8
173+
functional_test_runs: 25
174+
nproc_multiplier: 2
175+
functional_timeout_factor: 40
176+
177+
env:
178+
CCACHE_MAXSIZE: 400M
179+
CCACHE_DIR: ${{ github.workspace }}/.ccache
180+
LIBCXX_FLAGS: >-
181+
-fsanitize=thread
182+
-nostdinc++
183+
-nostdlib++
184+
-isystem /tmp/libcxx-build/include/c++/v1
185+
-L/tmp/libcxx-build/lib
186+
-Wl,-rpath,/tmp/libcxx-build/lib
187+
-lc++
188+
-lc++abi
189+
-lpthread
190+
-Wno-unused-command-line-argument
191+
TSAN_OPTIONS: suppressions=${{ github.workspace }}/test/sanitizer_suppressions/tsan:halt_on_error=1:second_deadlock_stack=1
192+
193+
steps:
194+
- name: Checkout Bitcoin Core
195+
uses: actions/checkout@v4
196+
with:
197+
repository: ${{ env.BITCOIN_REPO }}
198+
fetch-depth: 1
199+
200+
- name: Checkout libmultiprocess
201+
uses: actions/checkout@v4
202+
with:
203+
path: _libmultiprocess
204+
205+
- name: Add LLVM apt repository
206+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh add_llvm_apt_repository
207+
208+
- name: Install packages
209+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh install_tsan_packages
210+
211+
- name: Determine parallelism
212+
run: _libmultiprocess/ci/scripts/ci_helpers.sh determine_parallelism "${{ matrix.nproc_multiplier }}"
213+
214+
- name: Restore instrumented libc++ cache
215+
id: libcxx-cache
216+
uses: actions/cache@v4
217+
with:
218+
path: ${{ env.LIBCXX_DIR }}
219+
key: libcxx-Thread-llvmorg-${{ env.LLVM_VERSION }}.1.0
220+
221+
- name: Build instrumented libc++
222+
if: steps.libcxx-cache.outputs.cache-hit != 'true'
223+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_instrumented_libcxx
224+
225+
- name: Determine host
226+
id: host
227+
run: _libmultiprocess/ci/scripts/ci_helpers.sh determine_host
228+
229+
- name: Restore depends cache
230+
id: depends-cache
231+
uses: actions/cache/restore@v4
232+
with:
233+
path: |
234+
depends/built
235+
depends/${{ steps.host.outputs.host }}
236+
key: depends-tsan-${{ hashFiles('depends/packages/*.mk') }}-${{ env.LLVM_VERSION }}
237+
238+
- name: Build depends (stage 1, without IPC)
239+
if: steps.depends-cache.outputs.cache-hit != 'true'
240+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_depends_without_ipc
241+
242+
- name: Save depends cache
243+
uses: actions/cache/save@v4
244+
if: steps.depends-cache.outputs.cache-hit != 'true'
245+
with:
246+
path: |
247+
depends/built
248+
depends/${{ steps.host.outputs.host }}
249+
key: depends-tsan-${{ hashFiles('depends/packages/*.mk') }}-${{ env.LLVM_VERSION }}
250+
251+
- name: Replace libmultiprocess subtree
252+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh replace_subtree
253+
254+
- name: Build depends (stage 2, IPC packages including libmultiprocess)
255+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_depends_with_ipc
256+
257+
- name: Restore ccache
258+
id: ccache-restore
259+
uses: actions/cache/restore@v4
260+
with:
261+
path: ${{ env.CCACHE_DIR }}
262+
key: ccache-TSan-${{ github.ref }}-${{ github.sha }}
263+
restore-keys: |
264+
ccache-TSan-${{ github.ref }}-
265+
ccache-TSan-
266+
267+
- name: Reset ccache stats
268+
run: _libmultiprocess/ci/scripts/ci_helpers.sh reset_ccache_stats
269+
270+
- name: CMake configure
271+
env:
272+
BITCOIN_CORE_CMAKE_ARGS: |-
273+
-DSANITIZERS=thread
274+
-DAPPEND_CPPFLAGS=-DARENA_DEBUG -DDEBUG_LOCKCONTENTION -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES
275+
-DCMAKE_TOOLCHAIN_FILE=depends/${{ steps.host.outputs.host }}/toolchain.cmake
276+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh configure_bitcoin_core
277+
278+
- name: Build
279+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh build_bitcoin_core
280+
281+
- name: Show ccache stats
282+
run: _libmultiprocess/ci/scripts/ci_helpers.sh show_ccache_stats
283+
284+
- name: Run IPC unit tests
285+
env:
286+
LD_LIBRARY_PATH: depends/${{ steps.host.outputs.host }}/lib
287+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_unit_tests "${{ matrix.unit_test_runs }}"
288+
289+
- name: Run IPC functional tests
290+
env:
291+
LD_LIBRARY_PATH: depends/${{ steps.host.outputs.host }}/lib
292+
CI_FAILFAST_TEST_LEAVE_DANGLING: 1
293+
run: _libmultiprocess/ci/scripts/bitcoin_core_ci.sh run_ipc_functional_tests "${{ matrix.functional_test_runs }}" "${{ matrix.functional_timeout_factor }}"
294+
295+
- name: Save ccache
296+
uses: actions/cache/save@v4
297+
if: github.ref == 'refs/heads/master' || steps.ccache-restore.outputs.cache-hit != 'true'
298+
with:
299+
path: ${{ env.CCACHE_DIR }}
300+
key: ccache-TSan-${{ github.ref }}-${{ github.sha }}

src/ipc/libmultiprocess/.github/workflows/ci.yml

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,21 @@ jobs:
120120
env:
121121
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
122122
run: |
123-
brew install --quiet ninja capnp
123+
brew install --quiet ninja capnp llvm
124124
125125
- name: Run CI script
126126
run: |
127+
export PATH="$(brew --prefix llvm)/bin:$PATH"
127128
CI_CONFIG="ci/configs/macos.bash" bash ci/scripts/ci.sh
128129
129130
build:
130131
runs-on: ubuntu-latest
131132

132133
env:
134+
NIXPKGS_CHANNEL: nixos-25.05
135+
NIX_EXTRA_CONFIG: |
136+
keep-env-derivations = true
137+
keep-outputs = true
133138
NIX_EXTRA_CONFIG_ACT: |
134139
sandbox = false
135140
filter-syscalls = false
@@ -144,14 +149,33 @@ jobs:
144149
steps:
145150
- uses: actions/checkout@v5
146151

152+
- name: Determine CI configuration
153+
id: config
154+
env:
155+
CI_CONFIG: ci/configs/${{ matrix.config }}.bash
156+
run: ci/scripts/config.sh
157+
147158
- name: Install Nix
148159
uses: cachix/install-nix-action@v31 # 2025-05-27, from https://github.com/cachix/install-nix-action/tags
149160
with:
150-
nix_path: nixpkgs=channel:nixos-25.05 # latest release
161+
nix_path: nixpkgs=https://github.com/NixOS/nixpkgs/archive/${{ steps.config.outputs.nixpkgs_rev }}.tar.gz
151162
# Act executes inside an unprivileged container (Docker or Podman),
152163
# so KVM support isn't available.
153164
enable_kvm: "${{ github.actor != 'nektos/act' }}"
154-
extra_nix_config: ${{ github.actor == 'nektos/act' && env.NIX_EXTRA_CONFIG_ACT || '' }}
165+
extra_nix_config: |
166+
${{ env.NIX_EXTRA_CONFIG }}
167+
${{ github.actor == 'nektos/act' && env.NIX_EXTRA_CONFIG_ACT || '' }}
168+
169+
- name: Cache Nix store
170+
if: steps.config.outputs.cache_nix_store == 'true'
171+
uses: nix-community/cache-nix-action@v7
172+
with:
173+
primary-key: nix-${{ runner.os }}-${{ matrix.config }}-${{ steps.config.outputs.nixpkgs_rev }}-${{ hashFiles('shell.nix', 'ci/patches/*.patch', format('ci/configs/{0}.bash', matrix.config)) }}
174+
restore-prefixes-first-match: |
175+
nix-${{ runner.os }}-${{ matrix.config }}-${{ steps.config.outputs.nixpkgs_rev }}-
176+
nix-${{ runner.os }}-${{ matrix.config }}-
177+
nix-${{ runner.os }}-
178+
gc-max-store-size-linux: 10G
155179

156180
- name: Run CI script
157181
env:

src/ipc/libmultiprocess/ci/configs/gnu32.bash

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
CI_DESC="CI job cross-compiling to 32-bit"
22
CI_DIR=build-gnu32
3+
# Cache the heaviest Nix job to stay within GitHub's cache budget.
4+
CI_CACHE_NIX_STORE=true
35
NIX_ARGS=(
46
--arg minimal true
57
--arg crossPkgs 'import <nixpkgs> { crossSystem = { config = "i686-unknown-linux-gnu"; }; }'
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
CI_DESC="CI config for macOS"
22
CI_DIR=build-macos
33
export CXXFLAGS="-Werror -Wall -Wextra -Wpedantic -Wno-unused-parameter"
4-
CMAKE_ARGS=(-G Ninja)
4+
CMAKE_ARGS=(-G Ninja -DMP_ENABLE_CLANG_TIDY=ON)
55
BUILD_ARGS=(-k 0)

0 commit comments

Comments
 (0)