This is an automated email from the ASF dual-hosted git repository.
bneradt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 8aebe2c706 Fix intermittent cache unit test segfault in Fedora CI
(#13527)
8aebe2c706 is described below
commit 8aebe2c706e32a0457b7d1830a95b725fe549f0b
Author: Brian Neradt <[email protected]>
AuthorDate: Wed Aug 12 14:32:35 2026 -0500
Fix intermittent cache unit test segfault in Fedora CI (#13527)
The Fedora CI job fails every so often with a SIGSEGV in one of the
cache unit tests, always with the same stack: strrchr() called from
SourceLocation::str(), from lock_waiting(), from Mutex_trylock(). In
DEBUG builds a thread that fails to acquire a mutex reports the
holder's srcloc and handler, but those fields belong to whichever
thread holds the mutex, and a waiter that just failed to acquire it
holds nothing. That read races with the holder publishing the fields
on acquire and clearing them in Mutex_unlock(). Because
SourceLocation::str() loads file once for valid() and again for
strrchr(), and because the clear happens before the mutex is
released, a waiter can pass the validity check and then dereference a
null file. The cache unit tests are the only ones that enable the
locks debug tag, so they are the only ones that reach this code at
all.
This patch addresses this by reporting the waiting site rather than
the holder's. That SourceLocation is a MakeSourceLocation() temporary
owned by the caller, so nothing else can mutate it, and a holder
snapshot is stale the instant it is taken in any case. The holder is
still reported by lock_holding(), which runs from Mutex_unlock()
where the caller owns those fields.
Fixes: #13524
Co-authored-by: Claude Opus 5 <[email protected]>
---
include/iocore/eventsystem/Lock.h | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/include/iocore/eventsystem/Lock.h
b/include/iocore/eventsystem/Lock.h
index f41c862ba7..2fcef5fdad 100644
--- a/include/iocore/eventsystem/Lock.h
+++ b/include/iocore/eventsystem/Lock.h
@@ -261,7 +261,13 @@ Mutex_trylock(
if (m->thread_holding != t) {
if (!ink_mutex_try_acquire(&m->the_mutex)) {
#ifdef DEBUG
- lock_waiting(m->srcloc, m->handler);
+ // Report the waiting site, not the holder's. m->srcloc and m->handler
+ // belong to whichever thread holds the mutex, and this thread just
failed
+ // to acquire it, so reading them races with the holder publishing them
+ // below and clearing them in Mutex_unlock(). Any holder snapshot is
stale
+ // the instant it is taken anyway; lock_holding() still reports the
holder
+ // from Mutex_unlock(), where the fields are owned by the caller.
+ lock_waiting(location, ahandler);
#ifdef LOCK_CONTENTION_PROFILING
m->unsuccessful_nonblocking_acquires++;
m->nonblocking_acquires++;