[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:       Yasumasa Suenaga <yasuenag () gmail ! com>
Date:       2017-06-28 22:40:47
Message-ID: c5086795-8704-6fe1-02a8-2df22de4861a () gmail ! com
[Download RAW message or body]

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").intValue();
> >                 
> > -        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").intValue(); +  \
> > 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/JavaThread.java \
> >                 b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java
> >                 
> > --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.java
> > +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/JavaThread.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/ThreadState.java \
> > b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadState.java \
> >                 new file mode 100644
> > --- /dev/null
> > +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ThreadState.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
> > > --
> > > http://bernd.eckenfels.net
> > > ------------------------------------------------------------------------
> > > *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::addQuotationMarks).forEach(out::shouldContain);
> > >  +            Consumer<String> testMethod = null;
> > > +            if (mixed) {
> > > +                testMethod = out::shouldContain;
> > > +            } else {
> > > +                testMethod = out::shouldNotContain;
> > > +            }
> > > +
> > > Arrays.stream(mixedModeThreadNames).map(JhsdbThreadNameTest::addQuotationMarks).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 | Principal Consultant | +81.90.6148.8815
> > > Oracle <http://www.oracle.com> Consultant
> > > ORACLE Japan | Akasaka Center Bldg. | Motoakasaka 1-3-13 | 1070051
> > > Minato-ku, Tokyo, JAPAN
> > > 
> > > Oracle is committed to developing practices and products that help
> > > protect the environment <http://www.oracle.com/commitment>
> > 
> 


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

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