Skip to content

Commit cefd25e

Browse files
Merge #7047: ci: run multiprocess / tsan on arm runners
ecbce32 fix: resolve quotes (pasta) 72b77f3 ci: fix check-cache job to run on correct runner architecture (pasta) 7ef6f3d chore: move suppressions to "external libraries" (pasta) 64d5fb4 test: add comprehensive TSAN suppression for BDB pthread mutex (pasta) 1fa7b64 test: add TSAN deadlock suppression for DatabaseBatch (pasta) 550e588 test: add TSAN deadlock suppression for BerkeleyBatch (pasta) 6b0ed8b ci: run multiprocess job exclusively on ARM runners (pasta) 6afb8aa ci: enable multi-arch Docker image builds for x86 and ARM (pasta) Pull request description: ## Issue being fixed or feature implemented run long running tsan / multiprocess builds on arm ## What was done? before tsan took 11:09 https://github.com/dashpay/dash/actions/runs/19945280778/job/57193769222 after tsan took 9:52 https://github.com/PastaPastaPasta/dash/actions/runs/19967178415/job/57305624043 before multiprocess took 48:45 https://github.com/dashpay/dash/actions/runs/19945280778/job/57193769225 after multiprocess took 42:04 https://github.com/PastaPastaPasta/dash/actions/runs/19967178415/job/57305624116 (still waiting on the functional test runs, I expect these to also improve, but not sure) ## How Has This Been Tested? CI looks ~ good here: https://github.com/PastaPastaPasta/dash/actions/runs/19967178415/job/57305624118 ## Breaking Changes ## Checklist: _Go over all the following points, and put an `x` in all the boxes that apply._ - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: UdjinM6: utACK ecbce32 Tree-SHA512: 065ea0217cb92dfc49e863a8359110cbd7f4b1c13c50db29c25a3b6c2d2472159b7b008b109d089999d108fe6c5fa15f83edcb4cd974b8be05b19ca80ee2e02a
2 parents e02e0f3 + ecbce32 commit cefd25e

File tree

9 files changed

+174
-18
lines changed

9 files changed

+174
-18
lines changed

.github/workflows/build-container.yml

Lines changed: 93 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,16 @@ on:
1818
outputs:
1919
path:
2020
description: "Path to built container"
21-
value: ghcr.io/${{ jobs.build.outputs.repo }}/${{ inputs.name }}:${{ jobs.build.outputs.tag }}
21+
value: ghcr.io/${{ jobs.build-amd64.outputs.repo }}/${{ inputs.name }}:${{ jobs.build-amd64.outputs.tag }}
2222

2323
jobs:
24-
build:
25-
name: Build container
24+
build-amd64:
25+
name: Build container (amd64)
2626
runs-on: ubuntu-24.04
2727
outputs:
2828
tag: ${{ steps.prepare.outputs.tag }}
2929
repo: ${{ steps.prepare.outputs.repo }}
30+
digest: ${{ steps.build.outputs.digest }}
3031
steps:
3132
- name: Checkout code
3233
uses: actions/checkout@v4
@@ -38,8 +39,8 @@ jobs:
3839
run: |
3940
BRANCH_NAME=$(echo "${GITHUB_REF##*/}" | tr '[:upper:]' '[:lower:]')
4041
REPO_NAME=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
41-
echo "tag=${BRANCH_NAME}" >> $GITHUB_OUTPUT
42-
echo "repo=${REPO_NAME}" >> $GITHUB_OUTPUT
42+
echo "tag=${BRANCH_NAME}" >> "$GITHUB_OUTPUT"
43+
echo "repo=${REPO_NAME}" >> "$GITHUB_OUTPUT"
4344
4445
- name: Set up Docker Buildx
4546
uses: docker/setup-buildx-action@v3
@@ -52,17 +53,99 @@ jobs:
5253
password: ${{ secrets.GITHUB_TOKEN }}
5354

