[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-serviceability-dev
Subject:    Re: [10] RFR 8181647: jhsdb jstack could not output thread name
From:       David Buck <david.buck () oracle ! com>
Date:       2017-07-06 5:20:11
Message-ID: 3e0a003a-5664-6713-61a4-9bc06c8d2022 () oracle ! com
[Download RAW message or body]

Hi!

Sharath Ballal has identified another minor formatting issue on line 984 
of vmStructs.cpp. I have corrected it and uploaded a new webrev:

http://cr.openjdk.java.net/~dbuck/8181647.2/

I have run the changes through JPRT (default and "hotspot" test sets) 
and see no sign of regression.

We have already had one Reviewer, Suenaga-san, give a thumbs up to these 
changes. Unless there are any objections or additional suggestions made, 
in a few hours I will proceed with pushing this to 
http://hg.openjdk.java.net/jdk10/hs.

Cheers,
-Buck

On 2017/07/06 1:35, Poonam Parhar wrote:
> Hello Chihiro,
> 
> The updated webrev looks good!
> 
> Thanks,
> Poonam
> 
>> -----Original Message-----
>> From: chihiro ito
>> Sent: Wednesday, July 05, 2017 12:58 PM
>> To: Poonam Parhar; Yasumasa Suenaga
>> Cc: serviceability-dev@openjdk.java.net
>> Subject: Re: [10] RFR 8181647: jhsdb jstack could not output thread
>> name
>>
>> Hello Poonam,
>>
>> Thank you for reviewing.
>>
>> I applyed your advices. The webrev is following.
>>
>> http://cr.openjdk.java.net/~dbuck/8181647.1/
>>
>> Could you review, please?
>>
>> Regards,
>> Chihiro
>>
>> On 2017/07/06 3:23, Poonam Parhar wrote:
>>> Hello Chihiro,
>>>
>>> The changes in the following webrev look good to me:
>>> http://cr.openjdk.java.net/~dbuck/8181647.0/
>>>
>>> A few minor suggestions though:
>>>
>>> -
>> src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities.j
>> ava
>>>
>>> Lines 354 - 370:
>>> Extra whitespace in the if conditions can be removed:
>>> if( status == THREAD_STATUS_NEW ){
>>> to
>>> if(status == THREAD_STATUS_NEW){
>>>
>>> please do this for all the 'if' statements.
>>>
>>> - share/classes/sun/jvm/hotspot/runtime/JavaThread.java.
>>> Line 482: extra line; can be removed
>>> Line 507: not indented properly
>>>
>>> Thanks,
>>> Poonam
>>>
>>>
>>>> -----Original Message-----
>>>> From: Yasumasa Suenaga [mailto:yasuenag@gmail.com]
>>>> Sent: Tuesday, July 04, 2017 3:44 PM
>>>> To: chihiro ito
>>>> Cc: serviceability-dev@openjdk.java.net
>>>> Subject: Re: [10] RFR 8181647: jhsdb jstack could not output thread
>>>> name
>>>>
>>>> Hi Chihiro,
>>>>
>>>> It looks good to me.
>>>> However, I cannot be a sponsor because I cannot access JPRT. The
>>>> change(s) for HotSpot should be pushed via JPRT.
>>>>
>>>> Please find a sponsor for this change.
>>>> (Of course, you can list me as a reviewer (ysuenaga))
>>>>
>>>>
>>>> Thanks,
>>>>
>>>> Yasumasa
>>>>
>>>>
>>>> On 2017/07/05 2:17, chihiro ito wrote:
>>>>> Hi Yasumasa,
>>>>>
>>>>> Thank you for reviewing.
>>>>>
>>>>> I modified these following source code that you commented.
>>>>>> +
>>>> out.print(String.format("0x%016x",this.getAddress().asLongValue()));
>>>>>> +    out.print(" nid=");
>>>>>> +    out.print(String.format("0x%x
>>>> ",this.getOSThread().threadId()));
>>>>>> +    out.print(getOSThread().getThreadState().getPrintVal());
>>>>>> +    out.print(" [");
>>>>>> +    if( this.getLastJavaSP() == null){
>>>>>> +      out.print(String.format("0x%016x",0L));
>>>>> Based on your advice, I have modified as following. Could you
>>>> possibly review for this code ?
>>>>> +  private static final String  ADDRESS_FORMAT =
>> VM.getVM().isLP64()
>>>> ? "0x%016x" : "0x%08x";
>>>>> +    out.print(this.getAddress());
>>>>> +    out.print(" nid=");
>>>>> +    out.print(String.format("0x%x
>> ",this.getOSThread().threadId()));
>>>>> +    out.print(getOSThread().getThreadState().getPrintVal());
>>>>> +    out.print(" [");
>>>>> +    if( this.getLastJavaSP() == null){
>>>>> +      out.print(String.format(ADDRESS_FORMAT,0L));
>>>>>
>>>>> Regards,
>>>>> Chihiro
>>>>>
>>>>>
>>>>> hg diff -g is following.
>>>>>
>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>> @@ -1,5 +1,5 @@
>>>>>    /*
>>>>> - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>> + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>>>>>     *
>>>>>     * This code is free software; you can redistribute it and/or
>> modify
>>>> it
>>>>> @@ -59,20 +59,20 @@
>>>>>      // parkBlocker field is new since 1.6
>>>>>      private static OopField threadParkBlockerField;
>>>>>
>>>>> +  private static IntField threadPriorityField;
>>>>> +  private static BooleanField threadDaemonField;
>>>>> +
>>>>>      // possible values of java_lang_Thread::ThreadStatus
>>>>>      private static int THREAD_STATUS_NEW;
>>>>> -  /*
>>>>> -    Other enum constants are not needed as of now. Uncomment these
>>>> as and when needed.
>>>>> -    private static int THREAD_STATUS_RUNNABLE;
>>>>> -    private static int THREAD_STATUS_SLEEPING;
>>>>> -    private static int THREAD_STATUS_IN_OBJECT_WAIT;
>>>>> -    private static int THREAD_STATUS_IN_OBJECT_WAIT_TIMED;
>>>>> -    private static int THREAD_STATUS_PARKED;
>>>>> -    private static int THREAD_STATUS_PARKED_TIMED;
>>>>> -    private static int THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER;
>>>>> -    private static int THREAD_STATUS_TERMINATED;
>>>>> -  */
>>>>> +  private static int THREAD_STATUS_RUNNABLE;
>>>>> +  private static int THREAD_STATUS_SLEEPING;
>>>>> +  private static int THREAD_STATUS_IN_OBJECT_WAIT;
>>>>> +  private static int THREAD_STATUS_IN_OBJECT_WAIT_TIMED;
>>>>> +  private static int THREAD_STATUS_PARKED;
>>>>> +  private static int THREAD_STATUS_PARKED_TIMED;
>>>>> +  private static int THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER;
>>>>> +  private static int THREAD_STATUS_TERMINATED;
>>>>>
>>>>>      // java.util.concurrent.locks.AbstractOwnableSynchronizer
>> fields
>>>>>      private static OopField absOwnSyncOwnerThreadField;
>>>>> @@ -229,20 +229,19 @@
>>>>>          threadStatusField = (IntField) k.findField("threadStatus",
>>>> "I");
>>>>>          threadParkBlockerField = (OopField)
>> k.findField("parkBlocker",
>>>>>                                         "Ljava/lang/Object;");
>>>>> +      threadPriorityField = (IntField) k.findField("priority",
>> "I");
>>>>> +      threadDaemonField = (BooleanField) k.findField("daemon",
>> "Z");
>>>>>          TypeDataBase db = VM.getVM().getTypeDataBase();
>>>>>          THREAD_STATUS_NEW =
>>>> db.lookupIntConstant("java_lang_Thread::NEW").intValue();
>>>>> -      /*
>>>>> -        Other enum constants are not needed as of now. Uncomment
>>>> these as and when needed.
>>>>> -        THREAD_STATUS_RUNNABLE =
>>>> db.lookupIntConstant("java_lang_Thread::RUNNABLE").intValue();
>>>>> -        THREAD_STATUS_SLEEPING =
>>>> db.lookupIntConstant("java_lang_Thread::SLEEPING").intValue();
>>>>> -        THREAD_STATUS_IN_OBJECT_WAIT =
>>>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT").intValue();
>>>>> -        THREAD_STATUS_IN_OBJECT_WAIT_TIMED =
>>>>
>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT_TIMED").intValue
>>>> ();
>>>>> -        THREAD_STATUS_PARKED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED").intValue();
>>>>> -        THREAD_STATUS_PARKED_TIMED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED_TIMED").intValue();
>>>>> -        THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER =
>>>>
>> db.lookupIntConstant("java_lang_Thread::BLOCKED_ON_MONITOR_ENTER").intV
>>>> alue();
>>>>> -        THREAD_STATUS_TERMINATED =
>>>> db.lookupIntConstant("java_lang_Thread::TERMINATED").intValue();
>>>>> -      */
>>>>> +      THREAD_STATUS_RUNNABLE =
>>>> db.lookupIntConstant("java_lang_Thread::RUNNABLE").intValue();
>>>>> +      THREAD_STATUS_SLEEPING =
>>>> db.lookupIntConstant("java_lang_Thread::SLEEPING").intValue();
>>>>> +      THREAD_STATUS_IN_OBJECT_WAIT =
>>>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT").intValue();
>>>>> +      THREAD_STATUS_IN_OBJECT_WAIT_TIMED =
>>>>
>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT_TIMED").intValue
>>>> ();
>>>>> +      THREAD_STATUS_PARKED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED").intValue();
>>>>> +      THREAD_STATUS_PARKED_TIMED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED_TIMED").intValue();
>>>>> +      THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER =
>>>>
>> db.lookupIntConstant("java_lang_Thread::BLOCKED_ON_MONITOR_ENTER").intV
>>>> alue();
>>>>> +      THREAD_STATUS_TERMINATED =
>>>> db.lookupIntConstant("java_lang_Thread::TERMINATED").intValue();
>>>>>          if (Assert.ASSERTS_ENABLED) {
>>>>>            // it is okay to miss threadStatusField, because this was
>>>>> @@ -331,4 +330,46 @@
>>>>>          return absOwnSyncOwnerThreadField.getValue(oop);
>>>>>        }
>>>>>      }
>>>>> +
>>>>> +  public static int threadOopGetPriority(Oop threadOop) {
>>>>> +    initThreadFields();
>>>>> +    if (threadPriorityField != null) {
>>>>> +      return threadPriorityField.getValue(threadOop);
>>>>> +    } else {
>>>>> +      return 0;
>>>>> +    }
>>>>> +  }
>>>>> +
>>>>> +  public static boolean threadOopGetDaemon(Oop threadOop) {
>>>>> +    initThreadFields();
>>>>> +    if (threadDaemonField != null) {
>>>>> +      return threadDaemonField.getValue(threadOop);
>>>>> +    } else {
>>>>> +      return false;
>>>>> +    }
>>>>> +  }
>>>>> +
>>>>> +  public static String threadOopGetThreadStatusName(Oop threadOop)
>> {
>>>>> +    int status = OopUtilities.threadOopGetThreadStatus(threadOop);
>>>>> +    if( status == THREAD_STATUS_NEW ){
>>>>> +      return "NEW";
>>>>> +    }else if(status == THREAD_STATUS_RUNNABLE ){
>>>>> +      return "RUNNABLE";
>>>>> +    }else if(status == THREAD_STATUS_SLEEPING ){
>>>>> +      return "TIMED_WAITING (sleeping)";
>>>>> +    }else if(status == THREAD_STATUS_IN_OBJECT_WAIT ){
>>>>> +      return "WAITING (on object monitor)";
>>>>> +    }else if(status == THREAD_STATUS_IN_OBJECT_WAIT_TIMED ){
>>>>> +      return "TIMED_WAITING (on object monitor)";
>>>>> +    }else if(status == THREAD_STATUS_PARKED ){
>>>>> +      return "WAITING (parking)";
>>>>> +    }else if(status == THREAD_STATUS_PARKED_TIMED ){
>>>>> +      return "TIMED_WAITING (parking)";
>>>>> +    }else if(status == THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER ){
>>>>> +      return "BLOCKED (on object monitor)";
>>>>> +    }else if(status == THREAD_STATUS_TERMINATED ){
>>>>> +      return "TERMINATED";
>>>>> +    }
>>>>> +    return "UNKNOWN";
>>>>> +  }
>>>>>    }
>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>> @@ -70,6 +70,8 @@
>>>>>      private static int           NOT_TERMINATED;
>>>>>      private static int           EXITING;
>>>>>
>>>>> +  private static final String  ADDRESS_FORMAT =
>> VM.getVM().isLP64()
>>>> ? "0x%016x" : "0x%08x";
>>>>> +
>>>>>      static {
>>>>>        VM.registerVMInitializedObserver(new Observer() {
>>>>>            public void update(Observable o, Object data) {
>>>>> @@ -475,4 +477,35 @@
>>>>>        return access.getLastSP(addr);
>>>>>      }
>>>>>
>>>>> +
>>>>> +  public void printThreadInfoOn(PrintStream out){
>>>>> +
>>>>> +    Oop threadOop = this.getThreadObj();
>>>>> +
>>>>> +    out.print("\"");
>>>>> +    out.print(this.getThreadName());
>>>>> +    out.print("\" #");
>>>>> +    out.print(OopUtilities.threadOopGetTID(threadOop));
>>>>> +    if( OopUtilities.threadOopGetDaemon(threadOop) ){
>>>>> +      out.print(" daemon");
>>>>> +    }
>>>>> +    out.print(" prio=");
>>>>> +    out.print(OopUtilities.threadOopGetPriority(threadOop));
>>>>> +    out.print(" tid=");
>>>>> +    out.print(this.getAddress());
>>>>> +    out.print(" nid=");
>>>>> +    out.print(String.format("0x%x
>> ",this.getOSThread().threadId()));
>>>>> +    out.print(getOSThread().getThreadState().getPrintVal());
>>>>> +    out.print(" [");
>>>>> +    if( this.getLastJavaSP() == null){
>>>>> +      out.print(String.format(ADDRESS_FORMAT,0L));
>>>>> +    } else {
>>>>> +      out.print(this.getLastJavaSP().andWithMask(~0xFFF));
>>>>> +    }
>>>>> +    out.println("]");
>>>>> +    out.print("   java.lang.Thread.State: ");
>>>>> +
>> out.println(OopUtilities.threadOopGetThreadStatusName(threadOop));
>>>>> +    out.print("   JavaThread state: _thread_");
>>>>> +    out.println(this.getThreadState().toString().toLowerCase());
>>>>> +  }
>>>>>    }
>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>> @@ -1,5 +1,5 @@
>>>>>    /*
>>>>> - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>> + * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>>>>>     *
>>>>>     * This code is free software; you can redistribute it and/or
>> modify
>>>> it
>>>>> @@ -33,6 +33,19 @@
>>>>>    public class OSThread extends VMObject {
>>>>>        private static JIntField interruptedField;
>>>>>        private static Field threadIdField;
>>>>> +    private static CIntegerField threadStateField;
>>>>> +
>>>>> +    // ThreadStates read from underlying process
>>>>> +    private static int ALLOCATED;
>>>>> +    private static int INITIALIZED;
>>>>> +    private static int RUNNABLE;
>>>>> +    private static int MONITOR_WAIT;
>>>>> +    private static int CONDVAR_WAIT;
>>>>> +    private static int OBJECT_WAIT;
>>>>> +    private static int BREAKPOINTED;
>>>>> +    private static int SLEEPING;
>>>>> +    private static int ZOMBIE;
>>>>> +
>>>>>        static {
>>>>>            VM.registerVMInitializedObserver(new Observer() {
>>>>>                public void update(Observable o, Object data) {
>>>>> @@ -45,6 +58,17 @@
>>>>>            Type type = db.lookupType("OSThread");
>>>>>            interruptedField = type.getJIntField("_interrupted");
>>>>>            threadIdField = type.getField("_thread_id");
>>>>> +        threadStateField = type.getCIntegerField("_state");
>>>>> +
>>>>> +        ALLOCATED = db.lookupIntConstant("ALLOCATED").intValue();
>>>>> +        INITIALIZED =
>>>> db.lookupIntConstant("INITIALIZED").intValue();
>>>>> +        RUNNABLE = db.lookupIntConstant("RUNNABLE").intValue();
>>>>> +        MONITOR_WAIT =
>>>> db.lookupIntConstant("MONITOR_WAIT").intValue();
>>>>> +        CONDVAR_WAIT =
>>>> db.lookupIntConstant("CONDVAR_WAIT").intValue();
>>>>> +        OBJECT_WAIT =
>>>> db.lookupIntConstant("OBJECT_WAIT").intValue();
>>>>> +        BREAKPOINTED =
>>>> db.lookupIntConstant("BREAKPOINTED").intValue();
>>>>> +        SLEEPING = db.lookupIntConstant("SLEEPING").intValue();
>>>>> +        ZOMBIE = db.lookupIntConstant("ZOMBIE").intValue();
>>>>>        }
>>>>>
>>>>>        public OSThread(Address addr) {
>>>>> @@ -59,4 +83,28 @@
>>>>>            return threadIdField.getJInt(addr);
>>>>>        }
>>>>>
>>>>> +    public ThreadState getThreadState() {
>>>>> +        int val = (int)threadStateField.getValue(addr);
>>>>> +        if (val ==  ALLOCATED) {
>>>>> +            return ThreadState.ALLOCATED;
>>>>> +        } else if (val ==  INITIALIZED) {
>>>>> +            return ThreadState.INITIALIZED;
>>>>> +        } else if (val ==  RUNNABLE) {
>>>>> +            return ThreadState.RUNNABLE;
>>>>> +        } else if (val ==  MONITOR_WAIT) {
>>>>> +            return ThreadState.MONITOR_WAIT;
>>>>> +        } else if (val ==  CONDVAR_WAIT) {
>>>>> +            return ThreadState.CONDVAR_WAIT;
>>>>> +        } else if (val ==  OBJECT_WAIT) {
>>>>> +            return ThreadState.OBJECT_WAIT;
>>>>> +        } else if (val ==  BREAKPOINTED) {
>>>>> +            return ThreadState.BREAKPOINTED;
>>>>> +        } else if (val ==  SLEEPING) {
>>>>> +            return ThreadState.SLEEPING;
>>>>> +        } else if (val ==  ZOMBIE) {
>>>>> +            return ThreadState.ZOMBIE;
>>>>> +        } else {
>>>>> +            throw new RuntimeException("Illegal thread state " +
>>>> val);
>>>>> +        }
>>>>> +    }
>>>>>    }
>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>> new file mode 100644
>>>>> --- /dev/null
>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>> @@ -0,0 +1,60 @@
>>>>> +/*
>>>>> + * Copyright (c) 2017, Oracle and/or its affiliates. All rights
>>>> reserved.
>>>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>>>>> + *
>>>>> + * This code is free software; you can redistribute it and/or
>> modify
>>>> it
>>>>> + * under the terms of the GNU General Public License version 2
>> only,
>>>> as
>>>>> + * published by the Free Software Foundation.
>>>>> + *
>>>>> + * This code is distributed in the hope that it will be useful,
>> but
>>>> WITHOUT
>>>>> + * ANY WARRANTY; without even the implied warranty of
>>>> MERCHANTABILITY or
>>>>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
>>>> License
>>>>> + * version 2 for more details (a copy is included in the LICENSE
>>>> file that
>>>>> + * accompanied this code).
>>>>> + *
>>>>> + * You should have received a copy of the GNU General Public
>> License
>>>> version
>>>>> + * 2 along with this work; if not, write to the Free Software
>>>> Foundation,
>>>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>>>>> + *
>>>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA
>>>> 94065 USA
>>>>> + * or visit www.oracle.com if you need additional information or
>>>> have any
>>>>> + * questions.
>>>>> + */
>>>>> +
>>>>> +package sun.jvm.hotspot.runtime;
>>>>> +
>>>>> +/** This is a type-safe enum mirroring the ThreadState enum in
>>>>> + osThread.hpp. The conversion between the underlying ints
>>>>> + and these values is done in OSThread. */
>>>>> +
>>>>> +public class ThreadState {
>>>>> +
>>>>> +    private String printVal;
>>>>> +
>>>>> +    /** Memory has been allocated but not initialized */
>>>>> +    public static final ThreadState ALLOCATED = new
>>>> ThreadState("allocated");
>>>>> +    /** The thread has been initialized but yet started */
>>>>> +    public static final ThreadState INITIALIZED = new
>>>> ThreadState("initialized");
>>>>> +    /** Has been started and is runnable, but not necessarily
>>>> running */
>>>>> +    public static final ThreadState RUNNABLE = new
>>>> ThreadState("runnable");
>>>>> +    /** Waiting on a contended monitor lock */
>>>>> +    public static final ThreadState MONITOR_WAIT = new
>>>> ThreadState("waiting for monitor entry");
>>>>> +    /** Waiting on a condition variable */
>>>>> +    public static final ThreadState CONDVAR_WAIT = new
>>>> ThreadState("waiting on condition");
>>>>> +    /** Waiting on an Object.wait() call */
>>>>> +    public static final ThreadState OBJECT_WAIT = new
>>>> ThreadState("in Object.wait()");
>>>>> +    /** Suspended at breakpoint */
>>>>> +    public static final ThreadState BREAKPOINTED = new
>>>> ThreadState("at breakpoint");
>>>>> +    /** Thread.sleep() */
>>>>> +    public static final ThreadState SLEEPING = new
>>>> ThreadState("sleeping");
>>>>> +    /** All done, but not reclaimed yet */
>>>>> +    public static final ThreadState ZOMBIE = new
>>>> ThreadState("zombie");
>>>>> +
>>>>> +    private ThreadState(String printVal){
>>>>> +        this.printVal = printVal;
>>>>> +    }
>>>>> +
>>>>> +    public String getPrintVal() {
>>>>> +        return printVal;
>>>>> +    }
>>>>> +}
>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>> @@ -1,5 +1,5 @@
>>>>>    /*
>>>>> - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>> + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>>>>>     *
>>>>>     * This code is free software; you can redistribute it and/or
>> modify
>>>> it
>>>>> @@ -88,6 +88,10 @@
>>>>>                   out.print("----------------- ");
>>>>>                   out.print(th);
>>>>>                   out.println(" -----------------");
>>>>> +               JavaThread jthread = (JavaThread)
>>>> proxyToThread.get(th);
>>>>> +               if (jthread != null) {
>>>>> +                  jthread.printThreadInfoOn(out);
>>>>> +               }
>>>>>                   while (f != null) {
>>>>>                      ClosestSymbol sym = f.closestSymbolToPC();
>>>>>                      Address pc = f.pc();
>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>> @@ -1,5 +1,5 @@
>>>>>    /*
>>>>> - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>> + * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>>>>>     *
>>>>>     * This code is free software; you can redistribute it and/or
>> modify
>>>> it
>>>>> @@ -74,14 +74,7 @@
>>>>>                int i = 1;
>>>>>                for (JavaThread cur = threads.first(); cur != null;
>> cur
>>>> = cur.next(), i++) {
>>>>>                    if (cur.isJavaThread()) {
>>>>> -                    Address sp = cur.getLastJavaSP();
>>>>> -                    tty.print("Thread ");
>>>>> -                    cur.printThreadIDOn(tty);
>>>>> -                    tty.print(": (state = " +
>> cur.getThreadState());
>>>>> -                    if (verbose) {
>>>>> -                        tty.println(", current Java SP = " + sp);
>>>>> -                    }
>>>>> -                    tty.println(')');
>>>>> +                    cur.printThreadInfoOn(tty);
>>>>>                        try {
>>>>>                            for (JavaVFrame vf =
>>>> cur.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
>>>>>                                Method method = vf.getMethod();
>>>>> diff --git a/src/share/vm/runtime/vmStructs.cpp
>>>> b/src/share/vm/runtime/vmStructs.cpp
>>>>> --- a/src/share/vm/runtime/vmStructs.cpp
>>>>> +++ b/src/share/vm/runtime/vmStructs.cpp
>>>>> @@ -981,6 +981,7 @@
>>>>> /************/ \
>>>>> \
>>>>>      volatile_nonstatic_field(OSThread, _interrupted, jint)
>>>> \
>>>>> +  volatile_nonstatic_field(OSThread, _state, ThreadState) \
>>>>> \
>>>>> /************************/ \
>>>>>      /* OopMap and OopMapSet */ \
>>>>> @@ -2186,6 +2187,7 @@
>>>>> declare_integer_type(Generation::Name) \
>>>>> declare_integer_type(InstanceKlass::ClassState) \
>>>>> declare_integer_type(JavaThreadState) \
>>>>> + declare_integer_type(ThreadState) \
>>>>> declare_integer_type(Location::Type) \
>>>>> declare_integer_type(Location::Where) \
>>>>> declare_integer_type(Flag::Flags) \
>>>>> @@ -2443,6 +2445,20 @@
>>>>> declare_constant(JavaThread::_not_terminated) \
>>>>> declare_constant(JavaThread::_thread_exiting) \
>>>>> \
>>>>> + /*******************/ \
>>>>> +  /* JavaThreadState */
>>>> \
>>>>> + /*******************/ \
>>>>> + \
>>>>> + declare_constant(ALLOCATED) \
>>>>> + declare_constant(INITIALIZED) \
>>>>> + declare_constant(RUNNABLE) \
>>>>> + declare_constant(MONITOR_WAIT) \
>>>>> + declare_constant(CONDVAR_WAIT) \
>>>>> + declare_constant(OBJECT_WAIT) \
>>>>> + declare_constant(BREAKPOINTED) \
>>>>> + declare_constant(SLEEPING) \
>>>>> + declare_constant(ZOMBIE) \
>>>>> + \
>>>>> /******************************/ \
>>>>>      /* Klass misc. enum constants */
>>>> \
>>>>> /******************************/ \
>>>>> diff --git a/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>> b/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>>> new file mode 100644
>>>>> --- /dev/null
>>>>> +++ b/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>>> @@ -0,0 +1,87 @@
>>>>> +/*
>>>>> + * Copyright (c) 2017, Oracle and/or its affiliates. All rights
>>>> reserved.
>>>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>>>>> + *
>>>>> + * This code is free software; you can redistribute it and/or
>> modify
>>>> it
>>>>> + * under the terms of the GNU General Public License version 2
>> only,
>>>> as
>>>>> + * published by the Free Software Foundation.
>>>>> + *
>>>>> + * This code is distributed in the hope that it will be useful,
>> but
>>>> WITHOUT
>>>>> + * ANY WARRANTY; without even the implied warranty of
>>>> MERCHANTABILITY or
>>>>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
>>>> License
>>>>> + * version 2 for more details (a copy is included in the LICENSE
>>>> file that
>>>>> + * accompanied this code).
>>>>> + *
>>>>> + * You should have received a copy of the GNU General Public
>> License
>>>> version
>>>>> + * 2 along with this work; if not, write to the Free Software
>>>> Foundation,
>>>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>>>>> + *
>>>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA
>>>> 94065 USA
>>>>> + * or visit www.oracle.com if you need additional information or
>>>> have any
>>>>> + * questions.
>>>>> + */
>>>>> +
>>>>> +import jdk.test.lib.apps.LingeredApp;
>>>>> +import jdk.test.lib.JDKToolLauncher;
>>>>> +import jdk.test.lib.Platform;
>>>>> +import jdk.test.lib.process.OutputAnalyzer;
>>>>> +import jdk.test.lib.Utils;
>>>>> +
>>>>> +/*
>>>>> + * @test
>>>>> + * @library /test/lib
>>>>> + * @run main JhsdbThreadInfoTest
>>>>> + */
>>>>> +public class JhsdbThreadInfoTest {
>>>>> +
>>>>> +    public static void main(String[] args) throws Exception {
>>>>> +
>>>>> +        if (!Platform.shouldSAAttach()) {
>>>>> +            System.out.println("SA attach not expected to work -
>>>> test skipped.");
>>>>> +            return;
>>>>> +        }
>>>>> +
>>>>> +        LingeredApp app = null;
>>>>> +
>>>>> +        try {
>>>>> +            app = LingeredApp.startApp(Utils.getVmOptions());
>>>>> +            System.out.println("Started LingeredApp with pid " +
>>>> app.getPid());
>>>>> +
>>>>> +            JDKToolLauncher jhsdbLauncher =
>>>> JDKToolLauncher.createUsingTestJDK("jhsdb");
>>>>> +
>>>>> +            jhsdbLauncher.addToolArg("jstack");
>>>>> +            jhsdbLauncher.addToolArg("--pid");
>>>>> +            jhsdbLauncher.addToolArg(Long.toString(app.getPid()));
>>>>> +
>>>>> +            ProcessBuilder pb = new ProcessBuilder();
>>>>> +            pb.command(jhsdbLauncher.getCommand());
>>>>> +            Process jhsdb = pb.start();
>>>>> +
>>>>> +            jhsdb.waitFor();
>>>>> +
>>>>> +            OutputAnalyzer out = new OutputAnalyzer(jhsdb);
>>>>> +
>>>>> +            System.out.println(out.getStdout());
>>>>> +            System.err.println(out.getStderr());
>>>>> +
>>>>> +            out.shouldMatch("\".+\" #\\d+ daemon prio=\\d+
>> tid=0x[0-
>>>> 9a-f]+ nid=0x[0-9a-f]+ .+ \\[0x[0-9a-f]+]");
>>>>> +            out.shouldMatch("\"main\" #\\d+ prio=\\d+ tid=0x[0-9a-
>>>> f]+ nid=0x[0-9a-f]+ .+ \\[0x[0-9a-f]+]");
>>>>> +            out.shouldMatch("   java.lang.Thread.State: .+");
>>>>> +            out.shouldMatch("   JavaThread state: _thread_.+");
>>>>> +
>>>>> +            out.shouldNotContain("   java.lang.Thread.State:
>>>> UNKNOWN");
>>>>> +            out.stderrShouldBeEmpty();
>>>>> +
>>>>> +            System.out.println("Test Completed");
>>>>> +
>>>>> +
>>>>> +        } catch (InterruptedException ie) {
>>>>> +            throw new Error("Problem awaiting the child process: "
>> +
>>>> ie, ie);
>>>>> +        } catch (Exception attachE) {
>>>>> +            throw new Error("Couldn't start jhsdb, attach to
>>>> LingeredApp or match ThreadName: " + attachE);
>>>>> +
>>>>> +        } finally {
>>>>> +            LingeredApp.stopApp(app);
>>>>> +        }
>>>>> +    }
>>>>> +}
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On 2017/07/04 23:44, Yasumasa Suenaga wrote:
>>>>>> Hi Chihiro,
>>>>>>
>>>>>> Thank you for updating your patch!
>>>>>> I have a comment to printThreadInfoOn() in JavaThread.java:
>>>>>>
>>>>>>> +
>>>> out.print(String.format("0x%016x",this.getAddress().asLongValue()));
>>>>>>> +    out.print(" nid=");
>>>>>>> +    out.print(String.format("0x%x
>>>> ",this.getOSThread().threadId()));
>>>>>>> +    out.print(getOSThread().getThreadState().getPrintVal());
>>>>>>> +    out.print(" [");
>>>>>>> +    if( this.getLastJavaSP() == null){
>>>>>>> +      out.print(String.format("0x%016x",0L));
>>>>>> You set "0x%016x" to format string for address value.
>>>>>> However, this length is changed by pointer length e.g. "0x%08x"
>>>> should be set on ILP32 platforms.
>>>>>> In case of Linux, Address#toString() generates platform-aware
>> string
>>>> value in DebuggerUtilities#addressValueToString(). So you can use
>>>> Address#toString() if Address is not null.
>>>>>>
>>>>>> Yasumasa
>>>>>>
>>>>>>
>>>>>> On 2017/07/04 0:32, chihiro ito wrote:
>>>>>>> Hi Yasumasa,
>>>>>>>
>>>>>>> Thank you for review, again.
>>>>>>>
>>>>>>>> According to JavaThread::print_on() in thread.cpp , stack
>> address
>>>> in thread dump shows top of page address.
>>>>>>>> If so, can we calculate it as below?
>>>>>>>>
>>>>>>>>     this.getLastJavaSP().andWithMask(~0xFFF)
>>>>>>> Yes, It is also correct. I modified source code to your simple
>> one.
>>>>>>>
>>>>>>>> Are these regex correct?
>>>>>>>> Regex for SP "\\[0x[0-9a-f]+]" should be "\\[0x[0-9a-f]+\\]"
>>>>>>>> (Last backslash is missing.)
>>>>>>> ] that is not paired with [ does not need to be escaped.
>>>>>>>
>>>>>>> following 2 case it print true.
>>>>>>> System.out.println("]".matches("]"));
>>>>>>> System.out.println("]".matches("\\]"));
>>>>>>>
>>>>>>> The source code which modified the logical operation is as
>> follows.
>>>>>>>
>>>>>>> Regards,
>>>>>>> Chihiro
>>>>>>>
>>>>>>>
>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>     /*
>>>>>>> - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>> + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>> HEADER.
>>>>>>>      *
>>>>>>>      * This code is free software; you can redistribute it and/or
>>>> modify it
>>>>>>> @@ -59,20 +59,20 @@
>>>>>>>       // parkBlocker field is new since 1.6
>>>>>>>       private static OopField threadParkBlockerField;
>>>>>>>
>>>>>>> +  private static IntField threadPriorityField;
>>>>>>> +  private static BooleanField threadDaemonField;
>>>>>>> +
>>>>>>>       // possible values of java_lang_Thread::ThreadStatus
>>>>>>>       private static int THREAD_STATUS_NEW;
>>>>>>> -  /*
>>>>>>> -    Other enum constants are not needed as of now. Uncomment
>> these
>>>> as and when needed.
>>>>>>> -    private static int THREAD_STATUS_RUNNABLE;
>>>>>>> -    private static int THREAD_STATUS_SLEEPING;
>>>>>>> -    private static int THREAD_STATUS_IN_OBJECT_WAIT;
>>>>>>> -    private static int THREAD_STATUS_IN_OBJECT_WAIT_TIMED;
>>>>>>> -    private static int THREAD_STATUS_PARKED;
>>>>>>> -    private static int THREAD_STATUS_PARKED_TIMED;
>>>>>>> -    private static int THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER;
>>>>>>> -    private static int THREAD_STATUS_TERMINATED;
>>>>>>> -  */
>>>>>>> +  private static int THREAD_STATUS_RUNNABLE;
>>>>>>> +  private static int THREAD_STATUS_SLEEPING;
>>>>>>> +  private static int THREAD_STATUS_IN_OBJECT_WAIT;
>>>>>>> +  private static int THREAD_STATUS_IN_OBJECT_WAIT_TIMED;
>>>>>>> +  private static int THREAD_STATUS_PARKED;
>>>>>>> +  private static int THREAD_STATUS_PARKED_TIMED;
>>>>>>> +  private static int THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER;
>>>>>>> +  private static int THREAD_STATUS_TERMINATED;
>>>>>>>
>>>>>>>       // java.util.concurrent.locks.AbstractOwnableSynchronizer
>>>> fields
>>>>>>>       private static OopField absOwnSyncOwnerThreadField;
>>>>>>> @@ -229,20 +229,19 @@
>>>>>>>           threadStatusField = (IntField)
>> k.findField("threadStatus",
>>>> "I");
>>>>>>>           threadParkBlockerField = (OopField)
>>>> k.findField("parkBlocker",
>>>>>>>                                          "Ljava/lang/Object;");
>>>>>>> +      threadPriorityField = (IntField) k.findField("priority",
>>>> "I");
>>>>>>> +      threadDaemonField = (BooleanField) k.findField("daemon",
>>>> "Z");
>>>>>>>           TypeDataBase db = VM.getVM().getTypeDataBase();
>>>>>>>           THREAD_STATUS_NEW =
>>>> db.lookupIntConstant("java_lang_Thread::NEW").intValue();
>>>>>>> -      /*
>>>>>>> -        Other enum constants are not needed as of now. Uncomment
>>>> these as and when needed.
>>>>>>> -        THREAD_STATUS_RUNNABLE =
>>>> db.lookupIntConstant("java_lang_Thread::RUNNABLE").intValue();
>>>>>>> -        THREAD_STATUS_SLEEPING =
>>>> db.lookupIntConstant("java_lang_Thread::SLEEPING").intValue();
>>>>>>> -        THREAD_STATUS_IN_OBJECT_WAIT =
>>>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT").intValue();
>>>>>>> -        THREAD_STATUS_IN_OBJECT_WAIT_TIMED =
>>>>
>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT_TIMED").intValue
>>>> ();
>>>>>>> -        THREAD_STATUS_PARKED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED").intValue();
>>>>>>> -        THREAD_STATUS_PARKED_TIMED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED_TIMED").intValue();
>>>>>>> -        THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER =
>>>>
>> db.lookupIntConstant("java_lang_Thread::BLOCKED_ON_MONITOR_ENTER").intV
>>>> alue();
>>>>>>> -        THREAD_STATUS_TERMINATED =
>>>> db.lookupIntConstant("java_lang_Thread::TERMINATED").intValue();
>>>>>>> -      */
>>>>>>> +      THREAD_STATUS_RUNNABLE =
>>>> db.lookupIntConstant("java_lang_Thread::RUNNABLE").intValue();
>>>>>>> +      THREAD_STATUS_SLEEPING =
>>>> db.lookupIntConstant("java_lang_Thread::SLEEPING").intValue();
>>>>>>> +      THREAD_STATUS_IN_OBJECT_WAIT =
>>>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT").intValue();
>>>>>>> +      THREAD_STATUS_IN_OBJECT_WAIT_TIMED =
>>>>
>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT_TIMED").intValue
>>>> ();
>>>>>>> +      THREAD_STATUS_PARKED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED").intValue();
>>>>>>> +      THREAD_STATUS_PARKED_TIMED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED_TIMED").intValue();
>>>>>>> +      THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER =
>>>>
>> db.lookupIntConstant("java_lang_Thread::BLOCKED_ON_MONITOR_ENTER").intV
>>>> alue();
>>>>>>> +      THREAD_STATUS_TERMINATED =
>>>> db.lookupIntConstant("java_lang_Thread::TERMINATED").intValue();
>>>>>>>           if (Assert.ASSERTS_ENABLED) {
>>>>>>>             // it is okay to miss threadStatusField, because this
>> was
>>>>>>> @@ -331,4 +330,46 @@
>>>>>>>           return absOwnSyncOwnerThreadField.getValue(oop);
>>>>>>>         }
>>>>>>>       }
>>>>>>> +
>>>>>>> +  public static int threadOopGetPriority(Oop threadOop) {
>>>>>>> +    initThreadFields();
>>>>>>> +    if (threadPriorityField != null) {
>>>>>>> +      return threadPriorityField.getValue(threadOop);
>>>>>>> +    } else {
>>>>>>> +      return 0;
>>>>>>> +    }
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public static boolean threadOopGetDaemon(Oop threadOop) {
>>>>>>> +    initThreadFields();
>>>>>>> +    if (threadDaemonField != null) {
>>>>>>> +      return threadDaemonField.getValue(threadOop);
>>>>>>> +    } else {
>>>>>>> +      return false;
>>>>>>> +    }
>>>>>>> +  }
>>>>>>> +
>>>>>>> +  public static String threadOopGetThreadStatusName(Oop
>> threadOop)
>>>> {
>>>>>>> +    int status =
>> OopUtilities.threadOopGetThreadStatus(threadOop);
>>>>>>> +    if( status == THREAD_STATUS_NEW ){
>>>>>>> +      return "NEW";
>>>>>>> +    }else if(status == THREAD_STATUS_RUNNABLE ){
>>>>>>> +      return "RUNNABLE";
>>>>>>> +    }else if(status == THREAD_STATUS_SLEEPING ){
>>>>>>> +      return "TIMED_WAITING (sleeping)";
>>>>>>> +    }else if(status == THREAD_STATUS_IN_OBJECT_WAIT ){
>>>>>>> +      return "WAITING (on object monitor)";
>>>>>>> +    }else if(status == THREAD_STATUS_IN_OBJECT_WAIT_TIMED ){
>>>>>>> +      return "TIMED_WAITING (on object monitor)";
>>>>>>> +    }else if(status == THREAD_STATUS_PARKED ){
>>>>>>> +      return "WAITING (parking)";
>>>>>>> +    }else if(status == THREAD_STATUS_PARKED_TIMED ){
>>>>>>> +      return "TIMED_WAITING (parking)";
>>>>>>> +    }else if(status == THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER ){
>>>>>>> +      return "BLOCKED (on object monitor)";
>>>>>>> +    }else if(status == THREAD_STATUS_TERMINATED ){
>>>>>>> +      return "TERMINATED";
>>>>>>> +    }
>>>>>>> +    return "UNKNOWN";
>>>>>>> +  }
>>>>>>>     }
>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>>>> @@ -475,4 +475,35 @@
>>>>>>>         return access.getLastSP(addr);
>>>>>>>       }
>>>>>>>
>>>>>>> +
>>>>>>> +  public void printThreadInfoOn(PrintStream out){
>>>>>>> +
>>>>>>> +    Oop threadOop = this.getThreadObj();
>>>>>>> +
>>>>>>> +    out.print("\"");
>>>>>>> +    out.print(this.getThreadName());
>>>>>>> +    out.print("\" #");
>>>>>>> +    out.print(OopUtilities.threadOopGetTID(threadOop));
>>>>>>> +    if( OopUtilities.threadOopGetDaemon(threadOop) ){
>>>>>>> +      out.print(" daemon");
>>>>>>> +    }
>>>>>>> +    out.print(" prio=");
>>>>>>> +    out.print(OopUtilities.threadOopGetPriority(threadOop));
>>>>>>> +    out.print(" tid=");
>>>>>>> +
>>>> out.print(String.format("0x%016x",this.getAddress().asLongValue()));
>>>>>>> +    out.print(" nid=");
>>>>>>> +    out.print(String.format("0x%x
>>>> ",this.getOSThread().threadId()));
>>>>>>> +    out.print(getOSThread().getThreadState().getPrintVal());
>>>>>>> +    out.print(" [");
>>>>>>> +    if( this.getLastJavaSP() == null){
>>>>>>> +      out.print(String.format("0x%016x",0L));
>>>>>>> +    } else {
>>>>>>> +      out.print(this.getLastJavaSP().andWithMask(~0xFFF));
>>>>>>> +    }
>>>>>>> +    out.println("]");
>>>>>>> +    out.print("   java.lang.Thread.State: ");
>>>>>>> +
>>>> out.println(OopUtilities.threadOopGetThreadStatusName(threadOop));
>>>>>>> +    out.print("   JavaThread state: _thread_");
>>>>>>> + out.println(this.getThreadState().toString().toLowerCase());
>>>>>>> +  }
>>>>>>>     }
>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>     /*
>>>>>>> - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>> + * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>> HEADER.
>>>>>>>      *
>>>>>>>      * This code is free software; you can redistribute it and/or
>>>> modify it
>>>>>>> @@ -33,6 +33,19 @@
>>>>>>>     public class OSThread extends VMObject {
>>>>>>>         private static JIntField interruptedField;
>>>>>>>         private static Field threadIdField;
>>>>>>> +    private static CIntegerField threadStateField;
>>>>>>> +
>>>>>>> +    // ThreadStates read from underlying process
>>>>>>> +    private static int ALLOCATED;
>>>>>>> +    private static int INITIALIZED;
>>>>>>> +    private static int RUNNABLE;
>>>>>>> +    private static int MONITOR_WAIT;
>>>>>>> +    private static int CONDVAR_WAIT;
>>>>>>> +    private static int OBJECT_WAIT;
>>>>>>> +    private static int BREAKPOINTED;
>>>>>>> +    private static int SLEEPING;
>>>>>>> +    private static int ZOMBIE;
>>>>>>> +
>>>>>>>         static {
>>>>>>>             VM.registerVMInitializedObserver(new Observer() {
>>>>>>>                 public void update(Observable o, Object data) {
>>>>>>> @@ -45,6 +58,17 @@
>>>>>>>             Type type = db.lookupType("OSThread");
>>>>>>>             interruptedField = type.getJIntField("_interrupted");
>>>>>>>             threadIdField = type.getField("_thread_id");
>>>>>>> +        threadStateField = type.getCIntegerField("_state");
>>>>>>> +
>>>>>>> +        ALLOCATED =
>> db.lookupIntConstant("ALLOCATED").intValue();
>>>>>>> +        INITIALIZED =
>>>> db.lookupIntConstant("INITIALIZED").intValue();
>>>>>>> +        RUNNABLE = db.lookupIntConstant("RUNNABLE").intValue();
>>>>>>> +        MONITOR_WAIT =
>>>> db.lookupIntConstant("MONITOR_WAIT").intValue();
>>>>>>> +        CONDVAR_WAIT =
>>>> db.lookupIntConstant("CONDVAR_WAIT").intValue();
>>>>>>> +        OBJECT_WAIT =
>>>> db.lookupIntConstant("OBJECT_WAIT").intValue();
>>>>>>> +        BREAKPOINTED =
>>>> db.lookupIntConstant("BREAKPOINTED").intValue();
>>>>>>> +        SLEEPING = db.lookupIntConstant("SLEEPING").intValue();
>>>>>>> +        ZOMBIE = db.lookupIntConstant("ZOMBIE").intValue();
>>>>>>>         }
>>>>>>>
>>>>>>>         public OSThread(Address addr) {
>>>>>>> @@ -59,4 +83,28 @@
>>>>>>>             return threadIdField.getJInt(addr);
>>>>>>>         }
>>>>>>>
>>>>>>> +    public ThreadState getThreadState() {
>>>>>>> +        int val = (int)threadStateField.getValue(addr);
>>>>>>> +        if (val ==  ALLOCATED) {
>>>>>>> +            return ThreadState.ALLOCATED;
>>>>>>> +        } else if (val ==  INITIALIZED) {
>>>>>>> +            return ThreadState.INITIALIZED;
>>>>>>> +        } else if (val ==  RUNNABLE) {
>>>>>>> +            return ThreadState.RUNNABLE;
>>>>>>> +        } else if (val ==  MONITOR_WAIT) {
>>>>>>> +            return ThreadState.MONITOR_WAIT;
>>>>>>> +        } else if (val ==  CONDVAR_WAIT) {
>>>>>>> +            return ThreadState.CONDVAR_WAIT;
>>>>>>> +        } else if (val ==  OBJECT_WAIT) {
>>>>>>> +            return ThreadState.OBJECT_WAIT;
>>>>>>> +        } else if (val ==  BREAKPOINTED) {
>>>>>>> +            return ThreadState.BREAKPOINTED;
>>>>>>> +        } else if (val ==  SLEEPING) {
>>>>>>> +            return ThreadState.SLEEPING;
>>>>>>> +        } else if (val ==  ZOMBIE) {
>>>>>>> +            return ThreadState.ZOMBIE;
>>>>>>> +        } else {
>>>>>>> +            throw new RuntimeException("Illegal thread state " +
>>>> val);
>>>>>>> +        }
>>>>>>> +    }
>>>>>>>     }
>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>>>> new file mode 100644
>>>>>>> --- /dev/null
>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>>>> @@ -0,0 +1,60 @@
>>>>>>> +/*
>>>>>>> + * Copyright (c) 2017, Oracle and/or its affiliates. All rights
>>>> reserved.
>>>>>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>>>>>>> + *
>>>>>>> + * This code is free software; you can redistribute it and/or
>>>> modify it
>>>>>>> + * under the terms of the GNU General Public License version 2
>>>> only, as
>>>>>>> + * published by the Free Software Foundation.
>>>>>>> + *
>>>>>>> + * This code is distributed in the hope that it will be useful,
>>>> but WITHOUT
>>>>>>> + * ANY WARRANTY; without even the implied warranty of
>>>> MERCHANTABILITY or
>>>>>>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
>>>> License
>>>>>>> + * version 2 for more details (a copy is included in the LICENSE
>>>> file that
>>>>>>> + * accompanied this code).
>>>>>>> + *
>>>>>>> + * You should have received a copy of the GNU General Public
>>>> License version
>>>>>>> + * 2 along with this work; if not, write to the Free Software
>>>> Foundation,
>>>>>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>>>>>>> + *
>>>>>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA
>>>> 94065 USA
>>>>>>> + * or visit www.oracle.com if you need additional information or
>>>> have any
>>>>>>> + * questions.
>>>>>>> + */
>>>>>>> +
>>>>>>> +package sun.jvm.hotspot.runtime;
>>>>>>> +
>>>>>>> +/** This is a type-safe enum mirroring the ThreadState enum in
>>>>>>> + osThread.hpp. The conversion between the underlying ints
>>>>>>> + and these values is done in OSThread. */
>>>>>>> +
>>>>>>> +public class ThreadState {
>>>>>>> +
>>>>>>> +    private String printVal;
>>>>>>> +
>>>>>>> +    /** Memory has been allocated but not initialized */
>>>>>>> +    public static final ThreadState ALLOCATED = new
>>>> ThreadState("allocated");
>>>>>>> +    /** The thread has been initialized but yet started */
>>>>>>> +    public static final ThreadState INITIALIZED = new
>>>> ThreadState("initialized");
>>>>>>> +    /** Has been started and is runnable, but not necessarily
>>>> running */
>>>>>>> +    public static final ThreadState RUNNABLE = new
>>>> ThreadState("runnable");
>>>>>>> +    /** Waiting on a contended monitor lock */
>>>>>>> +    public static final ThreadState MONITOR_WAIT = new
>>>> ThreadState("waiting for monitor entry");
>>>>>>> +    /** Waiting on a condition variable */
>>>>>>> +    public static final ThreadState CONDVAR_WAIT = new
>>>> ThreadState("waiting on condition");
>>>>>>> +    /** Waiting on an Object.wait() call */
>>>>>>> +    public static final ThreadState OBJECT_WAIT = new
>>>> ThreadState("in Object.wait()");
>>>>>>> +    /** Suspended at breakpoint */
>>>>>>> +    public static final ThreadState BREAKPOINTED = new
>>>> ThreadState("at breakpoint");
>>>>>>> +    /** Thread.sleep() */
>>>>>>> +    public static final ThreadState SLEEPING = new
>>>> ThreadState("sleeping");
>>>>>>> +    /** All done, but not reclaimed yet */
>>>>>>> +    public static final ThreadState ZOMBIE = new
>>>> ThreadState("zombie");
>>>>>>> +
>>>>>>> +    private ThreadState(String printVal){
>>>>>>> +        this.printVal = printVal;
>>>>>>> +    }
>>>>>>> +
>>>>>>> +    public String getPrintVal() {
>>>>>>> +        return printVal;
>>>>>>> +    }
>>>>>>> +}
>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>     /*
>>>>>>> - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>> + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>> HEADER.
>>>>>>>      *
>>>>>>>      * This code is free software; you can redistribute it and/or
>>>> modify it
>>>>>>> @@ -88,6 +88,10 @@
>>>>>>>                    out.print("----------------- ");
>>>>>>>                    out.print(th);
>>>>>>>                    out.println(" -----------------");
>>>>>>> +               JavaThread jthread = (JavaThread)
>>>> proxyToThread.get(th);
>>>>>>> +               if (jthread != null) {
>>>>>>> +                  jthread.printThreadInfoOn(out);
>>>>>>> +               }
>>>>>>>                    while (f != null) {
>>>>>>>                       ClosestSymbol sym = f.closestSymbolToPC();
>>>>>>>                       Address pc = f.pc();
>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>     /*
>>>>>>> - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>> + * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>> HEADER.
>>>>>>>      *
>>>>>>>      * This code is free software; you can redistribute it and/or
>>>> modify it
>>>>>>> @@ -74,14 +74,7 @@
>>>>>>>                 int i = 1;
>>>>>>>                 for (JavaThread cur = threads.first(); cur !=
>> null;
>>>> cur = cur.next(), i++) {
>>>>>>>                     if (cur.isJavaThread()) {
>>>>>>> -                    Address sp = cur.getLastJavaSP();
>>>>>>> -                    tty.print("Thread ");
>>>>>>> -                    cur.printThreadIDOn(tty);
>>>>>>> -                    tty.print(": (state = " +
>>>> cur.getThreadState());
>>>>>>> -                    if (verbose) {
>>>>>>> -                        tty.println(", current Java SP = " +
>> sp);
>>>>>>> -                    }
>>>>>>> -                    tty.println(')');
>>>>>>> +                    cur.printThreadInfoOn(tty);
>>>>>>>                         try {
>>>>>>>                             for (JavaVFrame vf =
>>>> cur.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
>>>>>>>                                 Method method = vf.getMethod();
>>>>>>> diff --git a/src/share/vm/runtime/vmStructs.cpp
>>>> b/src/share/vm/runtime/vmStructs.cpp
>>>>>>> --- a/src/share/vm/runtime/vmStructs.cpp
>>>>>>> +++ b/src/share/vm/runtime/vmStructs.cpp
>>>>>>> @@ -981,6 +981,7 @@
>>>>>>> /************/ \
>>>>>>> \
>>>>>>>       volatile_nonstatic_field(OSThread, _interrupted, jint)
>>>> \
>>>>>>> +  volatile_nonstatic_field(OSThread, _state, ThreadState)
>>>> \
>>>>>>> \
>>>>>>> /************************/ \
>>>>>>>       /* OopMap and OopMapSet */ \
>>>>>>> @@ -2186,6 +2187,7 @@
>>>>>>> declare_integer_type(Generation::Name) \
>>>>>>> declare_integer_type(InstanceKlass::ClassState) \
>>>>>>> declare_integer_type(JavaThreadState) \
>>>>>>> + declare_integer_type(ThreadState) \
>>>>>>> declare_integer_type(Location::Type) \
>>>>>>> declare_integer_type(Location::Where) \
>>>>>>> declare_integer_type(Flag::Flags) \
>>>>>>> @@ -2443,6 +2445,20 @@
>>>>>>> declare_constant(JavaThread::_not_terminated) \
>>>>>>> declare_constant(JavaThread::_thread_exiting) \
>>>>>>> \
>>>>>>> + /*******************/ \
>>>>>>> +  /* JavaThreadState */
>>>> \
>>>>>>> + /*******************/ \
>>>>>>> + \
>>>>>>> + declare_constant(ALLOCATED) \
>>>>>>> + declare_constant(INITIALIZED) \
>>>>>>> + declare_constant(RUNNABLE) \
>>>>>>> + declare_constant(MONITOR_WAIT) \
>>>>>>> + declare_constant(CONDVAR_WAIT) \
>>>>>>> + declare_constant(OBJECT_WAIT) \
>>>>>>> + declare_constant(BREAKPOINTED) \
>>>>>>> + declare_constant(SLEEPING) \
>>>>>>> + declare_constant(ZOMBIE) \
>>>>>>> + \
>>>>>>> /******************************/ \
>>>>>>>       /* Klass misc. enum constants */
>>>> \
>>>>>>> /******************************/ \
>>>>>>> diff --git a/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>> b/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>>>>> new file mode 100644
>>>>>>> --- /dev/null
>>>>>>> +++ b/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>>>>> @@ -0,0 +1,87 @@
>>>>>>> +/*
>>>>>>> + * Copyright (c) 2017, Oracle and/or its affiliates. All rights
>>>> reserved.
>>>>>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
>>>>>>> + *
>>>>>>> + * This code is free software; you can redistribute it and/or
>>>> modify it
>>>>>>> + * under the terms of the GNU General Public License version 2
>>>> only, as
>>>>>>> + * published by the Free Software Foundation.
>>>>>>> + *
>>>>>>> + * This code is distributed in the hope that it will be useful,
>>>> but WITHOUT
>>>>>>> + * ANY WARRANTY; without even the implied warranty of
>>>> MERCHANTABILITY or
>>>>>>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
>>>> License
>>>>>>> + * version 2 for more details (a copy is included in the LICENSE
>>>> file that
>>>>>>> + * accompanied this code).
>>>>>>> + *
>>>>>>> + * You should have received a copy of the GNU General Public
>>>> License version
>>>>>>> + * 2 along with this work; if not, write to the Free Software
>>>> Foundation,
>>>>>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
>>>>>>> + *
>>>>>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA
>>>> 94065 USA
>>>>>>> + * or visit www.oracle.com if you need additional information or
>>>> have any
>>>>>>> + * questions.
>>>>>>> + */
>>>>>>> +
>>>>>>> +import jdk.test.lib.apps.LingeredApp;
>>>>>>> +import jdk.test.lib.JDKToolLauncher;
>>>>>>> +import jdk.test.lib.Platform;
>>>>>>> +import jdk.test.lib.process.OutputAnalyzer;
>>>>>>> +import jdk.test.lib.Utils;
>>>>>>> +
>>>>>>> +/*
>>>>>>> + * @test
>>>>>>> + * @library /test/lib
>>>>>>> + * @run main JhsdbThreadInfoTest
>>>>>>> + */
>>>>>>> +public class JhsdbThreadInfoTest {
>>>>>>> +
>>>>>>> +    public static void main(String[] args) throws Exception {
>>>>>>> +
>>>>>>> +        if (!Platform.shouldSAAttach()) {
>>>>>>> +            System.out.println("SA attach not expected to work -
>>>> test skipped.");
>>>>>>> +            return;
>>>>>>> +        }
>>>>>>> +
>>>>>>> +        LingeredApp app = null;
>>>>>>> +
>>>>>>> +        try {
>>>>>>> +            app = LingeredApp.startApp(Utils.getVmOptions());
>>>>>>> +            System.out.println("Started LingeredApp with pid " +
>>>> app.getPid());
>>>>>>> +
>>>>>>> +            JDKToolLauncher jhsdbLauncher =
>>>> JDKToolLauncher.createUsingTestJDK("jhsdb");
>>>>>>> +
>>>>>>> +            jhsdbLauncher.addToolArg("jstack");
>>>>>>> +            jhsdbLauncher.addToolArg("--pid");
>>>>>>> + jhsdbLauncher.addToolArg(Long.toString(app.getPid()));
>>>>>>> +
>>>>>>> +            ProcessBuilder pb = new ProcessBuilder();
>>>>>>> +            pb.command(jhsdbLauncher.getCommand());
>>>>>>> +            Process jhsdb = pb.start();
>>>>>>> +
>>>>>>> +            jhsdb.waitFor();
>>>>>>> +
>>>>>>> +            OutputAnalyzer out = new OutputAnalyzer(jhsdb);
>>>>>>> +
>>>>>>> +            System.out.println(out.getStdout());
>>>>>>> +            System.err.println(out.getStderr());
>>>>>>> +
>>>>>>> +            out.shouldMatch("\".+\" #\\d+ daemon prio=\\d+
>>>> tid=0x[0-9a-f]+ nid=0x[0-9a-f]+ .+ \\[0x[0-9a-f]+]");
>>>>>>> +            out.shouldMatch("\"main\" #\\d+ prio=\\d+ tid=0x[0-
>> 9a-
>>>> f]+ nid=0x[0-9a-f]+ .+ \\[0x[0-9a-f]+]");
>>>>>>> +            out.shouldMatch("   java.lang.Thread.State: .+");
>>>>>>> +            out.shouldMatch("   JavaThread state: _thread_.+");
>>>>>>> +
>>>>>>> +            out.shouldNotContain("   java.lang.Thread.State:
>>>> UNKNOWN");
>>>>>>> +            out.stderrShouldBeEmpty();
>>>>>>> +
>>>>>>> +            System.out.println("Test Completed");
>>>>>>> +
>>>>>>> +
>>>>>>> +        } catch (InterruptedException ie) {
>>>>>>> +            throw new Error("Problem awaiting the child process:
>> "
>>>> + ie, ie);
>>>>>>> +        } catch (Exception attachE) {
>>>>>>> +            throw new Error("Couldn't start jhsdb, attach to
>>>> LingeredApp or match ThreadName: " + attachE);
>>>>>>> +
>>>>>>> +        } finally {
>>>>>>> +            LingeredApp.stopApp(app);
>>>>>>> +        }
>>>>>>> +    }
>>>>>>> +}
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 2017/07/02 21:44, Yasumasa Suenaga wrote:
>>>>>>>> Hi Chihiro,
>>>>>>>>
>>>>>>>>
>>>>>>>> printThreadInfoOn() in JavaThread.java:
>>>>>>>>> +      Address maskAddress =
>>>> this.getLastJavaSP().andWithMask(0xFFF);
>>>>>>>>> +
>>>>
>> out.print(this.getLastJavaSP().xorWithMask(maskAddress.asLongValue()));
>>>>>>>> IMHO it is complex a bit.
>>>>>>>> According to JavaThread::print_on() in thread.cpp , stack
>> address
>>>> in thread dump shows top of page address.
>>>>>>>> If so, can we calculate it as below?
>>>>>>>>
>>>>>>>>     this.getLastJavaSP().andWithMask(~0xFFF)
>>>>>>>>
>>>>>>>>
>>>>>>>> JhsdbThreadInfoTest.java:
>>>>>>>>> +            out.shouldMatch("\".+\" #\\d+ daemon prio=\\d+
>>>> tid=0x[0-9a-f]+ nid=0x[0-9a-f]+ .+ \\[0x[0-9a-f]+]");
>>>>>>>>> +            out.shouldMatch("\"main\" #\\d+ prio=\\d+
>> tid=0x[0-
>>>> 9a-f]+ nid=0x[0-9a-f]+ .+ \\[0x[0-9a-f]+]");
>>>>>>>> Are these regex correct?
>>>>>>>> Regex for SP "\\[0x[0-9a-f]+]" should be "\\[0x[0-9a-f]+\\]"
>>>>>>>> (Last backslash is missing.)
>>>>>>>>
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>>
>>>>>>>> Yasumasa
>>>>>>>>
>>>>>>>>
>>>>>>>> On 2017/07/02 16:43, chihiro ito wrote:
>>>>>>>>> Hi Yasumasa,
>>>>>>>>>
>>>>>>>>> Thank you for your review. I modified source code following
>> your
>>>> advice.
>>>>>>>>> I applied this to latest source code and passed jtreg.
>>>>>>>>>
>>>>>>>>> Could somebody possibly be sponsor and commit this as cito ?
>>>>>>>>>
>>>>>>>>> Regards,
>>>>>>>>> Chihiro
>>>>>>>>>
>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>>>     /*
>>>>>>>>> - * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>>> + * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>>>      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>      *
>>>>>>>>>      * This code is free software; you can redistribute it
>> and/or
>>>> modify it
>>>>>>>>> @@ -59,20 +59,20 @@
>>>>>>>>>       // parkBlocker field is new since 1.6
>>>>>>>>>       private static OopField threadParkBlockerField;
>>>>>>>>>
>>>>>>>>> +  private static IntField threadPriorityField;
>>>>>>>>> +  private static BooleanField threadDaemonField;
>>>>>>>>> +
>>>>>>>>>       // possible values of java_lang_Thread::ThreadStatus
>>>>>>>>>       private static int THREAD_STATUS_NEW;
>>>>>>>>> -  /*
>>>>>>>>> -    Other enum constants are not needed as of now. Uncomment
>>>> these as and when needed.
>>>>>>>>> -    private static int THREAD_STATUS_RUNNABLE;
>>>>>>>>> -    private static int THREAD_STATUS_SLEEPING;
>>>>>>>>> -    private static int THREAD_STATUS_IN_OBJECT_WAIT;
>>>>>>>>> -    private static int THREAD_STATUS_IN_OBJECT_WAIT_TIMED;
>>>>>>>>> -    private static int THREAD_STATUS_PARKED;
>>>>>>>>> -    private static int THREAD_STATUS_PARKED_TIMED;
>>>>>>>>> -    private static int THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER;
>>>>>>>>> -    private static int THREAD_STATUS_TERMINATED;
>>>>>>>>> -  */
>>>>>>>>> +  private static int THREAD_STATUS_RUNNABLE;
>>>>>>>>> +  private static int THREAD_STATUS_SLEEPING;
>>>>>>>>> +  private static int THREAD_STATUS_IN_OBJECT_WAIT;
>>>>>>>>> +  private static int THREAD_STATUS_IN_OBJECT_WAIT_TIMED;
>>>>>>>>> +  private static int THREAD_STATUS_PARKED;
>>>>>>>>> +  private static int THREAD_STATUS_PARKED_TIMED;
>>>>>>>>> +  private static int THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER;
>>>>>>>>> +  private static int THREAD_STATUS_TERMINATED;
>>>>>>>>>
>>>>>>>>>       // java.util.concurrent.locks.AbstractOwnableSynchronizer
>>>> fields
>>>>>>>>>       private static OopField absOwnSyncOwnerThreadField;
>>>>>>>>> @@ -229,20 +229,19 @@
>>>>>>>>>           threadStatusField = (IntField)
>>>> k.findField("threadStatus", "I");
>>>>>>>>>           threadParkBlockerField = (OopField)
>>>> k.findField("parkBlocker",
>>>>>>>>> "Ljava/lang/Object;");
>>>>>>>>> +      threadPriorityField = (IntField) k.findField("priority",
>>>> "I");
>>>>>>>>> +      threadDaemonField = (BooleanField) k.findField("daemon",
>>>> "Z");
>>>>>>>>>           TypeDataBase db = VM.getVM().getTypeDataBase();
>>>>>>>>>           THREAD_STATUS_NEW =
>>>> db.lookupIntConstant("java_lang_Thread::NEW").intValue();
>>>>>>>>> -      /*
>>>>>>>>> -        Other enum constants are not needed as of now.
>> Uncomment
>>>> these as and when needed.
>>>>>>>>> -        THREAD_STATUS_RUNNABLE =
>>>> db.lookupIntConstant("java_lang_Thread::RUNNABLE").intValue();
>>>>>>>>> -        THREAD_STATUS_SLEEPING =
>>>> db.lookupIntConstant("java_lang_Thread::SLEEPING").intValue();
>>>>>>>>> -        THREAD_STATUS_IN_OBJECT_WAIT =
>>>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT").intValue();
>>>>>>>>> -        THREAD_STATUS_IN_OBJECT_WAIT_TIMED =
>>>>
>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT_TIMED").intValue
>>>> ();
>>>>>>>>> -        THREAD_STATUS_PARKED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED").intValue();
>>>>>>>>> -        THREAD_STATUS_PARKED_TIMED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED_TIMED").intValue();
>>>>>>>>> -        THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER =
>>>>
>> db.lookupIntConstant("java_lang_Thread::BLOCKED_ON_MONITOR_ENTER").intV
>>>> alue();
>>>>>>>>> -        THREAD_STATUS_TERMINATED =
>>>> db.lookupIntConstant("java_lang_Thread::TERMINATED").intValue();
>>>>>>>>> -      */
>>>>>>>>> +      THREAD_STATUS_RUNNABLE =
>>>> db.lookupIntConstant("java_lang_Thread::RUNNABLE").intValue();
>>>>>>>>> +      THREAD_STATUS_SLEEPING =
>>>> db.lookupIntConstant("java_lang_Thread::SLEEPING").intValue();
>>>>>>>>> +      THREAD_STATUS_IN_OBJECT_WAIT =
>>>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT").intValue();
>>>>>>>>> +      THREAD_STATUS_IN_OBJECT_WAIT_TIMED =
>>>>
>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT_TIMED").intValue
>>>> ();
>>>>>>>>> +      THREAD_STATUS_PARKED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED").intValue();
>>>>>>>>> +      THREAD_STATUS_PARKED_TIMED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED_TIMED").intValue();
>>>>>>>>> +      THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER =
>>>>
>> db.lookupIntConstant("java_lang_Thread::BLOCKED_ON_MONITOR_ENTER").intV
>>>> alue();
>>>>>>>>> +      THREAD_STATUS_TERMINATED =
>>>> db.lookupIntConstant("java_lang_Thread::TERMINATED").intValue();
>>>>>>>>>           if (Assert.ASSERTS_ENABLED) {
>>>>>>>>>             // it is okay to miss threadStatusField, because
>> this
>>>> was
>>>>>>>>> @@ -331,4 +330,46 @@
>>>>>>>>>           return absOwnSyncOwnerThreadField.getValue(oop);
>>>>>>>>>         }
>>>>>>>>>       }
>>>>>>>>> +
>>>>>>>>> +  public static int threadOopGetPriority(Oop threadOop) {
>>>>>>>>> +    initThreadFields();
>>>>>>>>> +    if (threadPriorityField != null) {
>>>>>>>>> +      return threadPriorityField.getValue(threadOop);
>>>>>>>>> +    } else {
>>>>>>>>> +      return 0;
>>>>>>>>> +    }
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public static boolean threadOopGetDaemon(Oop threadOop) {
>>>>>>>>> +    initThreadFields();
>>>>>>>>> +    if (threadDaemonField != null) {
>>>>>>>>> +      return threadDaemonField.getValue(threadOop);
>>>>>>>>> +    } else {
>>>>>>>>> +      return false;
>>>>>>>>> +    }
>>>>>>>>> +  }
>>>>>>>>> +
>>>>>>>>> +  public static String threadOopGetThreadStatusName(Oop
>>>> threadOop) {
>>>>>>>>> +    int status =
>>>> OopUtilities.threadOopGetThreadStatus(threadOop);
>>>>>>>>> +    if( status == THREAD_STATUS_NEW ){
>>>>>>>>> +      return "NEW";
>>>>>>>>> +    }else if(status == THREAD_STATUS_RUNNABLE ){
>>>>>>>>> +      return "RUNNABLE";
>>>>>>>>> +    }else if(status == THREAD_STATUS_SLEEPING ){
>>>>>>>>> +      return "TIMED_WAITING (sleeping)";
>>>>>>>>> +    }else if(status == THREAD_STATUS_IN_OBJECT_WAIT ){
>>>>>>>>> +      return "WAITING (on object monitor)";
>>>>>>>>> +    }else if(status == THREAD_STATUS_IN_OBJECT_WAIT_TIMED ){
>>>>>>>>> +      return "TIMED_WAITING (on object monitor)";
>>>>>>>>> +    }else if(status == THREAD_STATUS_PARKED ){
>>>>>>>>> +      return "WAITING (parking)";
>>>>>>>>> +    }else if(status == THREAD_STATUS_PARKED_TIMED ){
>>>>>>>>> +      return "TIMED_WAITING (parking)";
>>>>>>>>> +    }else if(status == THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER
>> ){
>>>>>>>>> +      return "BLOCKED (on object monitor)";
>>>>>>>>> +    }else if(status == THREAD_STATUS_TERMINATED ){
>>>>>>>>> +      return "TERMINATED";
>>>>>>>>> +    }
>>>>>>>>> +    return "UNKNOWN";
>>>>>>>>> +  }
>>>>>>>>>     }
>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>>>>>> @@ -475,4 +475,36 @@
>>>>>>>>>         return access.getLastSP(addr);
>>>>>>>>>       }
>>>>>>>>>
>>>>>>>>> +
>>>>>>>>> +  public void printThreadInfoOn(PrintStream out){
>>>>>>>>> +
>>>>>>>>> +    Oop threadOop = this.getThreadObj();
>>>>>>>>> +
>>>>>>>>> +    out.print("\"");
>>>>>>>>> +    out.print(this.getThreadName());
>>>>>>>>> +    out.print("\" #");
>>>>>>>>> +    out.print(OopUtilities.threadOopGetTID(threadOop));
>>>>>>>>> +    if( OopUtilities.threadOopGetDaemon(threadOop) ){
>>>>>>>>> +      out.print(" daemon");
>>>>>>>>> +    }
>>>>>>>>> +    out.print(" prio=");
>>>>>>>>> + out.print(OopUtilities.threadOopGetPriority(threadOop));
>>>>>>>>> +    out.print(" tid=");
>>>>>>>>> +
>>>> out.print(String.format("0x%016x",this.getAddress().asLongValue()));
>>>>>>>>> +    out.print(" nid=");
>>>>>>>>> +    out.print(String.format("0x%x
>>>> ",this.getOSThread().threadId()));
>>>>>>>>> + out.print(getOSThread().getThreadState().getPrintVal());
>>>>>>>>> +    out.print(" [");
>>>>>>>>> +    if( this.getLastJavaSP() == null){
>>>>>>>>> +      out.print(String.format("0x%016x",0L));
>>>>>>>>> +    } else {
>>>>>>>>> +      Address maskAddress =
>>>> this.getLastJavaSP().andWithMask(0xFFF);
>>>>>>>>> +
>>>>
>> out.print(this.getLastJavaSP().xorWithMask(maskAddress.asLongValue()));
>>>>>>>>> +    }
>>>>>>>>> +    out.println("]");
>>>>>>>>> +    out.print("   java.lang.Thread.State: ");
>>>>>>>>> +
>>>> out.println(OopUtilities.threadOopGetThreadStatusName(threadOop));
>>>>>>>>> +    out.print("   JavaThread state: _thread_");
>>>>>>>>> + out.println(this.getThreadState().toString().toLowerCase());
>>>>>>>>> +  }
>>>>>>>>>     }
>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>>>     /*
>>>>>>>>> - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>>> + * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>>>      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>      *
>>>>>>>>>      * This code is free software; you can redistribute it
>> and/or
>>>> modify it
>>>>>>>>> @@ -33,6 +33,19 @@
>>>>>>>>>     public class OSThread extends VMObject {
>>>>>>>>>         private static JIntField interruptedField;
>>>>>>>>>         private static Field threadIdField;
>>>>>>>>> +    private static CIntegerField threadStateField;
>>>>>>>>> +
>>>>>>>>> +    // ThreadStates read from underlying process
>>>>>>>>> +    private static int ALLOCATED;
>>>>>>>>> +    private static int INITIALIZED;
>>>>>>>>> +    private static int RUNNABLE;
>>>>>>>>> +    private static int MONITOR_WAIT;
>>>>>>>>> +    private static int CONDVAR_WAIT;
>>>>>>>>> +    private static int OBJECT_WAIT;
>>>>>>>>> +    private static int BREAKPOINTED;
>>>>>>>>> +    private static int SLEEPING;
>>>>>>>>> +    private static int ZOMBIE;
>>>>>>>>> +
>>>>>>>>>         static {
>>>>>>>>>             VM.registerVMInitializedObserver(new Observer() {
>>>>>>>>>                 public void update(Observable o, Object data) {
>>>>>>>>> @@ -45,6 +58,17 @@
>>>>>>>>>             Type type = db.lookupType("OSThread");
>>>>>>>>>             interruptedField =
>> type.getJIntField("_interrupted");
>>>>>>>>>             threadIdField = type.getField("_thread_id");
>>>>>>>>> +        threadStateField = type.getCIntegerField("_state");
>>>>>>>>> +
>>>>>>>>> +        ALLOCATED =
>>>> db.lookupIntConstant("ALLOCATED").intValue();
>>>>>>>>> +        INITIALIZED =
>>>> db.lookupIntConstant("INITIALIZED").intValue();
>>>>>>>>> +        RUNNABLE =
>> db.lookupIntConstant("RUNNABLE").intValue();
>>>>>>>>> +        MONITOR_WAIT =
>>>> db.lookupIntConstant("MONITOR_WAIT").intValue();
>>>>>>>>> +        CONDVAR_WAIT =
>>>> db.lookupIntConstant("CONDVAR_WAIT").intValue();
>>>>>>>>> +        OBJECT_WAIT =
>>>> db.lookupIntConstant("OBJECT_WAIT").intValue();
>>>>>>>>> +        BREAKPOINTED =
>>>> db.lookupIntConstant("BREAKPOINTED").intValue();
>>>>>>>>> +        SLEEPING =
>> db.lookupIntConstant("SLEEPING").intValue();
>>>>>>>>> +        ZOMBIE = db.lookupIntConstant("ZOMBIE").intValue();
>>>>>>>>>         }
>>>>>>>>>
>>>>>>>>>         public OSThread(Address addr) {
>>>>>>>>> @@ -59,4 +83,28 @@
>>>>>>>>>             return threadIdField.getJInt(addr);
>>>>>>>>>         }
>>>>>>>>>
>>>>>>>>> +    public ThreadState getThreadState() {
>>>>>>>>> +        int val = (int)threadStateField.getValue(addr);
>>>>>>>>> +        if (val ==  ALLOCATED) {
>>>>>>>>> +            return ThreadState.ALLOCATED;
>>>>>>>>> +        } else if (val ==  INITIALIZED) {
>>>>>>>>> +            return ThreadState.INITIALIZED;
>>>>>>>>> +        } else if (val ==  RUNNABLE) {
>>>>>>>>> +            return ThreadState.RUNNABLE;
>>>>>>>>> +        } else if (val ==  MONITOR_WAIT) {
>>>>>>>>> +            return ThreadState.MONITOR_WAIT;
>>>>>>>>> +        } else if (val ==  CONDVAR_WAIT) {
>>>>>>>>> +            return ThreadState.CONDVAR_WAIT;
>>>>>>>>> +        } else if (val ==  OBJECT_WAIT) {
>>>>>>>>> +            return ThreadState.OBJECT_WAIT;
>>>>>>>>> +        } else if (val ==  BREAKPOINTED) {
>>>>>>>>> +            return ThreadState.BREAKPOINTED;
>>>>>>>>> +        } else if (val ==  SLEEPING) {
>>>>>>>>> +            return ThreadState.SLEEPING;
>>>>>>>>> +        } else if (val ==  ZOMBIE) {
>>>>>>>>> +            return ThreadState.ZOMBIE;
>>>>>>>>> +        } else {
>>>>>>>>> +            throw new RuntimeException("Illegal thread state "
>> +
>>>> val);
>>>>>>>>> +        }
>>>>>>>>> +    }
>>>>>>>>>     }
>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>>>>>> new file mode 100644
>>>>>>>>> --- /dev/null
>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>>>>>> @@ -0,0 +1,60 @@
>>>>>>>>> +/*
>>>>>>>>> + * Copyright (c) 2017, Oracle and/or its affiliates. All
>> rights
>>>> reserved.
>>>>>>>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>> HEADER.
>>>>>>>>> + *
>>>>>>>>> + * This code is free software; you can redistribute it and/or
>>>> modify it
>>>>>>>>> + * under the terms of the GNU General Public License version 2
>>>> only, as
>>>>>>>>> + * published by the Free Software Foundation.
>>>>>>>>> + *
>>>>>>>>> + * This code is distributed in the hope that it will be
>> useful,
>>>> but WITHOUT
>>>>>>>>> + * ANY WARRANTY; without even the implied warranty of
>>>> MERCHANTABILITY or
>>>>>>>>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
>> Public
>>>> License
>>>>>>>>> + * version 2 for more details (a copy is included in the
>> LICENSE
>>>> file that
>>>>>>>>> + * accompanied this code).
>>>>>>>>> + *
>>>>>>>>> + * You should have received a copy of the GNU General Public
>>>> License version
>>>>>>>>> + * 2 along with this work; if not, write to the Free Software
>>>> Foundation,
>>>>>>>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
>> USA.
>>>>>>>>> + *
>>>>>>>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores,
>> CA
>>>> 94065 USA
>>>>>>>>> + * or visit www.oracle.com if you need additional information
>> or
>>>> have any
>>>>>>>>> + * questions.
>>>>>>>>> + */
>>>>>>>>> +
>>>>>>>>> +package sun.jvm.hotspot.runtime;
>>>>>>>>> +
>>>>>>>>> +/** This is a type-safe enum mirroring the ThreadState enum in
>>>>>>>>> + osThread.hpp. The conversion between the underlying ints
>>>>>>>>> + and these values is done in OSThread. */
>>>>>>>>> +
>>>>>>>>> +public class ThreadState {
>>>>>>>>> +
>>>>>>>>> +    private String printVal;
>>>>>>>>> +
>>>>>>>>> +    /** Memory has been allocated but not initialized */
>>>>>>>>> +    public static final ThreadState ALLOCATED = new
>>>> ThreadState("allocated");
>>>>>>>>> +    /** The thread has been initialized but yet started */
>>>>>>>>> +    public static final ThreadState INITIALIZED = new
>>>> ThreadState("initialized");
>>>>>>>>> +    /** Has been started and is runnable, but not necessarily
>>>> running */
>>>>>>>>> +    public static final ThreadState RUNNABLE = new
>>>> ThreadState("runnable");
>>>>>>>>> +    /** Waiting on a contended monitor lock */
>>>>>>>>> +    public static final ThreadState MONITOR_WAIT = new
>>>> ThreadState("waiting for monitor entry");
>>>>>>>>> +    /** Waiting on a condition variable */
>>>>>>>>> +    public static final ThreadState CONDVAR_WAIT = new
>>>> ThreadState("waiting on condition");
>>>>>>>>> +    /** Waiting on an Object.wait() call */
>>>>>>>>> +    public static final ThreadState OBJECT_WAIT = new
>>>> ThreadState("in Object.wait()");
>>>>>>>>> +    /** Suspended at breakpoint */
>>>>>>>>> +    public static final ThreadState BREAKPOINTED = new
>>>> ThreadState("at breakpoint");
>>>>>>>>> +    /** Thread.sleep() */
>>>>>>>>> +    public static final ThreadState SLEEPING = new
>>>> ThreadState("sleeping");
>>>>>>>>> +    /** All done, but not reclaimed yet */
>>>>>>>>> +    public static final ThreadState ZOMBIE = new
>>>> ThreadState("zombie");
>>>>>>>>> +
>>>>>>>>> +    private ThreadState(String printVal){
>>>>>>>>> +        this.printVal = printVal;
>>>>>>>>> +    }
>>>>>>>>> +
>>>>>>>>> +    public String getPrintVal() {
>>>>>>>>> +        return printVal;
>>>>>>>>> +    }
>>>>>>>>> +}
>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>>>     /*
>>>>>>>>> - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>>> + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>>>      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>      *
>>>>>>>>>      * This code is free software; you can redistribute it
>> and/or
>>>> modify it
>>>>>>>>> @@ -88,6 +88,10 @@
>>>>>>>>>                    out.print("----------------- ");
>>>>>>>>>                    out.print(th);
>>>>>>>>>                    out.println(" -----------------");
>>>>>>>>> +               JavaThread jthread = (JavaThread)
>>>> proxyToThread.get(th);
>>>>>>>>> +               if (jthread != null) {
>>>>>>>>> +                  jthread.printThreadInfoOn(out);
>>>>>>>>> +               }
>>>>>>>>>                    while (f != null) {
>>>>>>>>>                       ClosestSymbol sym = f.closestSymbolToPC();
>>>>>>>>>                       Address pc = f.pc();
>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>>>     /*
>>>>>>>>> - * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>>> + * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>>>      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>      *
>>>>>>>>>      * This code is free software; you can redistribute it
>> and/or
>>>> modify it
>>>>>>>>> @@ -74,14 +74,7 @@
>>>>>>>>>                 int i = 1;
>>>>>>>>>                 for (JavaThread cur = threads.first(); cur !=
>> null;
>>>> cur = cur.next(), i++) {
>>>>>>>>>                     if (cur.isJavaThread()) {
>>>>>>>>> -                    Address sp = cur.getLastJavaSP();
>>>>>>>>> -                    tty.print("Thread ");
>>>>>>>>> -                    cur.printThreadIDOn(tty);
>>>>>>>>> -                    tty.print(": (state = " +
>>>> cur.getThreadState());
>>>>>>>>> -                    if (verbose) {
>>>>>>>>> -                        tty.println(", current Java SP = " +
>>>> sp);
>>>>>>>>> -                    }
>>>>>>>>> -                    tty.println(')');
>>>>>>>>> +                    cur.printThreadInfoOn(tty);
>>>>>>>>>                         try {
>>>>>>>>>                             for (JavaVFrame vf =
>>>> cur.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
>>>>>>>>>                                 Method method = vf.getMethod();
>>>>>>>>> diff --git a/src/share/vm/runtime/vmStructs.cpp
>>>> b/src/share/vm/runtime/vmStructs.cpp
>>>>>>>>> --- a/src/share/vm/runtime/vmStructs.cpp
>>>>>>>>> +++ b/src/share/vm/runtime/vmStructs.cpp
>>>>>>>>> @@ -981,6 +981,7 @@
>>>>>>>>> /************/ \
>>>>>>>>> \
>>>>>>>>>       volatile_nonstatic_field(OSThread, _interrupted, jint)
>>>> \
>>>>>>>>> +  volatile_nonstatic_field(OSThread, _state, ThreadState)
>>>> \
>>>>>>>>> \
>>>>>>>>> /************************/ \
>>>>>>>>>       /* OopMap and OopMapSet */ \
>>>>>>>>> @@ -2186,6 +2187,7 @@
>>>>>>>>> declare_integer_type(Generation::Name) \
>>>>>>>>> declare_integer_type(InstanceKlass::ClassState) \
>>>>>>>>> declare_integer_type(JavaThreadState) \
>>>>>>>>> + declare_integer_type(ThreadState) \
>>>>>>>>> declare_integer_type(Location::Type) \
>>>>>>>>> declare_integer_type(Location::Where) \
>>>>>>>>> declare_integer_type(Flag::Flags) \
>>>>>>>>> @@ -2443,6 +2445,20 @@
>>>>>>>>> declare_constant(JavaThread::_not_terminated) \
>>>>>>>>> declare_constant(JavaThread::_thread_exiting) \
>>>>>>>>> \
>>>>>>>>> + /*******************/ \
>>>>>>>>> +  /* JavaThreadState */
>>>> \
>>>>>>>>> + /*******************/ \
>>>>>>>>> + \
>>>>>>>>> + declare_constant(ALLOCATED) \
>>>>>>>>> + declare_constant(INITIALIZED) \
>>>>>>>>> + declare_constant(RUNNABLE) \
>>>>>>>>> + declare_constant(MONITOR_WAIT) \
>>>>>>>>> + declare_constant(CONDVAR_WAIT) \
>>>>>>>>> + declare_constant(OBJECT_WAIT) \
>>>>>>>>> + declare_constant(BREAKPOINTED) \
>>>>>>>>> + declare_constant(SLEEPING) \
>>>>>>>>> + declare_constant(ZOMBIE) \
>>>>>>>>> + \
>>>>>>>>> /******************************/ \
>>>>>>>>>       /* Klass misc. enum constants */
>>>> \
>>>>>>>>> /******************************/ \
>>>>>>>>> diff --git a/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>> b/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>>>>>>> new file mode 100644
>>>>>>>>> --- /dev/null
>>>>>>>>> +++ b/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>>>>>>> @@ -0,0 +1,87 @@
>>>>>>>>> +/*
>>>>>>>>> + * Copyright (c) 2017, Oracle and/or its affiliates. All
>> rights
>>>> reserved.
>>>>>>>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>> HEADER.
>>>>>>>>> + *
>>>>>>>>> + * This code is free software; you can redistribute it and/or
>>>> modify it
>>>>>>>>> + * under the terms of the GNU General Public License version 2
>>>> only, as
>>>>>>>>> + * published by the Free Software Foundation.
>>>>>>>>> + *
>>>>>>>>> + * This code is distributed in the hope that it will be
>> useful,
>>>> but WITHOUT
>>>>>>>>> + * ANY WARRANTY; without even the implied warranty of
>>>> MERCHANTABILITY or
>>>>>>>>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
>> Public
>>>> License
>>>>>>>>> + * version 2 for more details (a copy is included in the
>> LICENSE
>>>> file that
>>>>>>>>> + * accompanied this code).
>>>>>>>>> + *
>>>>>>>>> + * You should have received a copy of the GNU General Public
>>>> License version
>>>>>>>>> + * 2 along with this work; if not, write to the Free Software
>>>> Foundation,
>>>>>>>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
>> USA.
>>>>>>>>> + *
>>>>>>>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores,
>> CA
>>>> 94065 USA
>>>>>>>>> + * or visit www.oracle.com if you need additional information
>> or
>>>> have any
>>>>>>>>> + * questions.
>>>>>>>>> + */
>>>>>>>>> +
>>>>>>>>> +import jdk.test.lib.apps.LingeredApp;
>>>>>>>>> +import jdk.test.lib.JDKToolLauncher;
>>>>>>>>> +import jdk.test.lib.Platform;
>>>>>>>>> +import jdk.test.lib.process.OutputAnalyzer;
>>>>>>>>> +import jdk.test.lib.Utils;
>>>>>>>>> +
>>>>>>>>> +/*
>>>>>>>>> + * @test
>>>>>>>>> + * @library /test/lib
>>>>>>>>> + * @run main JhsdbThreadInfoTest
>>>>>>>>> + */
>>>>>>>>> +public class JhsdbThreadInfoTest {
>>>>>>>>> +
>>>>>>>>> +    public static void main(String[] args) throws Exception {
>>>>>>>>> +
>>>>>>>>> +        if (!Platform.shouldSAAttach()) {
>>>>>>>>> +            System.out.println("SA attach not expected to work
>> -
>>>> test skipped.");
>>>>>>>>> +            return;
>>>>>>>>> +        }
>>>>>>>>> +
>>>>>>>>> +        LingeredApp app = null;
>>>>>>>>> +
>>>>>>>>> +        try {
>>>>>>>>> +            app = LingeredApp.startApp(Utils.getVmOptions());
>>>>>>>>> +            System.out.println("Started LingeredApp with pid "
>> +
>>>> app.getPid());
>>>>>>>>> +
>>>>>>>>> +            JDKToolLauncher jhsdbLauncher =
>>>> JDKToolLauncher.createUsingTestJDK("jhsdb");
>>>>>>>>> +
>>>>>>>>> +            jhsdbLauncher.addToolArg("jstack");
>>>>>>>>> +            jhsdbLauncher.addToolArg("--pid");
>>>>>>>>> + jhsdbLauncher.addToolArg(Long.toString(app.getPid()));
>>>>>>>>> +
>>>>>>>>> +            ProcessBuilder pb = new ProcessBuilder();
>>>>>>>>> +            pb.command(jhsdbLauncher.getCommand());
>>>>>>>>> +            Process jhsdb = pb.start();
>>>>>>>>> +
>>>>>>>>> +            jhsdb.waitFor();
>>>>>>>>> +
>>>>>>>>> +            OutputAnalyzer out = new OutputAnalyzer(jhsdb);
>>>>>>>>> +
>>>>>>>>> +            System.out.println(out.getStdout());
>>>>>>>>> +            System.err.println(out.getStderr());
>>>>>>>>> +
>>>>>>>>> +            out.shouldMatch("\".+\" #\\d+ daemon prio=\\d+
>>>> tid=0x[0-9a-f]+ nid=0x[0-9a-f]+ .+ \\[0x[0-9a-f]+]");
>>>>>>>>> +            out.shouldMatch("\"main\" #\\d+ prio=\\d+
>> tid=0x[0-
>>>> 9a-f]+ nid=0x[0-9a-f]+ .+ \\[0x[0-9a-f]+]");
>>>>>>>>> +            out.shouldMatch("   java.lang.Thread.State: .+");
>>>>>>>>> +            out.shouldMatch("   JavaThread state:
>> _thread_.+");
>>>>>>>>> +
>>>>>>>>> +            out.shouldNotContain(" java.lang.Thread.State:
>>>> UNKNOWN");
>>>>>>>>> +            out.stderrShouldBeEmpty();
>>>>>>>>> +
>>>>>>>>> +            System.out.println("Test Completed");
>>>>>>>>> +
>>>>>>>>> +
>>>>>>>>> +        } catch (InterruptedException ie) {
>>>>>>>>> +            throw new Error("Problem awaiting the child
>> process:
>>>> " + ie, ie);
>>>>>>>>> +        } catch (Exception attachE) {
>>>>>>>>> +            throw new Error("Couldn't start jhsdb, attach to
>>>> LingeredApp or match ThreadName: " + attachE);
>>>>>>>>> +
>>>>>>>>> +        } finally {
>>>>>>>>> +            LingeredApp.stopApp(app);
>>>>>>>>> +        }
>>>>>>>>> +    }
>>>>>>>>> +}
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 2017/06/29 7:40, Yasumasa Suenaga wrote:
>>>>>>>>>> Hi chihiro,
>>>>>>>>>>
>>>>>>>>>> getThreadState() in OSThread.java:
>>>>>>>>>>
>>>>>>>>>>>> +        } else if (val == BREAKPOINTED) {
>>>>>>>>>>>> +            return ThreadState.BREAKPOINTED;
>>>>>>>>>>>> +        } else if (val ==  BREAKPOINTED) {
>>>>>>>>>>>> +            return ThreadState.BREAKPOINTED;
>>>>>>>>>> These conditions are duplicated.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Please upload webrev if you can :-)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Yasumasa
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 2017/06/29 0:02, chihiro ito wrote:
>>>>>>>>>>> Hi all,
>>>>>>>>>>>
>>>>>>>>>>> In last week, I've posted review request [1].
>>>>>>>>>>> Could you possibly review for this following small change? If
>>>> review is ok, please commit this as cito.
>>>>>>>>>>> [1] http://mail.openjdk.java.net/pipermail/serviceability-
>>>> dev/2017-June/021430.html
>>>>>>>>>>> Thanks,
>>>>>>>>>>> Chihiro (Contributer)
>>>>>>>>>>>
>>>>>>>>>>> On 2017/06/18 13:02, chihiro ito wrote:
>>>>>>>>>>>> At first I thought to print just each thread name, but I
>> tried
>>>> to make it as similar as possible to JStack as following.
>>>>>>>>>>>> Mixed mode:
>>>>>>>>>>>> ----------------- 26476 -----------------
>>>>>>>>>>>> "main" #1 prio=5 tid=0x00007f6894019000 nid=0x676c waiting
>> on
>>>> condition [0x00007f689b7ae000]
>>>>>>>>>>>>      java.lang.Thread.State: TIMED_WAITING (sleeping)
>>>>>>>>>>>>      JavaThread state: _thread_blocked
>>>>>>>>>>>> 0x00007f689b185a82    __pthread_cond_timedwait + 0x132
>>>>>>>>>>>>
>>>>>>>>>>>> No mixed mode:
>>>>>>>>>>>> "main" #1 prio=5 tid=0x00007f6894019000 nid=0x676c waiting
>> on
>>>> condition [0x00007f689b7ae000]
>>>>>>>>>>>>      java.lang.Thread.State: TIMED_WAITING (sleeping)
>>>>>>>>>>>>      JavaThread state: _thread_blocked
>>>>>>>>>>>>    - java.lang.Thread.sleep(long) @bci=0 (Interpreted frame)
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> This change passed a test by jtreg.
>>>>>>>>>>>>
>>>>>>>>>>>> SOURCE_HOME=/home/user/repo/jdk10-hs
>>>>>>>>>>>> jtreg -dir:${SOURCE_HOME}/hotspot/test -
>>>> testjdk:${SOURCE_HOME}/build/linux-x86_64-normal-server-
>> slowdebug/jdk/
>>>> serviceability/sa/JhsdbThreadInfoTest.java
>>>>>>>>>>>> Test results: passed: 1
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Source:
>>>>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>>>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/OopUtilities
>>>> .java
>>>>>>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>>>>>>    /*
>>>>>>>>>>>> - * Copyright (c) 2000, 2016, Oracle and/or its affiliates.
>>>> All rights reserved.
>>>>>>>>>>>> + * Copyright (c) 2000, 2017, Oracle and/or its affiliates.
>>>> All rights reserved.
>>>>>>>>>>>>     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>>>>     *
>>>>>>>>>>>>     * This code is free software; you can redistribute it
>> and/or
>>>> modify it
>>>>>>>>>>>> @@ -59,20 +59,20 @@
>>>>>>>>>>>>      // parkBlocker field is new since 1.6
>>>>>>>>>>>>      private static OopField threadParkBlockerField;
>>>>>>>>>>>>
>>>>>>>>>>>> +  private static IntField threadPriorityField;
>>>>>>>>>>>> +  private static BooleanField threadDaemonField;
>>>>>>>>>>>> +
>>>>>>>>>>>>      // possible values of java_lang_Thread::ThreadStatus
>>>>>>>>>>>>      private static int THREAD_STATUS_NEW;
>>>>>>>>>>>> -  /*
>>>>>>>>>>>> -    Other enum constants are not needed as of now.
>> Uncomment
>>>> these as and when needed.
>>>>>>>>>>>> -    private static int THREAD_STATUS_RUNNABLE;
>>>>>>>>>>>> -    private static int THREAD_STATUS_SLEEPING;
>>>>>>>>>>>> -    private static int THREAD_STATUS_IN_OBJECT_WAIT;
>>>>>>>>>>>> -    private static int THREAD_STATUS_IN_OBJECT_WAIT_TIMED;
>>>>>>>>>>>> -    private static int THREAD_STATUS_PARKED;
>>>>>>>>>>>> -    private static int THREAD_STATUS_PARKED_TIMED;
>>>>>>>>>>>> -    private static int
>>>> THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER;
>>>>>>>>>>>> -    private static int THREAD_STATUS_TERMINATED;
>>>>>>>>>>>> -  */
>>>>>>>>>>>> +  private static int THREAD_STATUS_RUNNABLE;
>>>>>>>>>>>> +  private static int THREAD_STATUS_SLEEPING;
>>>>>>>>>>>> +  private static int THREAD_STATUS_IN_OBJECT_WAIT;
>>>>>>>>>>>> +  private static int THREAD_STATUS_IN_OBJECT_WAIT_TIMED;
>>>>>>>>>>>> +  private static int THREAD_STATUS_PARKED;
>>>>>>>>>>>> +  private static int THREAD_STATUS_PARKED_TIMED;
>>>>>>>>>>>> +  private static int
>> THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER;
>>>>>>>>>>>> +  private static int THREAD_STATUS_TERMINATED;
>>>>>>>>>>>>
>>>>>>>>>>>>      //
>> java.util.concurrent.locks.AbstractOwnableSynchronizer
>>>> fields
>>>>>>>>>>>>      private static OopField absOwnSyncOwnerThreadField;
>>>>>>>>>>>> @@ -229,20 +229,19 @@
>>>>>>>>>>>>          threadStatusField = (IntField)
>>>> k.findField("threadStatus", "I");
>>>>>>>>>>>>          threadParkBlockerField = (OopField)
>>>> k.findField("parkBlocker",
>>>>>>>>>>>> "Ljava/lang/Object;");
>>>>>>>>>>>> +      threadPriorityField = (IntField)
>>>> k.findField("priority", "I");
>>>>>>>>>>>> +      threadDaemonField = (BooleanField)
>>>> k.findField("daemon", "Z");
>>>>>>>>>>>>          TypeDataBase db = VM.getVM().getTypeDataBase();
>>>>>>>>>>>>          THREAD_STATUS_NEW =
>>>> db.lookupIntConstant("java_lang_Thread::NEW").intValue();
>>>>>>>>>>>> -      /*
>>>>>>>>>>>> -        Other enum constants are not needed as of now.
>>>> Uncomment these as and when needed.
>>>>>>>>>>>> -        THREAD_STATUS_RUNNABLE =
>>>> db.lookupIntConstant("java_lang_Thread::RUNNABLE").intValue();
>>>>>>>>>>>> -        THREAD_STATUS_SLEEPING =
>>>> db.lookupIntConstant("java_lang_Thread::SLEEPING").intValue();
>>>>>>>>>>>> -        THREAD_STATUS_IN_OBJECT_WAIT =
>>>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT").intValue();
>>>>>>>>>>>> -        THREAD_STATUS_IN_OBJECT_WAIT_TIMED =
>>>>
>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT_TIMED").intValue
>>>> ();
>>>>>>>>>>>> -        THREAD_STATUS_PARKED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED").intValue();
>>>>>>>>>>>> -        THREAD_STATUS_PARKED_TIMED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED_TIMED").intValue();
>>>>>>>>>>>> -        THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER =
>>>>
>> db.lookupIntConstant("java_lang_Thread::BLOCKED_ON_MONITOR_ENTER").intV
>>>> alue();
>>>>>>>>>>>> -        THREAD_STATUS_TERMINATED =
>>>> db.lookupIntConstant("java_lang_Thread::TERMINATED").intValue();
>>>>>>>>>>>> -      */
>>>>>>>>>>>> +      THREAD_STATUS_RUNNABLE =
>>>> db.lookupIntConstant("java_lang_Thread::RUNNABLE").intValue();
>>>>>>>>>>>> +      THREAD_STATUS_SLEEPING =
>>>> db.lookupIntConstant("java_lang_Thread::SLEEPING").intValue();
>>>>>>>>>>>> +      THREAD_STATUS_IN_OBJECT_WAIT =
>>>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT").intValue();
>>>>>>>>>>>> +      THREAD_STATUS_IN_OBJECT_WAIT_TIMED =
>>>>
>> db.lookupIntConstant("java_lang_Thread::IN_OBJECT_WAIT_TIMED").intValue
>>>> ();
>>>>>>>>>>>> +      THREAD_STATUS_PARKED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED").intValue();
>>>>>>>>>>>> +      THREAD_STATUS_PARKED_TIMED =
>>>> db.lookupIntConstant("java_lang_Thread::PARKED_TIMED").intValue();
>>>>>>>>>>>> +      THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER =
>>>>
>> db.lookupIntConstant("java_lang_Thread::BLOCKED_ON_MONITOR_ENTER").intV
>>>> alue();
>>>>>>>>>>>> +      THREAD_STATUS_TERMINATED =
>>>> db.lookupIntConstant("java_lang_Thread::TERMINATED").intValue();
>>>>>>>>>>>>          if (Assert.ASSERTS_ENABLED) {
>>>>>>>>>>>>            // it is okay to miss threadStatusField, because
>> this
>>>> was
>>>>>>>>>>>> @@ -331,4 +330,46 @@
>>>>>>>>>>>>          return absOwnSyncOwnerThreadField.getValue(oop);
>>>>>>>>>>>>        }
>>>>>>>>>>>>      }
>>>>>>>>>>>> +
>>>>>>>>>>>> +  public static int threadOopGetPriority(Oop threadOop) {
>>>>>>>>>>>> +    initThreadFields();
>>>>>>>>>>>> +    if (threadPriorityField != null) {
>>>>>>>>>>>> +      return threadPriorityField.getValue(threadOop);
>>>>>>>>>>>> +    } else {
>>>>>>>>>>>> +      return 0;
>>>>>>>>>>>> +    }
>>>>>>>>>>>> +  }
>>>>>>>>>>>> +
>>>>>>>>>>>> +  public static boolean threadOopGetDaemon(Oop threadOop) {
>>>>>>>>>>>> +    initThreadFields();
>>>>>>>>>>>> +    if (threadDaemonField != null) {
>>>>>>>>>>>> +      return threadDaemonField.getValue(threadOop);
>>>>>>>>>>>> +    } else {
>>>>>>>>>>>> +      return false;
>>>>>>>>>>>> +    }
>>>>>>>>>>>> +  }
>>>>>>>>>>>> +
>>>>>>>>>>>> +  public static String threadOopGetThreadStatusName(Oop
>>>> threadOop) {
>>>>>>>>>>>> +    int status =
>>>> OopUtilities.threadOopGetThreadStatus(threadOop);
>>>>>>>>>>>> +    if( status == THREAD_STATUS_NEW ){
>>>>>>>>>>>> +      return "NEW";
>>>>>>>>>>>> +    }else if(status == THREAD_STATUS_RUNNABLE ){
>>>>>>>>>>>> +      return "RUNNABLE";
>>>>>>>>>>>> +    }else if(status == THREAD_STATUS_SLEEPING ){
>>>>>>>>>>>> +      return "TIMED_WAITING (sleeping)";
>>>>>>>>>>>> +    }else if(status == THREAD_STATUS_IN_OBJECT_WAIT ){
>>>>>>>>>>>> +      return "WAITING (on object monitor)";
>>>>>>>>>>>> +    }else if(status == THREAD_STATUS_IN_OBJECT_WAIT_TIMED
>> ){
>>>>>>>>>>>> +      return "TIMED_WAITING (on object monitor)";
>>>>>>>>>>>> +    }else if(status == THREAD_STATUS_PARKED ){
>>>>>>>>>>>> +      return "WAITING (parking)";
>>>>>>>>>>>> +    }else if(status == THREAD_STATUS_PARKED_TIMED ){
>>>>>>>>>>>> +      return "TIMED_WAITING (parking)";
>>>>>>>>>>>> +    }else if(status ==
>> THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER
>>>> ){
>>>>>>>>>>>> +      return "BLOCKED (on object monitor)";
>>>>>>>>>>>> +    }else if(status == THREAD_STATUS_TERMINATED ){
>>>>>>>>>>>> +      return "TERMINATED";
>>>>>>>>>>>> +    }
>>>>>>>>>>>> +    return "UNKNOWN";
>>>>>>>>>>>> +  }
>>>>>>>>>>>>    }
>>>>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>>>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThrea
>>>> d.java
>>>>>>>>>>>> @@ -475,4 +475,36 @@
>>>>>>>>>>>>        return access.getLastSP(addr);
>>>>>>>>>>>>      }
>>>>>>>>>>>>
>>>>>>>>>>>> +
>>>>>>>>>>>> +  public void printThreadInfoOn(PrintStream out){
>>>>>>>>>>>> +
>>>>>>>>>>>> +    Oop threadOop = this.getThreadObj();
>>>>>>>>>>>> +
>>>>>>>>>>>> +    out.print("\"");
>>>>>>>>>>>> +    out.print(this.getThreadName());
>>>>>>>>>>>> +    out.print("\" #");
>>>>>>>>>>>> + out.print(OopUtilities.threadOopGetTID(threadOop));
>>>>>>>>>>>> +    if( OopUtilities.threadOopGetDaemon(threadOop) ){
>>>>>>>>>>>> +      out.print(" daemon");
>>>>>>>>>>>> +    }
>>>>>>>>>>>> +    out.print(" prio=");
>>>>>>>>>>>> + out.print(OopUtilities.threadOopGetPriority(threadOop));
>>>>>>>>>>>> +    out.print(" tid=");
>>>>>>>>>>>> +
>>>> out.print(String.format("0x%016x",this.getAddress().asLongValue()));
>>>>>>>>>>>> +    out.print(" nid=");
>>>>>>>>>>>> +    out.print(String.format("0x%x
>>>> ",this.getOSThread().threadId()));
>>>>>>>>>>>> + out.print(getOSThread().getThreadState().getPrintVal());
>>>>>>>>>>>> +    out.print(" [");
>>>>>>>>>>>> +    if( this.getLastJavaSP() == null){
>>>>>>>>>>>> +      out.print(String.format("0x%016x",0L));
>>>>>>>>>>>> +    } else {
>>>>>>>>>>>> +      Address maskAddress =
>>>> this.getLastJavaSP().andWithMask(0xFFF);
>>>>>>>>>>>> +
>>>>
>> out.print(this.getLastJavaSP().xorWithMask(maskAddress.asLongValue()));
>>>>>>>>>>>> +    }
>>>>>>>>>>>> +    out.println("]");
>>>>>>>>>>>> +    out.print("   java.lang.Thread.State: ");
>>>>>>>>>>>> +
>>>> out.println(OopUtilities.threadOopGetThreadStatusName(threadOop));
>>>>>>>>>>>> +    out.print("   JavaThread state: _thread_");
>>>>>>>>>>>> +
>> out.println(this.getThreadState().toString().toLowerCase());
>>>>>>>>>>>> +  }
>>>>>>>>>>>>    }
>>>>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>>>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/OSThread.
>>>> java
>>>>>>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>>>>>>    /*
>>>>>>>>>>>> - * Copyright (c) 2004, 2013, Oracle and/or its affiliates.
>>>> All rights reserved.
>>>>>>>>>>>> + * Copyright (c) 2004, 2017, Oracle and/or its affiliates.
>>>> All rights reserved.
>>>>>>>>>>>>     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>>>>     *
>>>>>>>>>>>>     * This code is free software; you can redistribute it
>> and/or
>>>> modify it
>>>>>>>>>>>> @@ -33,6 +33,19 @@
>>>>>>>>>>>>    public class OSThread extends VMObject {
>>>>>>>>>>>>        private static JIntField interruptedField;
>>>>>>>>>>>>        private static Field threadIdField;
>>>>>>>>>>>> +    private static CIntegerField threadStateField;
>>>>>>>>>>>> +
>>>>>>>>>>>> +    // ThreadStates read from underlying process
>>>>>>>>>>>> +    private static int ALLOCATED;
>>>>>>>>>>>> +    private static int INITIALIZED;
>>>>>>>>>>>> +    private static int RUNNABLE;
>>>>>>>>>>>> +    private static int MONITOR_WAIT;
>>>>>>>>>>>> +    private static int CONDVAR_WAIT;
>>>>>>>>>>>> +    private static int OBJECT_WAIT;
>>>>>>>>>>>> +    private static int BREAKPOINTED;
>>>>>>>>>>>> +    private static int SLEEPING;
>>>>>>>>>>>> +    private static int ZOMBIE;
>>>>>>>>>>>> +
>>>>>>>>>>>>        static {
>>>>>>>>>>>>            VM.registerVMInitializedObserver(new Observer() {
>>>>>>>>>>>>                public void update(Observable o, Object data)
>> {
>>>>>>>>>>>> @@ -45,6 +58,17 @@
>>>>>>>>>>>>            Type type = db.lookupType("OSThread");
>>>>>>>>>>>>            interruptedField =
>> type.getJIntField("_interrupted");
>>>>>>>>>>>>            threadIdField = type.getField("_thread_id");
>>>>>>>>>>>> +        threadStateField = type.getCIntegerField("_state");
>>>>>>>>>>>> +
>>>>>>>>>>>> +        ALLOCATED =
>>>> db.lookupIntConstant("ALLOCATED").intValue();
>>>>>>>>>>>> +        INITIALIZED =
>>>> db.lookupIntConstant("INITIALIZED").intValue();
>>>>>>>>>>>> +        RUNNABLE =
>>>> db.lookupIntConstant("RUNNABLE").intValue();
>>>>>>>>>>>> +        MONITOR_WAIT =
>>>> db.lookupIntConstant("MONITOR_WAIT").intValue();
>>>>>>>>>>>> +        CONDVAR_WAIT =
>>>> db.lookupIntConstant("CONDVAR_WAIT").intValue();
>>>>>>>>>>>> +        OBJECT_WAIT =
>>>> db.lookupIntConstant("OBJECT_WAIT").intValue();
>>>>>>>>>>>> +        BREAKPOINTED =
>>>> db.lookupIntConstant("BREAKPOINTED").intValue();
>>>>>>>>>>>> +        SLEEPING =
>>>> db.lookupIntConstant("SLEEPING").intValue();
>>>>>>>>>>>> +        ZOMBIE = db.lookupIntConstant("ZOMBIE").intValue();
>>>>>>>>>>>>        }
>>>>>>>>>>>>
>>>>>>>>>>>>        public OSThread(Address addr) {
>>>>>>>>>>>> @@ -59,4 +83,30 @@
>>>>>>>>>>>>            return threadIdField.getJInt(addr);
>>>>>>>>>>>>        }
>>>>>>>>>>>>
>>>>>>>>>>>> +    public ThreadState getThreadState() {
>>>>>>>>>>>> +        int val = (int)threadStateField.getValue(addr);
>>>>>>>>>>>> +        if (val ==  ALLOCATED) {
>>>>>>>>>>>> +            return ThreadState.ALLOCATED;
>>>>>>>>>>>> +        } else if (val ==  INITIALIZED) {
>>>>>>>>>>>> +            return ThreadState.INITIALIZED;
>>>>>>>>>>>> +        } else if (val ==  RUNNABLE) {
>>>>>>>>>>>> +            return ThreadState.RUNNABLE;
>>>>>>>>>>>> +        } else if (val ==  MONITOR_WAIT) {
>>>>>>>>>>>> +            return ThreadState.MONITOR_WAIT;
>>>>>>>>>>>> +        } else if (val ==  CONDVAR_WAIT) {
>>>>>>>>>>>> +            return ThreadState.CONDVAR_WAIT;
>>>>>>>>>>>> +        } else if (val ==  OBJECT_WAIT) {
>>>>>>>>>>>> +            return ThreadState.OBJECT_WAIT;
>>>>>>>>>>>> +        } else if (val ==  BREAKPOINTED) {
>>>>>>>>>>>> +            return ThreadState.BREAKPOINTED;
>>>>>>>>>>>> +        } else if (val ==  BREAKPOINTED) {
>>>>>>>>>>>> +            return ThreadState.BREAKPOINTED;
>>>>>>>>>>>> +        } else if (val ==  SLEEPING) {
>>>>>>>>>>>> +            return ThreadState.SLEEPING;
>>>>>>>>>>>> +        } else if (val ==  ZOMBIE) {
>>>>>>>>>>>> +            return ThreadState.ZOMBIE;
>>>>>>>>>>>> +        } else {
>>>>>>>>>>>> +            throw new RuntimeException("Illegal thread
>> state
>>>> " + val);
>>>>>>>>>>>> +        }
>>>>>>>>>>>> +    }
>>>>>>>>>>>>    }
>>>>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadSta
>>>> te.java
>>>>>>>>>>>> @@ -0,0 +1,60 @@
>>>>>>>>>>>> +/*
>>>>>>>>>>>> + * Copyright (c) 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>>>>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>>>> + *
>>>>>>>>>>>> + * This code is free software; you can redistribute it
>> and/or
>>>> modify it
>>>>>>>>>>>> + * under the terms of the GNU General Public License
>> version
>>>> 2 only, as
>>>>>>>>>>>> + * published by the Free Software Foundation.
>>>>>>>>>>>> + *
>>>>>>>>>>>> + * This code is distributed in the hope that it will be
>>>> useful, but WITHOUT
>>>>>>>>>>>> + * ANY WARRANTY; without even the implied warranty of
>>>> MERCHANTABILITY or
>>>>>>>>>>>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
>>>> Public License
>>>>>>>>>>>> + * version 2 for more details (a copy is included in the
>>>> LICENSE file that
>>>>>>>>>>>> + * accompanied this code).
>>>>>>>>>>>> + *
>>>>>>>>>>>> + * You should have received a copy of the GNU General
>> Public
>>>> License version
>>>>>>>>>>>> + * 2 along with this work; if not, write to the Free
>> Software
>>>> Foundation,
>>>>>>>>>>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
>>>> USA.
>>>>>>>>>>>> + *
>>>>>>>>>>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood
>> Shores,
>>>> CA 94065 USA
>>>>>>>>>>>> + * or visit www.oracle.com if you need additional
>> information
>>>> or have any
>>>>>>>>>>>> + * questions.
>>>>>>>>>>>> + */
>>>>>>>>>>>> +
>>>>>>>>>>>> +package sun.jvm.hotspot.runtime;
>>>>>>>>>>>> +
>>>>>>>>>>>> +/** This is a type-safe enum mirroring the ThreadState enum
>>>> in
>>>>>>>>>>>> + osThread.hpp. The conversion between the underlying ints
>>>>>>>>>>>> + and these values is done in OSThread. */
>>>>>>>>>>>> +
>>>>>>>>>>>> +public class ThreadState {
>>>>>>>>>>>> +
>>>>>>>>>>>> +    private String printVal;
>>>>>>>>>>>> +
>>>>>>>>>>>> +    /** Memory has been allocated but not initialized */
>>>>>>>>>>>> +    public static final ThreadState ALLOCATED = new
>>>> ThreadState("allocated");
>>>>>>>>>>>> +    /** The thread has been initialized but yet started */
>>>>>>>>>>>> +    public static final ThreadState INITIALIZED = new
>>>> ThreadState("initialized");
>>>>>>>>>>>> +    /** Has been started and is runnable, but not
>> necessarily
>>>> running */
>>>>>>>>>>>> +    public static final ThreadState RUNNABLE = new
>>>> ThreadState("runnable");
>>>>>>>>>>>> +    /** Waiting on a contended monitor lock */
>>>>>>>>>>>> +    public static final ThreadState MONITOR_WAIT = new
>>>> ThreadState("waiting for monitor entry");
>>>>>>>>>>>> +    /** Waiting on a condition variable */
>>>>>>>>>>>> +    public static final ThreadState CONDVAR_WAIT = new
>>>> ThreadState("waiting on condition");
>>>>>>>>>>>> +    /** Waiting on an Object.wait() call */
>>>>>>>>>>>> +    public static final ThreadState OBJECT_WAIT = new
>>>> ThreadState("in Object.wait()");
>>>>>>>>>>>> +    /** Suspended at breakpoint */
>>>>>>>>>>>> +    public static final ThreadState BREAKPOINTED = new
>>>> ThreadState("at breakpoint");
>>>>>>>>>>>> +    /** Thread.sleep() */
>>>>>>>>>>>> +    public static final ThreadState SLEEPING = new
>>>> ThreadState("sleeping");
>>>>>>>>>>>> +    /** All done, but not reclaimed yet */
>>>>>>>>>>>> +    public static final ThreadState ZOMBIE = new
>>>> ThreadState("zombie");
>>>>>>>>>>>> +
>>>>>>>>>>>> +    private ThreadState(String printVal){
>>>>>>>>>>>> +        this.printVal = printVal;
>>>>>>>>>>>> +    }
>>>>>>>>>>>> +
>>>>>>>>>>>> +    public String getPrintVal() {
>>>>>>>>>>>> +        return printVal;
>>>>>>>>>>>> +    }
>>>>>>>>>>>> +}
>>>>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>>>>>>    /*
>>>>>>>>>>>> - * Copyright (c) 2003, 2013, Oracle and/or its affiliates.
>>>> All rights reserved.
>>>>>>>>>>>> + * Copyright (c) 2003, 2017, Oracle and/or its affiliates.
>>>> All rights reserved.
>>>>>>>>>>>>     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>>>>     *
>>>>>>>>>>>>     * This code is free software; you can redistribute it
>> and/or
>>>> modify it
>>>>>>>>>>>> @@ -88,6 +88,10 @@
>>>>>>>>>>>>                   out.print("----------------- ");
>>>>>>>>>>>>                   out.print(th);
>>>>>>>>>>>>                   out.println(" -----------------");
>>>>>>>>>>>> +               JavaThread jthread = (JavaThread)
>>>> proxyToThread.get(th);
>>>>>>>>>>>> +               if (jthread != null) {
>>>>>>>>>>>> +                  jthread.printThreadInfoOn(out);
>>>>>>>>>>>> +               }
>>>>>>>>>>>>                   while (f != null) {
>>>>>>>>>>>>                      ClosestSymbol sym =
>> f.closestSymbolToPC();
>>>>>>>>>>>>                      Address pc = f.pc();
>>>>>>>>>>>> diff --git
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>>>>>>    /*
>>>>>>>>>>>> - * Copyright (c) 2002, 2013, Oracle and/or its affiliates.
>>>> All rights reserved.
>>>>>>>>>>>> + * Copyright (c) 2002, 2017, Oracle and/or its affiliates.
>>>> All rights reserved.
>>>>>>>>>>>>     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>>>>     *
>>>>>>>>>>>>     * This code is free software; you can redistribute it
>> and/or
>>>> modify it
>>>>>>>>>>>> @@ -74,14 +74,7 @@
>>>>>>>>>>>>                int i = 1;
>>>>>>>>>>>>                for (JavaThread cur = threads.first(); cur !=
>>>> null; cur = cur.next(), i++) {
>>>>>>>>>>>>                    if (cur.isJavaThread()) {
>>>>>>>>>>>> -                    Address sp = cur.getLastJavaSP();
>>>>>>>>>>>> -                    tty.print("Thread ");
>>>>>>>>>>>> -                    cur.printThreadIDOn(tty);
>>>>>>>>>>>> -                    tty.print(": (state = " +
>>>> cur.getThreadState());
>>>>>>>>>>>> -                    if (verbose) {
>>>>>>>>>>>> -                        tty.println(", current Java SP = "
>> +
>>>> sp);
>>>>>>>>>>>> -                    }
>>>>>>>>>>>> -                    tty.println(')');
>>>>>>>>>>>> +                    cur.printThreadInfoOn(tty);
>>>>>>>>>>>>                        try {
>>>>>>>>>>>>                            for (JavaVFrame vf =
>>>> cur.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
>>>>>>>>>>>>                                Method method =
>> vf.getMethod();
>>>>>>>>>>>> diff --git a/src/share/vm/runtime/vmStructs.cpp
>>>> b/src/share/vm/runtime/vmStructs.cpp
>>>>>>>>>>>> --- a/src/share/vm/runtime/vmStructs.cpp
>>>>>>>>>>>> +++ b/src/share/vm/runtime/vmStructs.cpp
>>>>>>>>>>>> @@ -981,6 +981,7 @@
>>>>>>>>>>>> /************/ \
>>>>>>>>>>>> \
>>>>>>>>>>>>      volatile_nonstatic_field(OSThread, _interrupted, jint)
>>>> \
>>>>>>>>>>>> +  volatile_nonstatic_field(OSThread, _state, ThreadState)
>>>> \
>>>>>>>>>>>> \
>>>>>>>>>>>> /************************/ \
>>>>>>>>>>>>      /* OopMap and OopMapSet */ \
>>>>>>>>>>>> @@ -2186,6 +2187,7 @@
>>>>>>>>>>>> declare_integer_type(Generation::Name) \
>>>>>>>>>>>> declare_integer_type(InstanceKlass::ClassState) \
>>>>>>>>>>>> declare_integer_type(JavaThreadState) \
>>>>>>>>>>>> + declare_integer_type(ThreadState) \
>>>>>>>>>>>> declare_integer_type(Location::Type) \
>>>>>>>>>>>> declare_integer_type(Location::Where) \
>>>>>>>>>>>> declare_integer_type(Flag::Flags) \
>>>>>>>>>>>> @@ -2443,6 +2445,20 @@
>>>>>>>>>>>> declare_constant(JavaThread::_not_terminated) \
>>>>>>>>>>>> declare_constant(JavaThread::_thread_exiting) \
>>>>>>>>>>>> \
>>>>>>>>>>>> + /*******************/ \
>>>>>>>>>>>> +  /* JavaThreadState */
>>>> \
>>>>>>>>>>>> + /*******************/ \
>>>>>>>>>>>> + \
>>>>>>>>>>>> + declare_constant(ALLOCATED) \
>>>>>>>>>>>> + declare_constant(INITIALIZED) \
>>>>>>>>>>>> + declare_constant(RUNNABLE) \
>>>>>>>>>>>> + declare_constant(MONITOR_WAIT) \
>>>>>>>>>>>> + declare_constant(CONDVAR_WAIT) \
>>>>>>>>>>>> + declare_constant(OBJECT_WAIT) \
>>>>>>>>>>>> + declare_constant(BREAKPOINTED) \
>>>>>>>>>>>> + declare_constant(SLEEPING) \
>>>>>>>>>>>> + declare_constant(ZOMBIE) \
>>>>>>>>>>>> + \
>>>>>>>>>>>> /******************************/ \
>>>>>>>>>>>>      /* Klass misc. enum constants */
>>>> \
>>>>>>>>>>>> /******************************/ \
>>>>>>>>>>>> diff --git a/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>> b/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>> +++ b/test/serviceability/sa/JhsdbThreadInfoTest.java
>>>>>>>>>>>> @@ -0,0 +1,87 @@
>>>>>>>>>>>> +/*
>>>>>>>>>>>> + * Copyright (c) 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>>>>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>>>> + *
>>>>>>>>>>>> + * This code is free software; you can redistribute it
>> and/or
>>>> modify it
>>>>>>>>>>>> + * under the terms of the GNU General Public License
>> version
>>>> 2 only, as
>>>>>>>>>>>> + * published by the Free Software Foundation.
>>>>>>>>>>>> + *
>>>>>>>>>>>> + * This code is distributed in the hope that it will be
>>>> useful, but WITHOUT
>>>>>>>>>>>> + * ANY WARRANTY; without even the implied warranty of
>>>> MERCHANTABILITY or
>>>>>>>>>>>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
>>>> Public License
>>>>>>>>>>>> + * version 2 for more details (a copy is included in the
>>>> LICENSE file that
>>>>>>>>>>>> + * accompanied this code).
>>>>>>>>>>>> + *
>>>>>>>>>>>> + * You should have received a copy of the GNU General
>> Public
>>>> License version
>>>>>>>>>>>> + * 2 along with this work; if not, write to the Free
>> Software
>>>> Foundation,
>>>>>>>>>>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
>>>> USA.
>>>>>>>>>>>> + *
>>>>>>>>>>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood
>> Shores,
>>>> CA 94065 USA
>>>>>>>>>>>> + * or visit www.oracle.com if you need additional
>> information
>>>> or have any
>>>>>>>>>>>> + * questions.
>>>>>>>>>>>> + */
>>>>>>>>>>>> +
>>>>>>>>>>>> +import jdk.test.lib.apps.LingeredApp;
>>>>>>>>>>>> +import jdk.test.lib.JDKToolLauncher;
>>>>>>>>>>>> +import jdk.test.lib.Platform;
>>>>>>>>>>>> +import jdk.test.lib.process.OutputAnalyzer;
>>>>>>>>>>>> +import jdk.test.lib.Utils;
>>>>>>>>>>>> +
>>>>>>>>>>>> +/*
>>>>>>>>>>>> + * @test
>>>>>>>>>>>> + * @library /test/lib
>>>>>>>>>>>> + * @run main JhsdbThreadInfoTest
>>>>>>>>>>>> + */
>>>>>>>>>>>> +public class JhsdbThreadInfoTest {
>>>>>>>>>>>> +
>>>>>>>>>>>> +    public static void main(String[] args) throws Exception
>> {
>>>>>>>>>>>> +
>>>>>>>>>>>> +        if (!Platform.shouldSAAttach()) {
>>>>>>>>>>>> +            System.out.println("SA attach not expected to
>>>> work - test skipped.");
>>>>>>>>>>>> +            return;
>>>>>>>>>>>> +        }
>>>>>>>>>>>> +
>>>>>>>>>>>> +        LingeredApp app = null;
>>>>>>>>>>>> +
>>>>>>>>>>>> +        try {
>>>>>>>>>>>> +            app =
>> LingeredApp.startApp(Utils.getVmOptions());
>>>>>>>>>>>> +            System.out.println("Started LingeredApp with
>> pid
>>>> " + app.getPid());
>>>>>>>>>>>> +
>>>>>>>>>>>> +            JDKToolLauncher jhsdbLauncher =
>>>> JDKToolLauncher.createUsingTestJDK("jhsdb");
>>>>>>>>>>>> +
>>>>>>>>>>>> +            jhsdbLauncher.addToolArg("jstack");
>>>>>>>>>>>> +            jhsdbLauncher.addToolArg("--pid");
>>>>>>>>>>>> + jhsdbLauncher.addToolArg(Long.toString(app.getPid()));
>>>>>>>>>>>> +
>>>>>>>>>>>> +            ProcessBuilder pb = new ProcessBuilder();
>>>>>>>>>>>> +            pb.command(jhsdbLauncher.getCommand());
>>>>>>>>>>>> +            Process jhsdb = pb.start();
>>>>>>>>>>>> +
>>>>>>>>>>>> +            jhsdb.waitFor();
>>>>>>>>>>>> +
>>>>>>>>>>>> +            OutputAnalyzer out = new OutputAnalyzer(jhsdb);
>>>>>>>>>>>> +
>>>>>>>>>>>> +            System.out.println(out.getStdout());
>>>>>>>>>>>> +            System.err.println(out.getStderr());
>>>>>>>>>>>> +
>>>>>>>>>>>> +            out.shouldMatch("\".+\" #\\d+ daemon prio=\\d+
>>>> tid=0x[0-9a-f]+ nid=0x[0-9a-f]+ .+ \\[0x[0-9a-f]+]");
>>>>>>>>>>>> +            out.shouldMatch("\"main\" #\\d+ prio=\\d+
>>>> tid=0x[0-9a-f]+ nid=0x[0-9a-f]+ .+ \\[0x[0-9a-f]+]");
>>>>>>>>>>>> +            out.shouldMatch(" java.lang.Thread.State: .+");
>>>>>>>>>>>> +            out.shouldMatch("   JavaThread state:
>>>> _thread_.+");
>>>>>>>>>>>> +
>>>>>>>>>>>> +            out.shouldNotContain(" java.lang.Thread.State:
>>>> UNKNOWN");
>>>>>>>>>>>> +            out.stderrShouldBeEmpty();
>>>>>>>>>>>> +
>>>>>>>>>>>> +            System.out.println("Test Completed");
>>>>>>>>>>>> +
>>>>>>>>>>>> +
>>>>>>>>>>>> +        } catch (InterruptedException ie) {
>>>>>>>>>>>> +            throw new Error("Problem awaiting the child
>>>> process: " + ie, ie);
>>>>>>>>>>>> +        } catch (Exception attachE) {
>>>>>>>>>>>> +            throw new Error("Couldn't start jhsdb, attach
>> to
>>>> LingeredApp or match ThreadName: " + attachE);
>>>>>>>>>>>> +
>>>>>>>>>>>> +        } finally {
>>>>>>>>>>>> +            LingeredApp.stopApp(app);
>>>>>>>>>>>> +        }
>>>>>>>>>>>> +    }
>>>>>>>>>>>> +}
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Regards,
>>>>>>>>>>>> Chihiro
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On 2017/06/14 16:51, Bernd Eckenfels wrote:
>>>>>>>>>>>>> I don't understand why this format is totally different
>> from
>>>> the normal stack traces? At least the header with the stack names
>> could
>>>> be similar?
>>>>>>>>>>>>> Gruss
>>>>>>>>>>>>> Bernd
>>>>>>>>>>>>> --
>>>>>>>>>>>>> https://urldefense.proofpoint.com/v2/url?u=http-
>>>>
>> 3A__bernd.eckenfels.net&d=DwICaQ&c=RoP1YumCXCgaWHvlZYR8PQcxBKCX5YTpkKY0
>>>>
>> 57SbK10&r=0SCyhNQIV2jPt0aEruqsRB6bzVcIXHTDh1GkXLV1dyY&m=3QRaQqXxp0PcpNU
>>>> QsiJOAlmzxeN3O9PyZoFxlIPpsUs&s=KMibjgBgQ9DJ0ddSGSJrvH7PZMz4zGnH-
>> CZml-
>>>> iRTMM&e= -----------------------------------------------------------
>> ---
>>>> ----------
>>>>>>>>>>>>> *From:* serviceability-dev <serviceability-dev-
>>>> bounces@openjdk.java.net> on behalf of chihiro ito
>>>> <chihiro.ito@oracle.com>
>>>>>>>>>>>>> *Sent:* Wednesday, June 14, 2017 9:17:42 AM
>>>>>>>>>>>>> *To:* Jini George; serviceability-dev@openjdk.java.net
>>>>>>>>>>>>> *Subject:* Re: [10] RFR 8181647: jhsdb jstack could not
>>>> output thread name
>>>>>>>>>>>>> Hi all,
>>>>>>>>>>>>>
>>>>>>>>>>>>> I added a test case and modified previous patch including
>> fix
>>>> the
>>>>>>>>>>>>> copyright year to 2017.
>>>>>>>>>>>>> I changed to output Java thread name next the separator
>> lines
>>>> in "jhsdb
>>>>>>>>>>>>> jstack --mixed" case as following.
>>>>>>>>>>>>>
>>>>>>>>>>>>> ----------------- 32117 -----------------
>>>>>>>>>>>>> "main"
>>>>>>>>>>>>> 0x00007f6c8feafa82    __pthread_cond_timedwait + 0x132
>>>>>>>>>>>>>
>>>>>>>>>>>>> Could you possibly review for this following small change?
>> If
>>>> review is
>>>>>>>>>>>>> ok, please commit this as cito.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Source:
>>>>>>>>>>>>> diff --git
>>>>>>>>>>>>>
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>>>>>> ---
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>>>>>> +++
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>>>>>>>     /*
>>>>>>>>>>>>> - * Copyright (c) 2003, 2013, Oracle and/or its affiliates.
>>>> All rights
>>>>>>>>>>>>> reserved.
>>>>>>>>>>>>> + * Copyright (c) 2003, 2017, Oracle and/or its affiliates.
>>>> All rights
>>>>>>>>>>>>> reserved.
>>>>>>>>>>>>>      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>>>>>      *
>>>>>>>>>>>>>      * This code is free software; you can redistribute it
>>>> and/or modify it
>>>>>>>>>>>>> @@ -88,6 +88,12 @@
>>>>>>>>>>>>>                    out.print("----------------- ");
>>>>>>>>>>>>>                    out.print(th);
>>>>>>>>>>>>>                    out.println(" -----------------");
>>>>>>>>>>>>> +               JavaThread jthread = (JavaThread)
>>>> proxyToThread.get(th);
>>>>>>>>>>>>> +               if (jthread != null) {
>>>>>>>>>>>>> +                   out.print("\"");
>>>>>>>>>>>>> + out.print(jthread.getThreadName());
>>>>>>>>>>>>> +                   out.println("\"");
>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>                    while (f != null) {
>>>>>>>>>>>>>                       ClosestSymbol sym =
>>>> f.closestSymbolToPC();
>>>>>>>>>>>>>                       Address pc = f.pc();
>>>>>>>>>>>>> diff --git
>>>>>>>>>>>>>
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>>>>>> ---
>>>>>>>>>>>>>
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>>>>>> +++
>>>>>>>>>>>>>
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>>>>>> @@ -1,5 +1,5 @@
>>>>>>>>>>>>>     /*
>>>>>>>>>>>>> - * Copyright (c) 2002, 2013, Oracle and/or its affiliates.
>>>> All rights
>>>>>>>>>>>>> reserved.
>>>>>>>>>>>>> + * Copyright (c) 2002, 2017, Oracle and/or its affiliates.
>>>> All rights
>>>>>>>>>>>>> reserved.
>>>>>>>>>>>>>      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>>>>>      *
>>>>>>>>>>>>>      * This code is free software; you can redistribute it
>>>> and/or modify it
>>>>>>>>>>>>> @@ -75,7 +75,9 @@
>>>>>>>>>>>>>                 for (JavaThread cur = threads.first(); cur
>> !=
>>>> null; cur =
>>>>>>>>>>>>> cur.next(), i++) {
>>>>>>>>>>>>>                     if (cur.isJavaThread()) {
>>>>>>>>>>>>>                         Address sp = cur.getLastJavaSP();
>>>>>>>>>>>>> -                    tty.print("Thread ");
>>>>>>>>>>>>> +                    tty.print("\"");
>>>>>>>>>>>>> +                    tty.print(cur.getThreadName());
>>>>>>>>>>>>> +                    tty.print("\" nid=");
>>>>>>>>>>>>>                         cur.printThreadIDOn(tty);
>>>>>>>>>>>>>                         tty.print(": (state = " +
>>>> cur.getThreadState());
>>>>>>>>>>>>>                         if (verbose) {
>>>>>>>>>>>>> diff --git
>> a/test/serviceability/sa/JhsdbThreadNameTest.java
>>>>>>>>>>>>> b/test/serviceability/sa/JhsdbThreadNameTest.java
>>>>>>>>>>>>> new file mode 100644
>>>>>>>>>>>>> --- /dev/null
>>>>>>>>>>>>> +++ b/test/serviceability/sa/JhsdbThreadNameTest.java
>>>>>>>>>>>>> @@ -0,0 +1,107 @@
>>>>>>>>>>>>> +/*
>>>>>>>>>>>>> + * Copyright (c) 2017, Oracle and/or its affiliates. All
>>>> rights reserved.
>>>>>>>>>>>>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
>>>> HEADER.
>>>>>>>>>>>>> + *
>>>>>>>>>>>>> + * This code is free software; you can redistribute it
>>>> and/or modify it
>>>>>>>>>>>>> + * under the terms of the GNU General Public License
>> version
>>>> 2 only, as
>>>>>>>>>>>>> + * published by the Free Software Foundation.
>>>>>>>>>>>>> + *
>>>>>>>>>>>>> + * This code is distributed in the hope that it will be
>>>> useful, but WITHOUT
>>>>>>>>>>>>> + * ANY WARRANTY; without even the implied warranty of
>>>> MERCHANTABILITY or
>>>>>>>>>>>>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
>>>> Public License
>>>>>>>>>>>>> + * version 2 for more details (a copy is included in the
>>>> LICENSE file that
>>>>>>>>>>>>> + * accompanied this code).
>>>>>>>>>>>>> + *
>>>>>>>>>>>>> + * You should have received a copy of the GNU General
>> Public
>>>> License
>>>>>>>>>>>>> version
>>>>>>>>>>>>> + * 2 along with this work; if not, write to the Free
>>>> Software Foundation,
>>>>>>>>>>>>> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-
>> 1301
>>>> USA.
>>>>>>>>>>>>> + *
>>>>>>>>>>>>> + * Please contact Oracle, 500 Oracle Parkway, Redwood
>>>> Shores, CA 94065 USA
>>>>>>>>>>>>> + * or visit www.oracle.com <http://www.oracle.com> if you
>>>> need additional information or have any
>>>>>>>>>>>>> + * questions.
>>>>>>>>>>>>> + */
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +import java.util.ArrayList;
>>>>>>>>>>>>> +import java.util.Arrays;
>>>>>>>>>>>>> +import java.util.List;
>>>>>>>>>>>>> +import java.util.function.Consumer;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +import jdk.test.lib.apps.LingeredApp;
>>>>>>>>>>>>> +import jdk.test.lib.JDKToolLauncher;
>>>>>>>>>>>>> +import jdk.test.lib.Platform;
>>>>>>>>>>>>> +import jdk.test.lib.process.OutputAnalyzer;
>>>>>>>>>>>>> +import jdk.test.lib.Utils;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +/*
>>>>>>>>>>>>> + * @test
>>>>>>>>>>>>> + * @library /test/lib
>>>>>>>>>>>>> + * @run main/othervm JhsdbThreadNameTest
>>>>>>>>>>>>> + */
>>>>>>>>>>>>> +public class JhsdbThreadNameTest {
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +    private static String notMixedModeThreadNames[] =
>>>>>>>>>>>>> {"Common-Cleaner", "Signal Dispatcher", "Finalizer",
>>>> "Reference
>>>>>>>>>>>>> Handler", "main"};
>>>>>>>>>>>>> +    private static String mixedModeThreadNames[] = {"C2
>>>>>>>>>>>>> CompilerThread0", "C1 CompilerThread1", "Sweeper thread",
>>>> "Service Thread"};
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +    private static void startHsdbJstack(boolean mixed)
>>>> throws Exception {
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +        LingeredApp app = null;
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +        try {
>>>>>>>>>>>>> +            List<String> vmArgs = new ArrayList<String>();
>>>>>>>>>>>>> +            vmArgs.add("-Xmx10m");
>>>>>>>>>>>>> +            vmArgs.addAll(Utils.getVmOptions());
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +            app = LingeredApp.startApp(vmArgs);
>>>>>>>>>>>>> +            System.out.println("Started LingeredApp with
>> pid
>>>> " +
>>>>>>>>>>>>> app.getPid());
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +            JDKToolLauncher jhsdbLauncher =
>>>>>>>>>>>>> JDKToolLauncher.createUsingTestJDK("jhsdb");
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +            jhsdbLauncher.addToolArg("jstack");
>>>>>>>>>>>>> +            jhsdbLauncher.addToolArg("--pid");
>>>>>>>>>>>>> + jhsdbLauncher.addToolArg(Long.toString(app.getPid()));
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +            if (mixed) {
>>>>>>>>>>>>> + jhsdbLauncher.addToolArg("--mixed");
>>>>>>>>>>>>> +            }
>>>>>>>>>>>>> +            ProcessBuilder pb = new ProcessBuilder();
>>>>>>>>>>>>> +            pb.command(jhsdbLauncher.getCommand());
>>>>>>>>>>>>> +            Process jhsdb = pb.start();
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +            jhsdb.waitFor();
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +            OutputAnalyzer out = new
>> OutputAnalyzer(jhsdb);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +
>>>>>>>>>>>>>
>>>>
>> Arrays.stream(notMixedModeThreadNames).map(JhsdbThreadNameTest::addQuot
>>>> ationMarks).forEach(out::shouldContain);
>>>>>>>>>>>>> +            Consumer<String> testMethod = null;
>>>>>>>>>>>>> +            if (mixed) {
>>>>>>>>>>>>> +                testMethod = out::shouldContain;
>>>>>>>>>>>>> +            } else {
>>>>>>>>>>>>> +                testMethod = out::shouldNotContain;
>>>>>>>>>>>>> +            }
>>>>>>>>>>>>> +
>>>>>>>>>>>>>
>>>>
>> Arrays.stream(mixedModeThreadNames).map(JhsdbThreadNameTest::addQuotati
>>>> onMarks).forEach(testMethod);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +        } catch (InterruptedException ie) {
>>>>>>>>>>>>> +            throw new Error("Problem awaiting the child
>>>> process: " +
>>>>>>>>>>>>> ie, ie);
>>>>>>>>>>>>> +        } catch (Exception attachE) {
>>>>>>>>>>>>> +            throw new Error("Couldn't start jhsdb, attach
>> to
>>>>>>>>>>>>> LingeredApp or match ThreadName: " + attachE);
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +        } finally {
>>>>>>>>>>>>> +            LingeredApp.stopApp(app);
>>>>>>>>>>>>> +        }
>>>>>>>>>>>>> +    }
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +    private static String addQuotationMarks(String str) {
>>>>>>>>>>>>> +        return "\"" + str + "\"";
>>>>>>>>>>>>> +    }
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +    public static void main(String[] args) throws
>> Exception
>>>> {
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +        if (!Platform.shouldSAAttach()) {
>>>>>>>>>>>>> +            System.out.println("SA attach not expected to
>>>> work - test
>>>>>>>>>>>>> skipped.");
>>>>>>>>>>>>> +            return;
>>>>>>>>>>>>> +        }
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +        startHsdbJstack(true);
>>>>>>>>>>>>> +        startHsdbJstack(false);
>>>>>>>>>>>>> +    }
>>>>>>>>>>>>> +}
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Regards,
>>>>>>>>>>>>> Chihiro
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 2017/06/08 18:04, chihiro ito wrote:
>>>>>>>>>>>>>> Hi Jini,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thank you for your advices. I try to add the test case and
>>>> modify the
>>>>>>>>>>>>>> copyright year to 2017.
>>>>>>>>>>>>>> Basically, I agree with your idea, but I think that the
>>>> separator line
>>>>>>>>>>>>>> should finally be the same as the output of the jstack
>>>> command. I
>>>>>>>>>>>>>> worry which is better way.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>> Chihiro
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On 2017/06/08 16:42, Jini George wrote:
>>>>>>>>>>>>>>> Hi Chihiro,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thank you for making this useful change. Your changes
>> look
>>>> good.
>>>>>>>>>>>>>>> It would be great though if you could add a test case for
>>>> this. Could
>>>>>>>>>>>>>>> you also modify the copyright year to 2017 ? One
>>>> additional
>>>>>>>>>>>>>>> suggestion: The addition of the thread name makes the
>>>> separator lines
>>>>>>>>>>>>>>> unaligned in the pstack/jstack --mixed cases. Like:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ----------------- "Service Thread" nid=16051 ------------
>> -
>>>> ----
>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>> ----------------- nid=16052 -----------------
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> So I am wondering if it would make sense to have the name
>>>> printed out
>>>>>>>>>>>>>>> on a separate line to keep the separator lines aligned.
>>>> But this is a
>>>>>>>>>>>>>>> nit, and I would leave it to you to decide on this.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>> Jini (Not a (R)eviewer)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On 6/7/2017 3:16 PM, chihiro ito wrote:
>>>>>>>>>>>>>>>> Hi all,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I changed to output Java thread name in jhsdb jstack as
>>>> following.
>>>>>>>>>>>>>>>> jhsdb jstack --pid 25879
>>>>>>>>>>>>>>>> "main" nid=25884: (state = BLOCKED)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> jhsdb jstack --mixed --pid 25879
>>>>>>>>>>>>>>>> ----------------- "main" nid=25884 -----------------
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Could you possibly review for this following small
>>>> change? If review
>>>>>>>>>>>>>>>> is ok, please commit this as cito.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Source:
>>>>>>>>>>>>>>>> diff --git
>>>>>>>>>>>>>>>>
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java
>>>>>>>>>>>>>>>> @@ -86,6 +86,13 @@
>>>>>>>>>>>>>>>>                try {
>>>>>>>>>>>>>>>>                   CFrame f = cdbg.topFrameForThread(th);
>>>>>>>>>>>>>>>> out.print("----------------- ");
>>>>>>>>>>>>>>>> +               JavaThread jthread = (JavaThread)
>>>>>>>>>>>>>>>> proxyToThread.get(th);
>>>>>>>>>>>>>>>> +               if (jthread != null) {
>>>>>>>>>>>>>>>> +                   out.print("\"");
>>>>>>>>>>>>>>>> + out.print(jthread.getThreadName());
>>>>>>>>>>>>>>>> +                   out.print("\" ");
>>>>>>>>>>>>>>>> +               }
>>>>>>>>>>>>>>>> +               out.print("nid=");
>>>>>>>>>>>>>>>>                   out.print(th);
>>>>>>>>>>>>>>>>                   out.println(" -----------------");
>>>>>>>>>>>>>>>>                   while (f != null) {
>>>>>>>>>>>>>>>> diff --git
>>>>>>>>>>>>>>>>
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>>
>>>>
>> a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>>>>>>>>> +++
>>>>>>>>>>>>>>>>
>>>>
>> b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/StackTrace.
>>>> java
>>>>>>>>>>>>>>>> @@ -75,7 +75,9 @@
>>>>>>>>>>>>>>>>                for (JavaThread cur = threads.first(); cur
>>>> != null; cur
>>>>>>>>>>>>>>>> = cur.next(), i++) {
>>>>>>>>>>>>>>>>                    if (cur.isJavaThread()) {
>>>>>>>>>>>>>>>>                        Address sp = cur.getLastJavaSP();
>>>>>>>>>>>>>>>> -                    tty.print("Thread ");
>>>>>>>>>>>>>>>> +                    tty.print("\"");
>>>>>>>>>>>>>>>> + tty.print(cur.getThreadName());
>>>>>>>>>>>>>>>> +                    tty.print("\" nid=");
>>>>>>>>>>>>>>>> cur.printThreadIDOn(tty);
>>>>>>>>>>>>>>>>                        tty.print(": (state = " +
>>>> cur.getThreadState());
>>>>>>>>>>>>>>>>                        if (verbose) {
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Regards,
>>>>>>>>>>>>>>>> Chihiro
>>>>>>>>>>>>>>>>
>>
>> --
>> Chihiro Ito @Oracle Consulting
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic