Skip LSan leak check in 02435_rollback_cancelled_queries#105474
Skip LSan leak check in 02435_rollback_cancelled_queries#105474groeneai wants to merge 5 commits into
Conversation
The test intentionally SIGKILLs the spawned `clickhouse-client` mid-INSERT to exercise transaction rollback under query cancellation. When LSan's at-exit leak check is enabled (e.g. `arm_asan_ubsan` runner), it forks a ptrace tracer for stop-the-world. On runners where `ptrace` is sandboxed by seccomp the tracer cannot attach, falls back to `SIGRTMIN+2`, and prints `ptrace appears to be blocked ... Child exited with signal 36` to stderr. The CI framework's `stderr-fatal` watch then fails the test even though stdout is correct (`1000000`, `0`). Set `LSAN_OPTIONS=detect_leaks=0` at the top of the test so the spawned clients skip the at-exit leak scan. Doing leak detection on a process we are killing on purpose is not useful. Tracking issue: rschu1ze directive on ClickHouse#104648 (one of three chronic flaky tests). The other two (`01563_distributed_query_finish` and `02345_implicit_transaction`) are addressed elsewhere; see PR body.
|
cc @rschu1ze (you asked for this in #104648) and @Algunenano (sibling PR #105457 for 01563 in the same bundle) — could you review? It is a one-line test-only fix to skip LSan's at-exit leak scan in a test that intentionally SIGKILLs the spawned client mid-INSERT, which on the targeted arm_asan_ubsan runner trips the seccomp |
|
Workflow [PR], commit [c22aca1] Summary: ✅ AI ReviewSummaryThis PR narrows the Final Verdict
|
|
What is "ptrace tracer for stop-the-world" and how can it detect KILL? |
|
1. What is "ptrace tracer for stop-the-world"? At process exit, the LSan runtime forks a helper child. The child calls 2. How can it detect KILL? It cannot, and the fix is not aimed at the SIGKILLed client. That process is reaped by the kernel instantly, its at-exit handler never runs, so LSan never spins up on it. The spurious failure is on the OTHER client subprocesses the test spawns: the post-kill verification queries ( So the description's "is racy here" wording is misleading. The LSan output we silence comes from cleanly-exiting verification clients, not from the killed one. |
Reflect the clarification from the PR thread: the spurious stderr comes from the cleanly-exiting verification clients running at-exit DoLeakCheck, not from the SIGKILLed insert client whose at-exit handler never runs.
|
@groeneai Are you sure we use seccomp in the CI? I don't remember that. |
|
And even if we do, how then is LSan supposed to work in other tests? |
|
@alexey-milovidov fair pushback, more careful answer: On "seccomp". It was my best guess from LSan's own diagnostic text. Source path: int pid = internal_fork();
if (pid == 0) {
internal_ptrace(PTRACE_ATTACH, 0, nullptr, nullptr);
internal__exit(0);
} else {
internal_waitpid(pid, &wstatus, 0);
if (WIFSIGNALED(wstatus)) {
VReport(0, "WARNING: ptrace appears to be blocked (is seccomp enabled?). LeakSanitizer may hang.\n");
VReport(0, "Child exited with signal %d.\n", WTERMSIG(wstatus));
}
}The message fires whenever the fork is signal-killed during the On "how does LSan work in other tests". CIDB hits for this exact warning across all CI over the last 30 days: That is the full list. The runner did ~11.9M test invocations across 7,133 distinct tests in the same window, all ASan+LSan. So whatever the runner does to ptrace surfaces only through this one test. The 02435-specific route through There is also a mechanical wrinkle. The warning lands in The |
The earlier comment attributed the LSan "ptrace appears to be blocked
(is seccomp enabled?)" stderr warning to a seccomp sandbox on the
arm_asan_ubsan runner. As discussed on the PR, that was a wrong guess:
LSan prints that text whenever its ptrace probe fork is signal-killed
during the PTRACE_ATTACH syscall, and the message bakes in the seccomp
hypothesis regardless of the real cause.
CIDB shows the warning fires for this one test only, out of ~7000 tests
on the same LSan-enabled runner, so a global ptrace/seccomp block is
ruled out. The actual mechanism is self-inflicted by the test:
- LSan's at-exit leak scan (sanitizer_stoptheworld_linux_libcdep.cpp,
TestPTrace) forks a probe child that internal_fork()s from the
clickhouse-client and therefore inherits the client's argv. Its
/proc/<pid>/cmdline still contains $TEST_MARK.
- thread_cancel greps /proc/*/cmdline for $TEST_MARK and sends
INT/KILL to every match, so it can hit the probe fork mid-ptrace.
- The signal-killed probe makes LSan print the warning to the
per-PID ASAN_OPTIONS log_path file, which clickhouse-test reports
as a fatal stderr and fails the run.
The fix (LSAN_OPTIONS=detect_leaks=0) is unchanged and already
approved; this only rewrites the comment to match the real cause so it
does not mislead the next reader. The test does not check for leaks.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Pushed 2bdf4bd: the code comment and PR description now state the real cause instead of the seccomp guess. As established above, this test is the only one of ~7000 on the LSan-enabled runner that hits the warning, so it is not a global ptrace block. The mechanism is self-inflicted: LSan's |
…lsan-ptrace-spurious-stderr
|
Updated the branch to current The fix is not redundant after The reds on the previous commit Answers to the earlier questions are in the thread above: the "seccomp" wording was retracted, and the real cause (the test signalling its own inherited- |
Only the clients started in thread_insert carry $TEST_MARK in their argv and run while thread_cancel kills every /proc/*/cmdline match, so only they can hit the inherited-argv ptrace probe race that produces the spurious "ptrace appears to be blocked" stderr. The setup queries, thread_select clients and the post-wait verification clients never match that kill loop, so scoping the export to thread_insert keeps full LSan coverage on them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pre-PR validation gate (click to expand)
Session id: cron:clickhouse-worker-slot-1:20260702-233600 |
LLVM Coverage Report
Changed lines: No C/C++ source files changed — skipping uncovered code analysis. Newly covered by added/modified tests: 115 line(s), 6 function(s) across 42 file(s) · Details Top files
|
CI finish ledger — c22aca1Every failure below has an owner: a fixing PR (ours or external), or a full-effort fix task whose fixing-PR link will be posted here when it opens. Only Session id: cron:our-pr-ci-monitor:20260703-033000 |

Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
Fix spurious
Stateless tests (arm_asan_ubsan, targeted)failures of02435_rollback_cancelled_queriescaused by LeakSanitizer at-exitptracewarnings.Description
02435_rollback_cancelled_queriesintermittently fails theStateless tests (arm_asan_ubsan, targeted)50x flaky runner with a fatal-looking stderr line even though stdout is correct (1000000,0):The "is seccomp enabled?" text is LSan's own guess and is misleading here. CIDB shows the warning fires for this one test only out of ~7000 tests on the same LSan-enabled runner, so a global ptrace/seccomp block is ruled out. The cause is self-inflicted by the test:
sanitizer_stoptheworld_linux_libcdep.cpp,TestPTrace) forks a probe child thatinternal_fork()s fromclickhouse-clientand inherits itsargv, so the probe's/proc/<pid>/cmdlinestill contains$TEST_MARK.thread_cancelgreps/proc/*/cmdlinefor$TEST_MARKand sendsINT/KILLto every match, so it can hit the probe fork mid-ptrace.ASAN_OPTIONS log_pathfile, whichclickhouse-testreports as a fatal stderr and fails the run.Setting
LSAN_OPTIONS=detect_leaks=0at the top of the test skips the at-exit scan. The test exercises INSERT cancellation and transaction rollback, not leak detection, so this does not weaken what the test checks.This is the second of three chronic flaky tests requested in #104648 .
01563_distributed_query_finishis addressed in #105457 ;02345_implicit_transaction(Timeout exceeded while flushing system log) needs a server-side change and will land separately.