5455
- name: Build and push Docker image
56+
id: build
5557
uses: docker/build-push-action@v6
5658
with:
5759
context: ${{ inputs.context }}
5860
file: ${{ inputs.file }}
5961
push: true
62+
platforms: linux/amd64
6063
tags: |
61-
ghcr.io/${{ steps.prepare.outputs.repo }}/${{ inputs.name }}:${{ hashFiles(inputs.file) }}
62-
ghcr.io/${{ steps.prepare.outputs.repo }}/${{ inputs.name }}:${{ steps.prepare.outputs.tag }}
63-
ghcr.io/${{ steps.prepare.outputs.repo }}/${{ inputs.name }}:latest
64+
ghcr.io/${{ steps.prepare.outputs.repo }}/${{ inputs.name }}:${{ hashFiles(inputs.file) }}-amd64
6465
cache-from: |
65-
type=registry,ref=ghcr.io/${{ steps.prepare.outputs.repo }}/${{ inputs.name }}:${{ hashFiles(inputs.file) }}
66+
type=registry,ref=ghcr.io/${{ steps.prepare.outputs.repo }}/${{ inputs.name }}:${{ hashFiles(inputs.file) }}-amd64
6667
type=registry,ref=ghcr.io/${{ steps.prepare.outputs.repo }}/${{ inputs.name }}:${{ steps.prepare.outputs.tag }}
67-
type=registry,ref=ghcr.io/${{ steps.prepare.outputs.repo }}/${{ inputs.name }}:latest
6868
cache-to: type=inline
69+
70+
build-arm64:
71+
name: Build container (arm64)
72+
runs-on: ubuntu-24.04-arm
73+
outputs:
74+
digest: ${{ steps.build.outputs.digest }}
75+
steps:
76+
- name: Checkout code
77+
uses: actions/checkout@v4
78+
with:
79+
ref: ${{ github.event.pull_request.head.sha }}
80+
81+
- name: Prepare variables
82+
id: prepare
83+
run: |
84+
BRANCH_NAME=$(echo "${GITHUB_REF##*/}" | tr '[:upper:]' '[:lower:]')
85+
REPO_NAME=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
86+
echo "tag=${BRANCH_NAME}" >> "$GITHUB_OUTPUT"
87+
echo "repo=${REPO_NAME}" >> "$GITHUB_OUTPUT"
88+
89+
- name: Set up Docker Buildx
90+
uses: docker/setup-buildx-action@v3
91+
92+
- name: Login to GitHub Container Registry
93+
uses: docker/login-action@v3
94+
with:
95+
registry: ghcr.io
96+
username: ${{ github.actor }}
97+
password: ${{ secrets.GITHUB_TOKEN }}
98+
99+
- name: Build and push Docker image
100+
id: build
101+
uses: docker/build-push-action@v6
102+
with:
103+
context: ${{ inputs.context }}
104+
file: ${{ inputs.file }}
105+
push: true
106+
platforms: linux/arm64
107+
tags: |
108+
ghcr.io/${{ steps.prepare.outputs.repo }}/${{ inputs.name }}:${{ hashFiles(inputs.file) }}-arm64
109+
cache-from: |
110+
type=registry,ref=ghcr.io/${{ steps.prepare.outputs.repo }}/${{ inputs.name }}:${{ hashFiles(inputs.file) }}-arm64
111+
type=registry,ref=ghcr.io/${{ steps.prepare.outputs.repo }}/${{ inputs.name }}:${{ steps.prepare.outputs.tag }}
112+
cache-to: type=inline
113+
114+
create-manifest:
115+
name: Create multi-arch manifest
116+
runs-on: ubuntu-24.04-arm
117+
needs: [build-amd64, build-arm64]
118+
steps:
119+
- name: Checkout code
120+
uses: actions/checkout@v4
121+
with:
122+
ref: ${{ github.event.pull_request.head.sha }}
123+
124+
- name: Set up Docker Buildx
125+
uses: docker/setup-buildx-action@v3
126+
127+
- name: Login to GitHub Container Registry
128+
uses: docker/login-action@v3
129+
with:
130+
registry: ghcr.io
131+
username: ${{ github.actor }}
132+
password: ${{ secrets.GITHUB_TOKEN }}
133+
134+
- name: Create and push multi-arch manifest
135+
run: |
136+
REPO="ghcr.io/${{ needs.build-amd64.outputs.repo }}/${{ inputs.name }}"
137+
TAG="${{ needs.build-amd64.outputs.tag }}"
138+
HASH_TAG="${{ hashFiles(inputs.file) }}"
139+
140+
# Create manifest from arch-specific images
141+
docker buildx imagetools create -t "${REPO}:${HASH_TAG}" \
142+
"${REPO}:${HASH_TAG}-amd64" \
143+
"${REPO}:${HASH_TAG}-arm64"
144+
145+
docker buildx imagetools create -t "${REPO}:${TAG}" \
146+
"${REPO}:${HASH_TAG}-amd64" \
147+
"${REPO}:${HASH_TAG}-arm64"
148+
149+
docker buildx imagetools create -t "${REPO}:latest" \
150+
"${REPO}:${HASH_TAG}-amd64" \
151+
"${REPO}:${HASH_TAG}-arm64"

.github/workflows/build-depends.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ on:
1111
description: "Path to built container at registry"
1212
required: true
1313
type: string
14+
runs-on:
15+
description: "Runner label to use (e.g., ubuntu-24.04 or ubuntu-24.04-arm)"
16+
required: false
17+
default: ubuntu-24.04
18+
type: string
1419
outputs:
1520
key:
1621
description: "Key needed for restoring depends cache"
@@ -25,7 +30,7 @@ on:
2530
jobs:
2631
check-cache:
2732
name: Check cache
28-
runs-on: ubuntu-latest
33+
runs-on: ${{ inputs.runs-on }}
2934
outputs:
3035
cache-hit: ${{ steps.cache-check.outputs.cache-hit }}
3136
cache-key: ${{ steps.setup.outputs.cache-key }}
@@ -52,11 +57,12 @@ jobs:
5257
source ./ci/dash/matrix.sh
5358
echo "DEP_OPTS=${DEP_OPTS}" >> "${GITHUB_OUTPUT}"
5459
echo "HOST=${HOST}" >> "${GITHUB_OUTPUT}"
60+
echo "RUNNER_ARCH=$(uname -m)" >> "${GITHUB_OUTPUT}"
5561
DEP_HASH="$(echo -n "${BUILD_TARGET}" "${DEP_OPTS}" "${HOST}" | sha256sum | head -c 64)"
5662
echo "DEP_HASH=${DEP_HASH}" >> "${GITHUB_OUTPUT}"
5763
DOCKERFILE_HASH="${{ hashFiles('contrib/containers/ci/ci.Dockerfile', 'contrib/containers/ci/ci-slim.Dockerfile') }}"
5864
PACKAGES_HASH="${{ hashFiles('depends/packages/*', 'depends/Makefile') }}"
59-
CACHE_KEY="depends-${DOCKERFILE_HASH}-${{ inputs.build-target }}-${DEP_HASH}-${PACKAGES_HASH}"
65+
CACHE_KEY="depends-${DOCKERFILE_HASH}-${{ inputs.runs-on }}-${{ inputs.build-target }}-${DEP_HASH}-${PACKAGES_HASH}"
6066
echo "cache-key=${CACHE_KEY}" >> "${GITHUB_OUTPUT}"
6167
echo "Cache key: ${CACHE_KEY}"
6268
shell: bash
@@ -73,7 +79,7 @@ jobs:
7379
name: Build depends
7480
needs: [check-cache]
7581
if: needs.check-cache.outputs.cache-hit != 'true'
76-
runs-on: ubuntu-24.04
82+
runs-on: ${{ inputs.runs-on }}
7783
container:
7884
image: ${{ inputs.container-path }}
7985
options: --user root

