Skip to content

Commit bfccbd0

Browse files
Merge pull request #50 from chdb-io/fix/race-step-verdict
Judge the race step by what the detector found
2 parents b30d3b1 + 12cb828 commit bfccbd0

2 files changed

Lines changed: 71 additions & 2 deletions

File tree

‎.github/scripts/race-test.sh‎

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/bin/bash
2+
# The race detector's findings decide this step, not the exit status.
3+
#
4+
# libchdb starts process-global ClickHouse thread pools and offers no way to stop
5+
# them: the v26.7.0 C ABI has 50 functions and none of them shuts the engine down,
6+
# so ~33 engine threads are still parked on condvars when the test binary exits.
7+
# Under -race, Go's exit path runs racefini -> __tsan_fini, which tears the
8+
# sanitizer runtime down while those threads can still wake and run instrumented
9+
# code. One faults; because it is a C thread, Go's badsignal re-raises and the
10+
# process dies with a segfault after every test has already reported PASS.
11+
#
12+
# Established from a core dump: the crashing thread's stack is
13+
# runtime.raise <- raisebadsignal <- badsignal <- sigtrampgo, __tsan_fini and
14+
# __run_exit_handlers are on the stack, and 33 threads sit in
15+
# __pthread_cond_wait_common inside libchdb. Waiting before exit does not help —
16+
# measured 5/48, 3/48, 7/48, 3/48 crashes for waits of none, 500ms, 2s and 5s,
17+
# because BackgroundSchedulePool re-arms its tasks on a timer and never quiesces.
18+
#
19+
# So: run the race detector and fail on what it is for — a reported data race, a
20+
# failing test, a panic — and do not fail on that one segfault. Nothing about the
21+
# detector's coverage changes; only the way this step reads its own result.
22+
#
23+
# Remove this wrapper once the engine can be shut down (chdb-core needs either a
24+
# chdb_shutdown() for callers or an atexit that stops the pools). Then the plain
25+
# exit status is trustworthy again.
26+
set -uo pipefail
27+
28+
LOG=$(mktemp)
29+
go test -race -timeout=180s ./... 2>&1 | tee "$LOG"
30+
status=${PIPESTATUS[0]}
31+
32+
if grep -q "DATA RACE" "$LOG"; then
33+
echo "::error::the race detector reported a data race"
34+
exit 1
35+
fi
36+
if grep -qE "^--- FAIL|^\s+--- FAIL" "$LOG"; then
37+
echo "::error::a test failed under the race detector"
38+
exit 1
39+
fi
40+
if grep -qE "^panic:|^fatal error:" "$LOG"; then
41+
echo "::error::the test binary panicked under the race detector"
42+
exit 1
43+
fi
44+
45+
# A fault the Go runtime handled itself, i.e. one that hit a thread it owns while
46+
# a test was running. It prints its own header and a goroutine dump; the exit-time
47+
# crash never does, because there the signal lands on a libchdb thread and Go's
48+
# badsignal path re-raises without a dump. The distinction is what keeps the
49+
# exemption below from covering a crash during a test — a real one landed here
50+
# once already, chdb-io/chdb-go#46.
51+
if grep -qE "^(SIGSEGV|SIGBUS|SIGFPE|SIGILL|SIGABRT|SIGTRAP):" "$LOG"; then
52+
echo "::error::the runtime reported a fatal signal during a test, not at exit"
53+
exit 1
54+
fi
55+
56+
if [ "$status" -ne 0 ]; then
57+
# Positive evidence, not just the presence of the word: the package has to have
58+
# reported PASS and then died on the very next line. "Contains a segfault
59+
# somewhere" would exempt far more than the one crash this is about.
60+
if grep -A1 '^PASS$' "$LOG" | grep -q '^signal: segmentation fault'; then
61+
echo "::warning::tests passed; the binary segfaulted at exit, which is the" \
62+
"known libchdb thread-shutdown issue and not a test result"
63+
exit 0
64+
fi
65+
echo "::error::race step failed for a reason this wrapper does not recognise" \
66+
"(exit $status; no data race, failing test, panic, or in-test signal, and" \
67+
"no PASS immediately followed by a segfault)"
68+
exit "$status"
69+
fi

‎.github/workflows/chdb.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
- name: Test
3030
run: make test
3131
- name: Test with race detector
32-
run: go test -race -timeout=180s ./...
32+
run: ./.github/scripts/race-test.sh
3333
- name: Test main
3434
run: ./chdb-go "SELECT 12345"
3535

@@ -51,7 +51,7 @@ jobs:
5151
- name: Test
5252
run: make test
5353
- name: Test with race detector
54-
run: go test -race -timeout=180s ./...
54+
run: ./.github/scripts/race-test.sh
5555
- name: Test main
5656
run: ./chdb-go "SELECT 12345"
5757

0 commit comments

Comments
 (0)