提交 96c0fd1f 编写于 作者: M mchung

6973831: NPE when printing stack trace of OOME

Summary: Initialize suppressedExceptions field to null
Reviewed-by: briangoetz, dholmes, forax
上级 ee7b3a88
...@@ -200,7 +200,16 @@ public class Throwable implements Serializable { ...@@ -200,7 +200,16 @@ public class Throwable implements Serializable {
* @serial * @serial
* @since 1.7 * @since 1.7
*/ */
private List<Throwable> suppressedExceptions = Collections.emptyList(); private List<Throwable> suppressedExceptions = null;
/*
* This field is lazily initialized when the first suppressed
* exception is added.
*
* OutOfMemoryError is preallocated in the VM for better OOM
* diagnosability during VM initialization. Constructor can't
* be not invoked. If a new field to be added in the future must
* be initialized to non-null, it requires a synchronized VM change.
*/
/** Message for trying to suppress a null exception. */ /** Message for trying to suppress a null exception. */
private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception."; private static final String NULL_CAUSE_MESSAGE = "Cannot suppress a null exception.";
...@@ -329,7 +338,7 @@ public class Throwable implements Serializable { ...@@ -329,7 +338,7 @@ public class Throwable implements Serializable {
* cause is nonexistent or unknown. * cause is nonexistent or unknown.
* @since 1.4 * @since 1.4
*/ */
public Throwable getCause() { public synchronized Throwable getCause() {
return (cause==this ? null : cause); return (cause==this ? null : cause);
} }
...@@ -563,7 +572,7 @@ public class Throwable implements Serializable { ...@@ -563,7 +572,7 @@ public class Throwable implements Serializable {
s.println("\tat " + traceElement); s.println("\tat " + traceElement);
// Print suppressed exceptions, if any // Print suppressed exceptions, if any
for (Throwable se : suppressedExceptions) for (Throwable se : getSuppressedExceptions())
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu); se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu);
// Print cause, if any // Print cause, if any
...@@ -604,7 +613,7 @@ public class Throwable implements Serializable { ...@@ -604,7 +613,7 @@ public class Throwable implements Serializable {
s.println(prefix + "\t... " + framesInCommon + " more"); s.println(prefix + "\t... " + framesInCommon + " more");
// Print suppressed exceptions, if any // Print suppressed exceptions, if any
for (Throwable se : suppressedExceptions) for (Throwable se : getSuppressedExceptions())
se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION,
prefix +"\t", dejaVu); prefix +"\t", dejaVu);
...@@ -747,7 +756,9 @@ public class Throwable implements Serializable { ...@@ -747,7 +756,9 @@ public class Throwable implements Serializable {
if (defensiveCopy[i] == null) if (defensiveCopy[i] == null)
throw new NullPointerException("stackTrace[" + i + "]"); throw new NullPointerException("stackTrace[" + i + "]");
this.stackTrace = defensiveCopy; synchronized (this) {
this.stackTrace = defensiveCopy;
}
} }
/** /**
...@@ -772,11 +783,11 @@ public class Throwable implements Serializable { ...@@ -772,11 +783,11 @@ public class Throwable implements Serializable {
private void readObject(ObjectInputStream s) private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException { throws IOException, ClassNotFoundException {
s.defaultReadObject(); // read in all fields s.defaultReadObject(); // read in all fields
List<Throwable> suppressed = Collections.emptyList(); List<Throwable> suppressed = null;
if (suppressedExceptions != null && if (suppressedExceptions != null &&
!suppressedExceptions.isEmpty()) { // Copy Throwables to new list !suppressedExceptions.isEmpty()) { // Copy Throwables to new list
suppressed = new ArrayList<Throwable>(); suppressed = new ArrayList<Throwable>();
for(Throwable t : suppressedExceptions) { for (Throwable t : suppressedExceptions) {
if (t == null) if (t == null)
throw new NullPointerException(NULL_CAUSE_MESSAGE); throw new NullPointerException(NULL_CAUSE_MESSAGE);
suppressed.add(t); suppressed.add(t);
...@@ -819,7 +830,7 @@ public class Throwable implements Serializable { ...@@ -819,7 +830,7 @@ public class Throwable implements Serializable {
if (exception == this) if (exception == this)
throw new IllegalArgumentException("Self-suppression not permitted"); throw new IllegalArgumentException("Self-suppression not permitted");
if (suppressedExceptions.size() == 0) if (suppressedExceptions == null)
suppressedExceptions = new ArrayList<Throwable>(); suppressedExceptions = new ArrayList<Throwable>();
suppressedExceptions.add(exception); suppressedExceptions.add(exception);
} }
...@@ -835,7 +846,10 @@ public class Throwable implements Serializable { ...@@ -835,7 +846,10 @@ public class Throwable implements Serializable {
* suppressed to deliver this exception. * suppressed to deliver this exception.
* @since 1.7 * @since 1.7
*/ */
public Throwable[] getSuppressedExceptions() { public synchronized Throwable[] getSuppressedExceptions() {
return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY); if (suppressedExceptions == null)
return EMPTY_THROWABLE_ARRAY;
else
return suppressedExceptions.toArray(EMPTY_THROWABLE_ARRAY);
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册