.github/workflows/build-src.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ on:
2424
required: false
2525
type: string
2626
default: ""
27+
runs-on:
28+
description: "Runner label to use (e.g., ubuntu-24.04 or ubuntu-24.04-arm)"
29+
required: false
30+
default: ubuntu-24.04
31+
type: string
2732
outputs:
2833
key:
2934
description: "Key needed for restoring artifacts bundle"
@@ -32,7 +37,7 @@ on:
3237
jobs:
3338
build-src:
3439
name: Build source
35-
runs-on: ubuntu-24.04
40+
runs-on: ${{ inputs.runs-on }}
3641
outputs:
3742
key: ${{ steps.bundle.outputs.key }}
3843
container:

.github/workflows/build.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ jobs:
8686
container-path: ${{ needs.container.outputs.path }}
8787

8888
depends-linux64_multiprocess:
89-
name: x86_64-pc-linux-gnu_multiprocess
89+
name: linux64_multiprocess
9090
uses: ./.github/workflows/build-depends.yml
9191
needs: [container, cache-sources]
9292
if: |
@@ -95,6 +95,7 @@ jobs:
9595
with:
9696
build-target: linux64_multiprocess
9797
container-path: ${{ needs.container.outputs.path }}
98+
runs-on: ubuntu-24.04-arm
9899

99100
depends-linux64_nowallet:
100101
name: x86_64-pc-linux-gnu_nowallet
@@ -176,6 +177,7 @@ jobs:
176177
depends-key: ${{ needs.depends-linux64_multiprocess.outputs.key }}
177178
depends-host: ${{ needs.depends-linux64_multiprocess.outputs.host }}
178179
depends-dep-opts: ${{ needs.depends-linux64_multiprocess.outputs.dep-opts }}
180+
runs-on: ubuntu-24.04-arm
179181

180182
src-linux64_nowallet:
181183
name: linux64_nowallet-build
@@ -211,6 +213,7 @@ jobs:
211213
depends-key: ${{ needs.depends-linux64_multiprocess.outputs.key }}
212214
depends-host: ${{ needs.depends-linux64_multiprocess.outputs.host }}
213215
depends-dep-opts: ${{ needs.depends-linux64_multiprocess.outputs.dep-opts }}
216+
runs-on: ubuntu-24.04-arm
214217

215218
src-linux64_ubsan:
216219
name: linux64_ubsan-build
@@ -263,6 +266,7 @@ jobs:
263266
bundle-key: ${{ needs.src-linux64_multiprocess.outputs.key }}
264267
build-target: linux64_multiprocess
265268
container-path: ${{ needs.container-slim.outputs.path }}
269+
runs-on: ubuntu-24.04-arm
266270

267271
test-linux64_nowallet:
268272
name: linux64_nowallet-test
@@ -290,6 +294,7 @@ jobs:
290294
bundle-key: ${{ needs.src-linux64_tsan.outputs.key }}
291295
build-target: linux64_tsan
292296
container-path: ${{ needs.container-slim.outputs.path }}
297+
runs-on: ubuntu-24.04-arm
293298

294299
test-linux64_ubsan:
295300
name: linux64_ubsan-test

.github/workflows/test-src.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ on:
1515
description: "Path to built container at registry"
1616
required: true
1717
type: string
18+
runs-on:
19+
description: "Runner label to use (e.g., ubuntu-24.04 or ubuntu-24.04-arm)"
20+
required: false
21+
default: ubuntu-24.04
22+
type: string
1823

1924
env:
2025
INTEGRATION_TESTS_ARGS: "--extended --exclude feature_pruning,feature_dbcrash"
@@ -23,7 +28,7 @@ env:
2328
jobs:
2429
test-src:
2530
name: Test source
26-
runs-on: ubuntu-24.04
31+
runs-on: ${{ inputs.runs-on }}
2732
container:
2833
image: ${{ inputs.container-path }}
2934
options: --user root

ci/test/00_setup_env_native_multiprocess.sh

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,24 @@
77
export LC_ALL=C.UTF-8
88

