JDK-6571589 : (thread) Thread.getStackTrace() returns null
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 5.0,6u2
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-06-20
  • Updated: 2011-05-18
  • Resolved: 2011-05-18
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.
Other Other JDK 6 JDK 7
5.0u17-revFixed 5.0u18Fixed 6u10Fixed 7 b16Fixed
Related Reports
Relates :  
Description
With the following test program, NullPointerException will be
thrown. That is not in line with the API.
http://java.sun.com/javase/6/docs/api/java/lang/Thread.html#getStackTrace()

TP:
----->
public class STNull {
  public static void main(String[] args) throws Exception {
    while(true) {
      Thread t = new Thread();
      t.start();
      StackTraceElement[] stes = t.getStackTrace();
      System.out.println(stes.length);
    }
  }
}
<-----

One of our customers reported NPE would be seen on Linux/EM64T below.

----->
java version "1.5.0_12"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_12-b04)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_12-b04, mixed mode)

java version "1.6.0_02"
Java(TM) SE Runtime Environment (build 1.6.0_02-b04)
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_02-b04, mixed mode)

java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b13)
Java HotSpot(TM) 64-Bit Server VM (build 1.7.0-ea-b13, mixed mode)
<-----

I also reproduced this against both jdk 5.0 and jdk 6.0 on my Windows
XP laptop as follows.

----->
$ java -version
java version "1.5.0_10"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_10-b03)
Java HotSpot(TM) Client VM (build 1.5.0_10-b03, mixed mode, sharing)

$ java STNull
0
0
0
0
0
Exception in thread "main" java.lang.NullPointerException
        at STNull.main(STNull.java:7) 

$ /g/jdk60/bin/java -version 
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode)

$ /g/jdk60/bin/java STNull
0
0
0
0
0
0
0
0
Exception in thread "main" java.lang.NullPointerException
        at STNull.main(STNull.java:7) 
<-----

Comments
EVALUATION Also: 1) Update getAllStackTraces to remove redundant isAlive check and amend the logic to only add traces for threads that have stacktraces available, i.e. not null. 2) Add extra clarification to getStackTrace specification about the possible return value of a thread that has been started but has not yet been scheduled to run by the system
25-06-2007

SUGGESTED FIX ------- Thread.java ------- 1398c1398,1399 < * this thread has not started or has terminated. --- > * this thread has not started, has started but has not yet been > * scheduled to run by the system, or has terminated. 1437a1439,1440 > // optimization so we do not call into the vm for threads that > // have not yet started or have terminated 1441c1444,1451 < return dumpThreads(new Thread[] {this})[0]; --- > StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this}); > StackTraceElement[] stackTrace = stackTraceArray[0]; > // a thread that was alive during the previous isAlive call may have > // since terminated, therefore not having a stacktrace. > if (stackTrace == null) { > stackTrace = EMPTY_STACK_TRACE; > } > return stackTrace; 1499,1503c1509,1510 < if (threads[i].isAlive()) { < StackTraceElement[] stackTrace = traces[i]; < if (stackTrace == null) { < stackTrace = EMPTY_STACK_TRACE; < } --- > StackTraceElement[] stackTrace = traces[i]; > if (stackTrace != null) { 1505c1512,1513 < } --- > } > // else terminated so we don't put it in the map
25-06-2007

EVALUATION The problem here is that there is a race between the thread calling getStackTrace and the thread, on which the stacktrace is trying to be retrieved, terminating. The library code for getStackTrace calls isAlive to determine if the thread is alive before calling into the vm to retrieve its stacktrace. Of course the thread may be alive at this point and subsequently terminate before the vm tries to retrieve its stacktrace. Looking at the vm operation VM_ThreadDump it looks this this code quite rightly handles threads that have terminated or are exiting, by adding a ThreadSnapshot that has a NULL _stack_trace. The problem or area of contention seems to be that ThreadService::dump_stack_traces when it sees a NULL stacktrace in one of the snapshots it puts a NULL into the StackTraceElement[][] instead of possibly an empty StackTraceElement[] element. The library code is not expecting this null. ..or is it. Thread.getAllStackTraces already tests for a possible null element in the StackTraceElement[][] returned from JVM_DumpThreads. So that being said I have amended the library code to handle this situation. *** (#1 of 1): [ UNSAVED ] ###@###.###
25-06-2007