JDK-6915662 : Throwable.setStackTrace is not thread-safe
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 6u12
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2010-01-11
  • Updated: 2011-02-16
  • Resolved: 2010-08-31
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7Resolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Client VM (build 11.2-b01, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Windows XP Professional - Version 2002 - Service Pack 2

A DESCRIPTION OF THE PROBLEM :
Throwable class is not thread safe regarding private StackTraceElement[] stackTrace field.

Can be modified concurrently by two threads causing ArrayIndexOutOfBoundsException.

Two places of modification:

1) setStackTrace
    public void setStackTrace(StackTraceElement[] stackTrace) {
        ....
        this.stackTrace = defensiveCopy;
    }

2) getOurStackTrace
    private synchronized StackTraceElement[] getOurStackTrace() {
        // Initialize stack trace if this is the first call to this method
        if (stackTrace == null) {
            int depth = getStackTraceDepth();
            stackTrace = new StackTraceElement[depth];
            for (int i=0; i < depth; i++)
                stackTrace[i] = getStackTraceElement(i); // throws ArrayIndexOutOfBoundsException
        }
        return stackTrace;
    }

Solution: setStackTrace should be synchronized as well

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run two threads calling on the same Throwable object:
1) first thread - setStackTrace
2) second thread - getStackTrace

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Not exception thrown
ACTUAL -
Occasional ArrayIndexOutOfBoundsException

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ArrayIndexOutOfBoundsException: 65
	at java.lang.Throwable.getOurStackTrace(Throwable.java:592)
	at java.lang.Throwable.printStackTrace(Throwable.java:511)
	at org.apache.log4j.spi.ThrowableInformation.getThrowableStrRep(ThrowableInformation.java:59)
	at org.apache.log4j.spi.LoggingEvent.getThrowableStrRep(LoggingEvent.java:342)
	at org.apache.log4j.WriterAppender.subAppend(WriterAppender.java:304)
	at org.apache.log4j.RollingFileAppender.subAppend(RollingFileAppender.java:236)
	at org.apache.log4j.WriterAppender.append(WriterAppender.java:159)
	at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:230)
	at org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:65)
	at org.apache.log4j.Category.callAppenders(Category.java:203)
	at org.apache.log4j.Category.forcedLog(Category.java:388)
	at org.apache.log4j.Category.log(Category.java:823)


REPRODUCIBILITY :
This bug can be reproduced occasionally.

Comments
EVALUATION The bug has been fixed by 6973831.
31-08-2010

EVALUATION The synchronization issue of the Throwable.setStackTrace method was caught and fixed in the code review for 6973831: http://hg.openjdk.java.net/jdk7/tl/jdk/rev/389bc53d0945 In process to contact the submitter to verify the fix.
13-08-2010

EVALUATION The Throwable.stackTrace field is set in the setStackTrace method with no synchronization.
21-07-2010