Avoid resetting detached thread-local states. In rare chance it can happen that some threads can end in between `CleanUpDetachedTls()` and `ForEachTls` when resetting the states. PiperOrigin-RevId: 899651655
diff --git a/centipede/sancov_state.cc b/centipede/sancov_state.cc index 19570d6..784793c 100644 --- a/centipede/sancov_state.cc +++ b/centipede/sancov_state.cc
@@ -176,6 +176,7 @@ // TODO(xinhaoyuan): Consider refactoring the list operations into class // methods instead of duplicating them. ThreadLocalSancovState *detached_tls = new ThreadLocalSancovState(tls); + detached_tls->detached = true; auto* old_list = sancov_state->detached_tls_list; detached_tls->next = old_list; sancov_state->detached_tls_list = detached_tls; @@ -309,6 +310,7 @@ void CleanUpSancovTls() { sancov_state->CleanUpDetachedTls(); sancov_state->ForEachTls([](ThreadLocalSancovState& tls) { + if (tls.detached) return; if (sancov_state->flags.path_level != 0) { tls.path_ring_buffer.Reset(sancov_state->flags.path_level); }
diff --git a/centipede/sancov_state.h b/centipede/sancov_state.h index 85407e3..5ff8d27 100644 --- a/centipede/sancov_state.h +++ b/centipede/sancov_state.h
@@ -101,6 +101,9 @@ // Whether the thread should be traced for execution feedback. bool traced; + // Whether the thread state is detached, i.e. the thread has ended. + bool detached; + // Paths are thread-local, so we maintain the current bounded path here. // We allow paths of up to 100, controlled at run-time via the "path_level". static constexpr uint64_t kBoundedPathLength = 100;