Skip to content

Commit f0eb1b6

Browse files
committed
bug(tracing): register_callsite doesn't get called
This branch contains code to reproduce an issue where 2 thread local subscribers interfer so that when the first one takes too long to complete `register_callsite()`, the second subscriber doesn't have `register_callsite()` called at all. It also contains an attempt at a fix by removing a race condition in `DefaultCallsite::register`. This fix may be necessary anyway, but it isn't sufficient. The issue for this problem is #2743.
1 parent 7f0cc09 commit f0eb1b6

File tree

2 files changed

+37
-25
lines changed

2 files changed

+37
-25
lines changed

tracing-core/src/callsite.rs

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -310,31 +310,35 @@ impl DefaultCallsite {
310310
// This only happens once (or if the cached interest value was corrupted).
311311
#[cold]
312312
pub fn register(&'static self) -> Interest {
313-
// Attempt to advance the registration state to `REGISTERING`...
314-
match self.registration.compare_exchange(
315-
Self::UNREGISTERED,
316-
Self::REGISTERING,
317-
Ordering::AcqRel,
318-
Ordering::Acquire,
319-
) {
320-
Ok(_) => {
321-
// Okay, we advanced the state, try to register the callsite.
322-
rebuild_callsite_interest(self, &DISPATCHERS.rebuilder());
323-
CALLSITES.push_default(self);
324-
self.registration.store(Self::REGISTERED, Ordering::Release);
325-
}
326-
// Great, the callsite is already registered! Just load its
327-
// previous cached interest.
328-
Err(Self::REGISTERED) => {}
329-
// Someone else is registering...
330-
Err(_state) => {
331-
debug_assert_eq!(
332-
_state,
333-
Self::REGISTERING,
334-
"weird callsite registration state"
335-
);
336-
// Just hit `enabled` this time.
337-
return Interest::sometimes();
313+
loop {
314+
// Attempt to advance the registration state to `REGISTERING`...
315+
match self.registration.compare_exchange(
316+
Self::UNREGISTERED,
317+
Self::REGISTERING,
318+
Ordering::AcqRel,
319+
Ordering::Acquire,
320+
) {
321+
Ok(_) => {
322+
// Okay, we advanced the state, try to register the callsite.
323+
rebuild_callsite_interest(self, &DISPATCHERS.rebuilder());
324+
CALLSITES.push_default(self);
325+
self.registration.store(Self::REGISTERED, Ordering::Release);
326+
break;
327+
}
328+
// Great, the callsite is already registered! Just load its
329+
// previous cached interest.
330+
Err(Self::REGISTERED) => break,
331+
// Someone else is registering...
332+
Err(_state) => {
333+
debug_assert_eq!(
334+
_state,
335+
Self::REGISTERING,
336+
"weird callsite registration state: {_state}"
337+
);
338+
// The callsite is being registered. We have to wait until
339+
// registration is finished, otherwise
340+
continue;
341+
}
338342
}
339343
}
340344

tracing-subscriber/src/fmt/format/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,13 @@ where
953953

954954
for span in scope.from_root() {
955955
write!(writer, "{}", bold.paint(span.metadata().name()))?;
956+
write!(
957+
writer,
958+
"[{}/{:#?}]",
959+
span.id().into_u64(),
960+
span.metadata() as *const _,
961+
)?;
962+
956963
seen = true;
957964

958965
let ext = span.extensions();
@@ -1006,6 +1013,7 @@ where
10061013
)?;
10071014
}
10081015

1016+
write!(writer, "[/{:#?}]", event.metadata() as *const _,)?;
10091017
ctx.format_fields(writer.by_ref(), event)?;
10101018
writeln!(writer)
10111019
}

0 commit comments

Comments
 (0)