8250801: Add clhsdb "threadcontext" command
Reviewed-by: sspitsyn, kevinw
This commit is contained in:
parent
fd9fb9a4af
commit
bdfa15d92c
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot
test/hotspot/jtreg/serviceability/sa
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2022, 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
|
||||
@ -1671,19 +1671,54 @@ public class CommandProcessor {
|
||||
}
|
||||
}
|
||||
},
|
||||
new Command("threadcontext", "threadcontext [-v] { -a | id }", false) {
|
||||
public void doit(Tokens t) {
|
||||
boolean verbose = false;
|
||||
if (t.countTokens() == 2) {
|
||||
if (t.nextToken().equals("-v")) {
|
||||
verbose = true;
|
||||
} else {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (t.countTokens() != 1) {
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
String id = t.nextToken();
|
||||
Threads threads = VM.getVM().getThreads();
|
||||
boolean all = id.equals("-a");
|
||||
for (int i = 0; i < threads.getNumberOfThreads(); i++) {
|
||||
JavaThread thread = threads.getJavaThreadAt(i);
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
thread.printThreadIDOn(new PrintStream(bos));
|
||||
if (all || bos.toString().equals(id)) {
|
||||
out.format("Thread \"%s\" id=%s Address=%s\n",
|
||||
thread.getThreadName(), bos.toString(), thread.getAddress());
|
||||
thread.printThreadContextOn(out, verbose);
|
||||
out.println(" ");
|
||||
if (!all) return;
|
||||
}
|
||||
}
|
||||
if (!all) {
|
||||
out.println("Couldn't find thread " + id);
|
||||
}
|
||||
}
|
||||
},
|
||||
new Command("thread", "thread { -a | id }", false) {
|
||||
public void doit(Tokens t) {
|
||||
if (t.countTokens() != 1) {
|
||||
usage();
|
||||
} else {
|
||||
String name = t.nextToken();
|
||||
String id = t.nextToken();
|
||||
Threads threads = VM.getVM().getThreads();
|
||||
boolean all = name.equals("-a");
|
||||
boolean all = id.equals("-a");
|
||||
for (int i = 0; i < threads.getNumberOfThreads(); i++) {
|
||||
JavaThread thread = threads.getJavaThreadAt(i);
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
thread.printThreadIDOn(new PrintStream(bos));
|
||||
if (all || bos.toString().equals(name)) {
|
||||
if (all || bos.toString().equals(id)) {
|
||||
out.println("Thread " + bos.toString() + " Address " + thread.getAddress());
|
||||
thread.printInfoOn(out);
|
||||
out.println(" ");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2022, 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
|
||||
@ -481,6 +481,25 @@ public class JavaThread extends Thread {
|
||||
return access.getLastSP(addr);
|
||||
}
|
||||
|
||||
// Print the contents of all registers in the thread's context
|
||||
public void printThreadContextOn(PrintStream out, boolean verbose){
|
||||
ThreadContext tc = getThreadProxy().getContext();
|
||||
for (int r = 0; r < tc.getNumRegisters(); r++) {
|
||||
Address regAddr = tc.getRegisterAsAddress(r);
|
||||
System.out.format("%s: %s", tc.getRegisterName(r), regAddr);
|
||||
if (regAddr == null) {
|
||||
System.out.println();
|
||||
} else {
|
||||
PointerLocation l = PointerFinder.find(regAddr);
|
||||
if (l.isUnknown()) {
|
||||
System.out.println();
|
||||
} else {
|
||||
System.out.print(": ");
|
||||
l.printOn(System.out, false, verbose);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void printThreadInfoOn(PrintStream out){
|
||||
Oop threadOop = this.getThreadObj();
|
||||
|
108
test/hotspot/jtreg/serviceability/sa/ClhsdbThreadContext.java
Normal file
108
test/hotspot/jtreg/serviceability/sa/ClhsdbThreadContext.java
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2022, 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 java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jdk.test.lib.apps.LingeredApp;
|
||||
import jtreg.SkippedException;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test clhsdb where command
|
||||
* @requires vm.hasSA
|
||||
* @library /test/lib
|
||||
* @run main/othervm ClhsdbThreadContext
|
||||
*/
|
||||
|
||||
public class ClhsdbThreadContext {
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Starting ClhsdbThreadContext test");
|
||||
|
||||
LingeredApp theApp = null;
|
||||
try {
|
||||
ClhsdbLauncher test = new ClhsdbLauncher();
|
||||
theApp = LingeredApp.startApp();
|
||||
System.out.println("Started LingeredApp with pid " + theApp.getPid());
|
||||
|
||||
// Run threadcontext on all threads
|
||||
String cmdStr = "threadcontext -a";
|
||||
List<String> cmds = List.of(cmdStr);
|
||||
Map<String, List<String>> expStrMap = new HashMap<>();
|
||||
expStrMap.put(cmdStr, List.of(
|
||||
"Thread \"Common-Cleaner\"",
|
||||
"Thread \"Service Thread\"",
|
||||
"Thread \"Finalizer\"",
|
||||
"Thread \"SteadyStateThread\"",
|
||||
"In java stack for thread \"SteadyStateThread\""));
|
||||
String cmdOutput = test.run(theApp.getPid(), cmds, expStrMap, null);
|
||||
|
||||
// Run threadcontext on all threads in verbose mode
|
||||
cmdStr = "threadcontext -v -a";
|
||||
cmds = List.of(cmdStr);
|
||||
expStrMap = new HashMap<>();
|
||||
expStrMap.put(cmdStr, List.of(
|
||||
"Thread \"Common-Cleaner\"",
|
||||
"Thread \"Service Thread\"",
|
||||
"Thread \"Finalizer\"",
|
||||
"Thread \"SteadyStateThread\""));
|
||||
Map<String, List<String>> unexpStrMap = new HashMap<>();
|
||||
unexpStrMap.put(cmdStr, List.of(
|
||||
"In java stack for thread \"SteadyStateThread\""));
|
||||
test.run(theApp.getPid(), cmds, expStrMap, unexpStrMap);
|
||||
|
||||
// Look for a line like the following and parse the threadID out of it.
|
||||
// Thread "SteadyStateThread" id=18010 Address=0x000014bf103eaf50
|
||||
String[] parts = cmdOutput.split("Thread \"SteadyStateThread\" id=");
|
||||
String[] tokens = parts[1].split(" ");
|
||||
String threadID = tokens[0];
|
||||
|
||||
// Run threadcontext on the SteadyStateThread in verbose mode
|
||||
cmdStr = "threadcontext -v " + threadID;
|
||||
cmds = List.of(cmdStr);
|
||||
expStrMap = new HashMap<>();
|
||||
expStrMap.put(cmdStr, List.of(
|
||||
"Thread \"SteadyStateThread\"",
|
||||
"java.lang.Thread.State: BLOCKED",
|
||||
"In java stack \\[0x\\p{XDigit}+,0x\\p{XDigit}+,0x\\p{XDigit}+\\] for thread"));
|
||||
unexpStrMap = new HashMap<>();
|
||||
unexpStrMap.put(cmdStr, List.of(
|
||||
"Thread \"Common-Cleaner\"",
|
||||
"Thread \"Service Thread\"",
|
||||
"Thread \"Finalizer\""));
|
||||
test.run(theApp.getPid(), cmds, expStrMap, unexpStrMap);
|
||||
|
||||
// Run threadcontext on all threads in verbose mode
|
||||
|
||||
} catch (SkippedException se) {
|
||||
throw se;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Test ERROR " + ex, ex);
|
||||
} finally {
|
||||
LingeredApp.stopApp(theApp);
|
||||
}
|
||||
|
||||
System.out.println("Test PASSED");
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user