8261098: Add clhsdb "findsym" command

Reviewed-by: amenkov, sspitsyn
This commit is contained in:
Chris Plummer 2021-02-19 00:58:28 +00:00
parent 0c31d5b9c5
commit c158413e48
4 changed files with 83 additions and 8 deletions

View File

@ -68,7 +68,7 @@ class AutoJavaString {
public:
// check env->ExceptionOccurred() after ctor
AutoJavaString(JNIEnv* env, jstring str)
: m_env(env), m_str(str), m_buf(env->GetStringUTFChars(str, NULL)) {
: m_env(env), m_str(str), m_buf(str == NULL ? NULL : env->GetStringUTFChars(str, NULL)) {
}
~AutoJavaString() {
@ -350,12 +350,14 @@ JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_l
jlong addr;
jboolean isCopy;
struct ps_prochandle* ph = get_proc_handle(env, this_obj);
// Note, objectName is ignored, and may in fact be NULL.
// lookup_symbol will always search all objects/libs
AutoJavaString objectName_cstr(env, objectName);
CHECK_EXCEPTION_(0);
AutoJavaString symbolName_cstr(env, symbolName);
CHECK_EXCEPTION_(0);
addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr);
addr = (jlong) lookup_symbol(ph, NULL, symbolName_cstr);
return addr;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2021, 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
@ -47,6 +47,8 @@ import sun.jvm.hotspot.ci.ciEnv;
import sun.jvm.hotspot.code.CodeBlob;
import sun.jvm.hotspot.code.CodeCacheVisitor;
import sun.jvm.hotspot.code.NMethod;
import sun.jvm.hotspot.debugger.cdbg.CDebugger;
import sun.jvm.hotspot.debugger.cdbg.LoadObject;
import sun.jvm.hotspot.debugger.Address;
import sun.jvm.hotspot.debugger.OopHandle;
import sun.jvm.hotspot.classfile.ClassLoaderDataGraph;
@ -607,6 +609,40 @@ public class CommandProcessor {
}
}
},
new Command("findsym", "findsym name", false) {
public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();
} else {
String symbol = t.nextToken();
Address addr = VM.getVM().getDebugger().lookup(null, symbol);
if (addr == null && VM.getVM().getDebugger().getOS().equals("win32")) {
// On win32 symbols are prefixed with the dll name. Do the user
// a favor and see if this is a symbol in jvm.dll or java.dll.
addr = VM.getVM().getDebugger().lookup(null, "jvm!" + symbol);
if (addr == null) {
addr = VM.getVM().getDebugger().lookup(null, "java!" + symbol);
}
}
if (addr == null) {
out.println("Symbol not found");
return;
}
out.print(addr); // Print the address of the symbol.
CDebugger cdbg = VM.getVM().getDebugger().getCDebugger();
LoadObject loadObject = cdbg.loadObjectContainingPC(addr);
// Print the shared library path and the offset of the symbol.
if (loadObject != null) {
out.print(": " + loadObject.getName());
long diff = addr.minus(loadObject.getBase());
if (diff != 0L) {
out.print(" + 0x" + Long.toHexString(diff));
}
}
out.println();
}
}
},
new Command("findpc", "findpc address", false) {
public void doit(Tokens t) {
if (t.countTokens() != 1) {
@ -892,7 +928,7 @@ public class CommandProcessor {
}
},
new Command("dumpideal", "dumpideal { -a | id }", false) {
// Do a full dump of the nodes reachabile from root in each compiler thread.
// Do a full dump of the nodes reachable from root in each compiler thread.
public void doit(Tokens t) {
if (t.countTokens() != 1) {
usage();

View File

@ -101,7 +101,7 @@ class AutoJavaString {
public:
// check env->ExceptionOccurred() after ctor
AutoJavaString(JNIEnv* env, jstring str)
: m_env(env), m_str(str), m_buf(env->GetStringUTFChars(str, nullptr)) {
: m_env(env), m_str(str), m_buf(str == nullptr ? nullptr : env->GetStringUTFChars(str, nullptr)) {
}
~AutoJavaString() {

View File

@ -82,6 +82,7 @@ public class ClhsdbFindPC {
private static void testFindPC(boolean withXcomp, boolean withCore) throws Exception {
try {
String linesep = System.getProperty("line.separator");
String segvAddress = null;
List<String> cmds = null;
String cmdStr = null;
@ -218,7 +219,7 @@ public class ClhsdbFindPC {
String examineOutput = runTest(withCore, cmds, null);
// Extract <value>.
parts = examineOutput.split(tid + ": ");
String value = parts[1];
String value = parts[1].split(linesep)[0];
// Use findpc on <value>. The output should look something like:
// Address 0x00007fed86f610b8: vtable for JavaThread + 0x10
cmdStr = "findpc " + value;
@ -229,13 +230,49 @@ public class ClhsdbFindPC {
} else if (Platform.isOSX()) {
if (withCore) {
expStrMap.put(cmdStr, List.of("__ZTV10JavaThread"));
} else { // symbol lookups not supported with OSX live process
} else { // address -> symbol lookups not supported with OSX live process
expStrMap.put(cmdStr, List.of("In unknown location"));
}
} else {
expStrMap.put(cmdStr, List.of("vtable for JavaThread"));
}
runTest(withCore, cmds, expStrMap);
String findpcOutput = runTest(withCore, cmds, expStrMap);
// Determine if we have symbol support. Currently we assume yes except on windows.
boolean hasSymbols = true;
if (Platform.isWindows()) {
if (findpcOutput.indexOf("jvm!JavaThread::`vftable'") == -1) {
hasSymbols = false;
}
}
// Run "findsym MaxJNILocalCapacity". The output should look something like:
// 0x00007eff8e1a0da0: <jdk-dir>/lib/server/libjvm.so + 0x1d81da0
String symbol = "MaxJNILocalCapacity";
cmds = List.of("findsym " + symbol);
expStrMap = new HashMap<>();
if (!hasSymbols) {
expStrMap.put(cmdStr, List.of("Symbol not found"));
}
String findsymOutput = runTest(withCore, cmds, expStrMap);
// Run findpc on the result of "findsym MaxJNILocalCapacity". The output
// should look something like:
// Address 0x00007eff8e1a0da0: MaxJNILocalCapacity
if (hasSymbols) {
parts = findsymOutput.split("findsym " + symbol + linesep);
parts = parts[1].split(":");
String findsymAddress = parts[0].split(linesep)[0];
cmdStr = "findpc " + findsymAddress;
cmds = List.of(cmdStr);
expStrMap = new HashMap<>();
if (Platform.isOSX() && !withCore) {
// address -> symbol lookups not supported with OSX live process
expStrMap.put(cmdStr, List.of("Address " + findsymAddress + ": In unknown location"));
} else {
expStrMap.put(cmdStr, List.of("Address " + findsymAddress + ": .*" + symbol));
}
runTest(withCore, cmds, expStrMap);
}
} catch (SkippedException se) {
throw se;
} catch (Exception ex) {