RFR: 8006423 SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67) (original) (raw)

Rickard Bäckman rickard.backman at oracle.com
Fri Feb 8 03:41:28 PST 2013


Staffan,

the change looks good to me! Thanks for fixing this problem.

/R

On Jan 17, 2013, at 8:48 PM, Staffan Larsen wrote:

This is a request for review of a fix for SA on OS X.

webrev: http://cr.openjdk.java.net/~sla/8006423/webrev.00/ bug: http://bugs.sun.com/bugdatabase/viewbug.do?bugid=8006423 The bug report contains a detailed description of the problem and the proposed solution. I have copied some of that text below. To verify the fix I have manually run jstack on OS X. Thanks, /Staffan

In many cases when running the SA version of JStack (or other SA tools) an NPE is thrown in BsdThread.getContext(). The underlaying cause is that SA fails to read the context of the thread in the native method getThreadIntegerRegisterSet0() (threadgetstate returns an error). The following is my understanding of what the cause is and a suggestion for a fix - my experience with OS X is a bit limited so I may be off on some details. threadgetstate() takes a threadt as a parameter. The value of this parameter comes from SA reading the value of the OSThread.threadid field in the Hotspot process being debugged. This value is set in HotSpot to ::machthreadself() which is documented as "The machthreadself system call returns the calling thread's thread port." My theory is that this "thread port" in not valid when a different process calls threadgetstate(). Instead, the other process (SA in this case) needs it's own "thread port" for the thread it wants to access. There is a way to list all the thread ports in a different process (or "task" as they are called in Mach) via the taskthreads() function. So now we have the thread ports, we just need to correlate them with the C++ Thread objects in the Hotspot process. One way to do this correlation is via the stack pointer. We can get the current value of the stack pointer (rsp) in SA and look through all the Thread objects to see which one the stack pointer belongs to (by looking at Thread.stackbase and Thread.stacksize). Another way seems to be to use the threadinfo() function with the THREADIDENTIFIERINFO parameter. This gives us a struct which has a field called threadid. The comment for this field in the threadinfo.h file says "system-wide unique 64-bit thread id". The value for this threadid is the same when called from Hotspot and when called from the debugging process (SA), so this looks like a way to do the correlation. This requires Hotspot to store this value in OSThread and SA to first list all the "thread ports", then find the threadid for each one and select the right "thread port" for the thread we are looking for. Using a threadid provided by the system seems more reliable than using the stack pointer for correlation.



More information about the serviceability-dev mailing list