99
export CONTAINER_NAME=ci_native_multiprocess
10-
export HOST=x86_64-pc-linux-gnu
10+
case "$(uname -m)" in
11+
aarch64)
12+
export HOST=aarch64-linux-gnu
13+
;;
14+
x86_64)
15+
export HOST=x86_64-pc-linux-gnu
16+
;;
17+
*)
18+
if command -v dpkg >/dev/null 2>&1; then
19+
arch="$(dpkg --print-architecture)"
20+
if [ "${arch}" = "arm64" ]; then
21+
export HOST=aarch64-linux-gnu
22+
elif [ "${arch}" = "amd64" ]; then
23+
export HOST=x86_64-pc-linux-gnu
24+
fi
25+
fi
26+
;;
27+
esac
1128
export PACKAGES="cmake python3 llvm clang"
1229
export DEP_OPTS="MULTIPROCESS=1 CC=clang-19 CXX=clang++-19"
1330
export RUN_TIDY=true

ci/test/00_setup_env_native_tsan.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,24 @@
77
export LC_ALL=C.UTF-8
88

99
export CONTAINER_NAME=ci_native_tsan
10+
case "$(uname -m)" in
11+
aarch64)
12+
export HOST=aarch64-linux-gnu
13+
;;
14+
x86_64)
15+
export HOST=x86_64-pc-linux-gnu
16+
;;
17+
*)
18+
if command -v dpkg >/dev/null 2>&1; then
19+
arch="$(dpkg --print-architecture)"
20+
if [ "${arch}" = "arm64" ]; then
21+
export HOST=aarch64-linux-gnu
22+
elif [ "${arch}" = "amd64" ]; then
23+
export HOST=x86_64-pc-linux-gnu
24+
fi
25+
fi
26+
;;
27+
esac
1028
export PACKAGES="clang-19 llvm-19 libclang-rt-19-dev libc++abi-19-dev libc++-19-dev python3-zmq"
1129
export DEP_OPTS="CC=clang-19 CXX='clang++-19 -stdlib=libc++'"
1230
export TEST_RUNNER_EXTRA="--extended --exclude feature_pruning,feature_dbcrash,wallet_multiwallet.py" # Temporarily suppress ASan heap-use-after-free (see issue #14163)

contrib/containers/ci/ci-slim.Dockerfile

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ RUN set -ex; \
1919

2020
# Main image
2121
FROM ubuntu:noble
22+
ARG TARGETARCH
2223

2324
# Include built assets
2425
COPY --from=cppcheck-builder /src/cppcheck/build/bin/cppcheck /usr/local/bin/cppcheck
@@ -107,7 +108,16 @@ RUN set -ex; \
107108

108109
ARG SHELLCHECK_VERSION=v0.8.0
109110
RUN set -ex; \
110-
curl -fL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" -o /tmp/shellcheck.tar.xz; \
111+
ARCH_INFERRED="${TARGETARCH}"; \
112+
if [ -z "${ARCH_INFERRED}" ]; then \
113+
ARCH_INFERRED="$(dpkg --print-architecture || true)"; \
114+
fi; \
115+
case "${ARCH_INFERRED}" in \
116+
amd64|x86_64) SC_ARCH="x86_64" ;; \
117+
arm64|aarch64) SC_ARCH="aarch64" ;; \
118+
*) echo "Unsupported architecture for ShellCheck: ${ARCH_INFERRED}"; exit 1 ;; \
119+
esac; \
120+
curl -fL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.${SC_ARCH}.tar.xz" -o /tmp/shellcheck.tar.xz; \
111121
mkdir -p /opt/shellcheck && tar -xf /tmp/shellcheck.tar.xz -C /opt/shellcheck --strip-components=1 && rm /tmp/shellcheck.tar.xz
112122
ENV PATH="/opt/shellcheck:${PATH}"
113123

test/sanitizer_suppressions/tsan

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ race:libzmq
4141
# Race in headers only Boost Test
4242
race:std::__1::ios_base::flags
4343

44+
# BerkeleyDB internal lock ordering - BDB uses its own locking protocol
45+
# with pthread rwlocks that TSAN cannot properly reason about
46+
deadlock:BerkeleyBatch
47+
deadlock:DatabaseBatch
48+
deadlock:__db_pthread_mutex
49+
50+
4451
# Intermittent issues
4552
# -------------------
4653
#

0 commit comments

Comments
 (0)