From c3b2303810acb56fc32bc8a1ec1032056d713e97 Mon Sep 17 00:00:00 2001 From: Paulo Motta Date: Fri, 10 Oct 2025 14:56:30 -0400 Subject: [PATCH] Heap dump should not be generated on handled exceptions Patch by Paulo Motta; Reviewed by Isaac Reath, Stefan Miklosovic for CASSANDRA-20974 --- CHANGES.txt | 3 ++- .../org/apache/cassandra/utils/HeapUtils.java | 4 ---- .../utils/JVMStabilityInspector.java | 23 ++++++++++++++----- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 401ac07a1e..eb95066bbe 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,7 @@ 5.0.7 + * Heap dump should not be generated on handled exceptions (CASSANDRA-20974) Merged from 4.1: -* ReadCommandController should close fast to avoid deadlock when building secondary index (CASSANDRA-19564) + * ReadCommandController should close fast to avoid deadlock when building secondary index (CASSANDRA-19564) Merged from 4.0: * Updated dtest-api to 0.0.18 and removed JMX-related classes that now live in the dtest-api (CASSANDRA-20884) diff --git a/src/java/org/apache/cassandra/utils/HeapUtils.java b/src/java/org/apache/cassandra/utils/HeapUtils.java index 38a6969908..6171866b40 100644 --- a/src/java/org/apache/cassandra/utils/HeapUtils.java +++ b/src/java/org/apache/cassandra/utils/HeapUtils.java @@ -128,10 +128,6 @@ public final class HeapUtils return fullPath; } - else - { - logger.debug("Heap dump creation on uncaught exceptions is disabled."); - } } catch (Throwable e) { diff --git a/src/java/org/apache/cassandra/utils/JVMStabilityInspector.java b/src/java/org/apache/cassandra/utils/JVMStabilityInspector.java index a396ef9947..c35c7eb938 100644 --- a/src/java/org/apache/cassandra/utils/JVMStabilityInspector.java +++ b/src/java/org/apache/cassandra/utils/JVMStabilityInspector.java @@ -75,7 +75,7 @@ public final class JVMStabilityInspector if (t2 != t && (t2 instanceof FSError || t2 instanceof CorruptSSTableException)) logger.error("Exception in thread {}", thread, t2); } - JVMStabilityInspector.inspectThrowable(t); + inspectThrowable(t, JVMStabilityInspector::inspectDiskError, true); } /** @@ -86,12 +86,12 @@ public final class JVMStabilityInspector */ public static void inspectThrowable(Throwable t) throws OutOfMemoryError { - inspectThrowable(t, JVMStabilityInspector::inspectDiskError); + inspectThrowable(t, JVMStabilityInspector::inspectDiskError, false); } public static void inspectCommitLogThrowable(Throwable t) { - inspectThrowable(t, JVMStabilityInspector::inspectCommitLogError); + inspectThrowable(t, JVMStabilityInspector::inspectCommitLogError, false); } private static void inspectDiskError(Throwable t) @@ -102,7 +102,7 @@ public final class JVMStabilityInspector FileUtils.handleFSError((FSError) t); } - public static void inspectThrowable(Throwable t, Consumer fn) throws OutOfMemoryError + public static void inspectThrowable(Throwable t, Consumer fn, boolean isUncaughtException) throws OutOfMemoryError { boolean isUnstable = false; if (t instanceof OutOfMemoryError) @@ -136,7 +136,18 @@ public final class JVMStabilityInspector } // Anything other than an OOM, we should try and heap dump to capture what's going on if configured to do so - HeapUtils.maybeCreateHeapDump(); + if (isUncaughtException && DatabaseDescriptor.getDumpHeapOnUncaughtException()) + { + try + { + // Avoid entering maybeCreateHeapDump unless the setting is enabled to avoid expensive lock + HeapUtils.maybeCreateHeapDump(); + } + catch (Throwable sub) + { + t.addSuppressed(sub); + } + } if (t instanceof InterruptedException) throw new UncheckedInterruptedException((InterruptedException) t); @@ -167,7 +178,7 @@ public final class JVMStabilityInspector } if (t.getCause() != null) - inspectThrowable(t.getCause(), fn); + inspectThrowable(t.getCause(), fn, isUncaughtException); } private static final Set FORCE_HEAP_OOM_IGNORE_SET = ImmutableSet.of("Java heap space", "GC Overhead limit exceeded");