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

Staffan Larsen staffan.larsen at oracle.com
Sun Feb 3 12:18:24 PST 2013


On 1 feb 2013, at 18:55, Yumin Qi <yumin.qi at oracle.com> wrote:

> Staffan,
> 
>  This looks good. One question is why not set it to _thread_id? is it because it is 64bit int and  on other platforms 32 bits?

Do you mean reusing the _thread_id field instead of adding a new field? I think we need the current value of the _thread_id field (the mach thread port) for other purposes in Hotspot where the unique thread id does not work out.

> os_bsd.cpp:
> 
> 858 #ifdef __APPLE__
> 859   osthread->set_thread_id(::mach_thread_self());
> 860   osthread->set_unique_thread_id(locate_unique_thread_id());
> 861 #else
> 862   osthread->set_thread_id(::pthread_self());
> 863 #endif
> 864   osthread->set_pthread_id(::pthread_self());
> 
> I would like to remove #else part,   my understanding is only SA uses _unique_thread_id.

The #else part is for non-apple bsd ports (FreeBSD for example). Only the apple port of the bsd code can use the unique thread id. I'm not sure how this works on other bsds, so I don't want to change that code.

While I'm reviewing you Mach-o core file reader, I realize that you use the stack pointer for identifying threads. This was one of the options in my implementation. Given that you are using it for core files, then it makes sense to use the same solution for attached processes. I'm thinking that maybe I should revisit my solution and remove the _unique_thread_id.

/Staffan


> 
> Thanks
> Yumin
> 
> 
> On 1/17/2013 11:48 AM, 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/view_bug.do?bug_id=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() (thread_get_state 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.
>> 
>> thread_get_state() takes a thread_t as a parameter. The value of this parameter comes from SA reading the value of the OSThread._thread_id field in the Hotspot process being debugged. This value is set in HotSpot to ::mach_thread_self() which is documented as "The mach_thread_self system call returns the calling thread's thread port."
>> 
>> My theory is that this "thread port" in not valid when a different process calls thread_get_state(). 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 task_threads() 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._stack_base and Thread._stack_size).
>> 
>> Another way seems to be to use the thread_info() function with the THREAD_IDENTIFIER_INFO parameter. This gives us a struct which has a field called thread_id. The comment for this field in the thread_info.h file says "system-wide unique 64-bit thread id". The value for this thread_id 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 thread_id for each one and select the right "thread port" for the thread we are looking for.
>> 
>> Using a thread_id provided by the system seems more reliable than using the stack pointer for correlation.
>> 
>> 



More information about the hotspot-runtime-dev mailing list