8271588: JFR Recorder Thread crashed with SIGSEGV in write_klass

Reviewed-by: egahlin
This commit is contained in:
Markus Grönlund 2021-08-05 09:13:26 +00:00
parent f312f28b8b
commit 90f85ff70f
5 changed files with 17 additions and 7 deletions

View File

@ -455,7 +455,7 @@ size_t JfrCheckpointManager::flush_type_set() {
elements = ::flush_type_set(thread);
}
}
if (_new_checkpoint.is_signaled()) {
if (_new_checkpoint.is_signaled_with_reset()) {
WriteOperation wo(_chunkwriter);
MutexedWriteOperation mwo(wo);
_thread_local_mspace->iterate(mwo); // current epoch list

View File

@ -1103,6 +1103,10 @@ void JfrTypeSet::clear() {
}
size_t JfrTypeSet::on_unloading_classes(JfrCheckpointWriter* writer) {
// JfrTraceIdEpoch::has_changed_tag_state_no_reset() is a load-acquire we issue to see side-effects (i.e. tags).
// The JfrRecorderThread does this as part of normal processing, but with concurrent class unloading, which can
// happen in arbitrary threads, we invoke it explicitly.
JfrTraceIdEpoch::has_changed_tag_state_no_reset();
if (JfrRecorder::is_recording()) {
return serialize(writer, NULL, true, false);
}

View File

@ -108,6 +108,10 @@ class JfrTraceIdEpoch : AllStatic {
}
static bool has_changed_tag_state() {
return _tag_state.is_signaled_with_reset();
}
static bool has_changed_tag_state_no_reset() {
return _tag_state.is_signaled();
}

View File

@ -44,7 +44,7 @@ typedef JfrStringPool::BufferPtr BufferPtr;
static JfrSignal _new_string;
bool JfrStringPool::is_modified() {
return _new_string.is_signaled();
return _new_string.is_signaled_with_reset();
}
static JfrStringPool* _instance = NULL;

View File

@ -34,14 +34,16 @@ class JfrSignal {
JfrSignal() : _signaled(false) {}
void signal() const {
if (!Atomic::load_acquire(&_signaled)) {
Atomic::release_store(&_signaled, true);
}
Atomic::release_store(&_signaled, true);
}
bool is_signaled() const {
if (Atomic::load_acquire(&_signaled)) {
Atomic::release_store(&_signaled, false); // auto-reset
return Atomic::load_acquire(&_signaled);
}
bool is_signaled_with_reset() const {
if (is_signaled()) {
Atomic::release_store(&_signaled, false);
return true;
}
return false;