Skip to content

Commit

Permalink
8263635: Add --servername option to jhsdb debugd
Browse files Browse the repository at this point in the history
Reviewed-by: cjplummer, sspitsyn
  • Loading branch information
YaSuenag committed May 27, 2021
1 parent 6ffa3e6 commit 37bc4e2
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 104 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
Expand Down Expand Up @@ -103,11 +103,11 @@ private void run(String[] args) {
try {
if (usePid) {
System.err.println("Attaching to process ID " + pid + " and starting RMI services, please wait...");
agent.startServer(pid, serverID);
agent.startServer(pid, serverID, null);
} else {
System.err.println("Attaching to core " + coreFileName +
" from executable " + javaExecutableName + " and starting RMI services, please wait...");
agent.startServer(javaExecutableName, coreFileName, serverID);
agent.startServer(javaExecutableName, coreFileName, serverID, null);
}
}
catch (DebuggerException e) {
Expand Down
Expand Up @@ -90,6 +90,7 @@ public class HotSpotAgent {

// All needed information for server side
private String serverID;
private String serverName;

private String[] jvmLibNames;

Expand Down Expand Up @@ -203,15 +204,17 @@ public synchronized boolean detach() throws DebuggerException {
to which the RMI connector is bound. If not specified a random
available port is used. */
public synchronized void startServer(int processID,
String uniqueID,
String serverID,
String serverName,
int rmiPort) {
if (debugger != null) {
throw new DebuggerException("Already attached");
}
pid = processID;
startupMode = PROCESS_MODE;
isServer = true;
serverID = uniqueID;
this.serverID = serverID;
this.serverName = serverName;
this.rmiPort = rmiPort;
go();
}
Expand All @@ -220,16 +223,16 @@ public synchronized void startServer(int processID,
starts a debug server, allowing remote machines to connect and
examine this process. Uses specified name to uniquely identify a
specific debuggee on the server */
public synchronized void startServer(int processID, String uniqueID) {
startServer(processID, uniqueID, 0);
public synchronized void startServer(int processID, String serverID, String serverName) {
startServer(processID, serverID, serverName, 0);
}

/** This attaches to a process running on the local machine and
starts a debug server, allowing remote machines to connect and
examine this process. */
public synchronized void startServer(int processID)
throws DebuggerException {
startServer(processID, null);
startServer(processID, null, null);
}

/** This opens a core file on the local machine and starts a debug
Expand All @@ -239,7 +242,8 @@ public synchronized void startServer(int processID)
is bound. If not specified a random available port is used. */
public synchronized void startServer(String javaExecutableName,
String coreFileName,
String uniqueID,
String serverID,
String serverName,
int rmiPort) {
if (debugger != null) {
throw new DebuggerException("Already attached");
Expand All @@ -251,7 +255,8 @@ public synchronized void startServer(String javaExecutableName,
this.coreFileName = coreFileName;
startupMode = CORE_FILE_MODE;
isServer = true;
serverID = uniqueID;
this.serverID = serverID;
this.serverName = serverName;
this.rmiPort = rmiPort;
go();
}
Expand All @@ -262,16 +267,17 @@ public synchronized void startServer(String javaExecutableName,
debugee */
public synchronized void startServer(String javaExecutableName,
String coreFileName,
String uniqueID) {
startServer(javaExecutableName, coreFileName, uniqueID, 0);
String serverID,
String serverName) {
startServer(javaExecutableName, coreFileName, serverID, serverName, 0);
}

/** This opens a core file on the local machine and starts a debug
server, allowing remote machines to connect and examine this
core file. */
public synchronized void startServer(String javaExecutableName, String coreFileName)
throws DebuggerException {
startServer(javaExecutableName, coreFileName, null);
startServer(javaExecutableName, coreFileName, null, null);
}

/** This may only be called on the server side after startServer()
Expand Down Expand Up @@ -302,7 +308,7 @@ private boolean detachInternal() {
DebuggerException ex = null;
if (isServer) {
try {
RMIHelper.unbind(serverID);
RMIHelper.unbind(serverID, serverName);
}
catch (DebuggerException de) {
ex = de;
Expand Down Expand Up @@ -377,7 +383,7 @@ private void setupDebugger() {
catch (RemoteException rem) {
throw new DebuggerException(rem);
}
RMIHelper.rebind(serverID, remote);
RMIHelper.rebind(serverID, serverName, remote);
}
} else {
//
Expand Down
73 changes: 45 additions & 28 deletions src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/RMIHelper.java
Expand Up @@ -28,12 +28,14 @@
import java.net.*;
import java.rmi.*;
import java.rmi.registry.*;
import java.util.regex.*;
import sun.jvm.hotspot.debugger.DebuggerException;

public class RMIHelper {
private static final boolean startRegistry;
private static final Pattern CONNECT_PATTERN = Pattern.compile("^((?<serverid>.+?)@)?(?<host>.+?)(/(?<servername>.+))?$");
private static final String DEFAULT_RMI_OBJECT_NAME = "SARemoteDebugger";
private static int port;
private static String serverNamePrefix;

static {
String tmp = System.getProperty("sun.jvm.hotspot.rmi.startRegistry");
Expand All @@ -53,12 +55,10 @@ public class RMIHelper {
System.err.println("invalid port supplied, assuming default");
}
}

serverNamePrefix = System.getProperty("sun.jvm.hotspot.rmi.serverNamePrefix", "SARemoteDebugger");
}

public static void rebind(String uniqueID, Remote object) throws DebuggerException {
String name = getName(uniqueID);
public static void rebind(String serverID, String serverName, Remote object) throws DebuggerException {
String name = getName(serverID, serverName);
try {
Naming.rebind(name, object);
} catch (RemoteException re) {
Expand All @@ -78,34 +78,41 @@ public static void rebind(String uniqueID, Remote object) throws DebuggerExcepti
}
}

public static void unbind(String uniqueID) throws DebuggerException {
String name = getName(uniqueID);
public static void unbind(String serverID, String serverName) throws DebuggerException {
String name = getName(serverID, serverName);
try {
Naming.unbind(name);
} catch (Exception exp) {
throw new DebuggerException(exp);
}
}

public static Remote lookup(String debugServerID) throws DebuggerException {
// debugServerID follows the pattern [unique_id@]host[:port]
// we have to transform this as //host[:port]/<serverNamePrefix>['_'<unique_id>]
public static Remote lookup(String connectionString) throws DebuggerException {
// connectionString follows the pattern [serverid@]host[:port][/servername]
// we have to transform this as //host[:port]/<servername>['_'<serverid>]
Matcher matcher = CONNECT_PATTERN.matcher(connectionString);
matcher.find();

int index = debugServerID.indexOf('@');
StringBuilder nameBuf = new StringBuilder("//");
String uniqueID = null;
if (index != -1) {
nameBuf.append(debugServerID.substring(index + 1));
uniqueID = debugServerID.substring(0, index);
} else {
nameBuf.append(debugServerID);
String serverNamePrefix = System.getProperty("sun.jvm.hotspot.rmi.serverNamePrefix");
String rmiObjectName = matcher.group("servername");
if (serverNamePrefix != null) {
if (rmiObjectName == null) {
System.err.println("WARNING: sun.jvm.hotspot.rmi.serverNamePrefix is deprecated. Please specify it in --connect.");
rmiObjectName = serverNamePrefix;
} else {
throw new DebuggerException("Cannot set both sun.jvm.hotspot.rmi.serverNamePrefix and servername in --connect together");
}
}

if (rmiObjectName == null) {
rmiObjectName = DEFAULT_RMI_OBJECT_NAME;
}
StringBuilder nameBuf = new StringBuilder("//");
nameBuf.append(matcher.group("host"));
nameBuf.append('/');
nameBuf.append(serverNamePrefix);
if (uniqueID != null) {
nameBuf.append(rmiObjectName);
if (matcher.group("serverid") != null) {
nameBuf.append('_');
nameBuf.append(uniqueID);
nameBuf.append(matcher.group("serverid"));
}

try {
Expand All @@ -115,12 +122,22 @@ public static Remote lookup(String debugServerID) throws DebuggerException {
}
}

private static String getName(String uniqueID) {
String name = null;
if (uniqueID != null) {
name = serverNamePrefix + "_" + uniqueID;
} else {
name = serverNamePrefix;
private static String getName(String serverID, String serverName) {
String name = serverName;
String serverNamePrefix = System.getProperty("sun.jvm.hotspot.rmi.serverNamePrefix");
if (serverNamePrefix != null) {
if (serverName == null) {
System.err.println("WARNING: sun.jvm.hotspot.rmi.serverNamePrefix is deprecated. Please specify it with --servername.");
name = serverNamePrefix;
} else {
throw new DebuggerException("Cannot set both sun.jvm.hotspot.rmi.serverNamePrefix and --servername together");
}
}
if (name == null) {
name = DEFAULT_RMI_OBJECT_NAME;
}
if (serverID != null) {
name += "_" + serverID;
}
if (port != Registry.REGISTRY_PORT) {
name = "//localhost:" + port + "/" + name;
Expand Down
Expand Up @@ -68,7 +68,7 @@ private static boolean commonHelp(String mode, boolean canConnectToRemote) {
System.out.println(" --core <corefile> To operate on the given core file.");
System.out.println(" --exe <executable for corefile>");
if (canConnectToRemote) {
System.out.println(" --connect [<id>@]<host>[:registryport] To connect to a remote debug server (debugd).");
System.out.println(" --connect [<serverid>@]<host>[:registryport][/servername] To connect to a remote debug server (debugd).");
}
System.out.println();
System.out.println(" The --core and --exe options must be set together to give the core");
Expand All @@ -85,15 +85,14 @@ private static boolean commonHelp(String mode, boolean canConnectToRemote) {
System.out.println(" Examples: jhsdb " + mode + " --pid 1234");
System.out.println(" or jhsdb " + mode + " --core ./core.1234 --exe ./myexe");
if (canConnectToRemote) {
System.out.println(" or jhsdb " + mode + " --connect id@debugserver:1234");
System.out.println(" or jhsdb " + mode + " --connect serverid@debugserver:1234/servername");
}
return false;
}

private static boolean debugdHelp() {
// [options] <pid> [server-id]
// [options] <executable> <core> [server-id]
System.out.println(" --serverid <id> A unique identifier for this debug server.");
System.out.println(" --serverid <id> A unique identifier for this debugd server.");
System.out.println(" --servername <name> Instance name of debugd server.");
System.out.println(" --rmiport <port> Sets the port number to which the RMI connector is bound." +
" If not specified a random available port is used.");
System.out.println(" --registryport <port> Sets the RMI registry port." +
Expand Down Expand Up @@ -376,7 +375,8 @@ private static void runDEBUGD(String[] args) {
"rmiport=", "rmiport",
"registryport=", "registryport",
"disable-registry", "disable-registry",
"hostname=", "hostname");
"hostname=", "hostname",
"servername=", "servername");

Map<String, String> argMap = parseOptions(args, longOptsMap);

Expand All @@ -391,6 +391,7 @@ private static void runDEBUGD(String[] args) {
String javaExecutableName = argMap.get("exe");
String coreFileName = argMap.get("core");
String pidString = argMap.get("pid");
String serverName = argMap.get("servername");

// Set RMI registry port, if specified
if (registryPort != null) {
Expand Down Expand Up @@ -434,7 +435,7 @@ private static void runDEBUGD(String[] args) {
System.err.println("Attaching to process ID " + pid + " and starting RMI services," +
" please wait...");
try {
agent.startServer(pid, serverID, rmiPort);
agent.startServer(pid, serverID, serverName, rmiPort);
} catch (DebuggerException e) {
System.err.print("Error attaching to process or starting server: ");
e.printStackTrace();
Expand All @@ -446,7 +447,7 @@ private static void runDEBUGD(String[] args) {
System.err.println("Attaching to core " + coreFileName +
" from executable " + javaExecutableName + " and starting RMI services, please wait...");
try {
agent.startServer(javaExecutableName, coreFileName, serverID, rmiPort);
agent.startServer(javaExecutableName, coreFileName, serverID, serverName, rmiPort);
} catch (DebuggerException e) {
System.err.print("Error attaching to core file or starting server: ");
e.printStackTrace();
Expand Down
26 changes: 17 additions & 9 deletions src/jdk.hotspot.agent/share/man/jhsdb.1
Expand Up @@ -32,34 +32,34 @@ analyze the content of a core dump from a crashed Java Virtual Machine
.PP
\f[CB]jhsdb\f[R] \f[CB]clhsdb\f[R] [\f[CB]\-\-pid\f[R] \f[I]pid\f[R] |
\f[CB]\-\-exe\f[R] \f[I]executable\f[R] \f[CB]\-\-core\f[R] \f[I]coredump\f[R] |
\f[CB]\-\-connect\f[R] \f[I][server\-id\@]debugd\-host[:registryport]\f[R]\]
\f[CB]\-\-connect\f[R] \f[I][serverid\@]debugd\-host[:registryport][/servername]\f[R]\]
.PP
\f[CB]jhsdb\f[R] \f[CB]hsdb\f[R] [\f[CB]\-\-pid\f[R] \f[I]pid\f[R] |
\f[CB]\-\-exe\f[R] \f[I]executable\f[R] \f[CB]\-\-core\f[R] \f[I]coredump\f[R] |
\f[CB]\-\-connect\f[R] \f[I][server\-id\@]debugd\-host[:registryport]\f[R]\]
\f[CB]\-\-connect\f[R] \f[I][serverid\@]debugd\-host[:registryport][/servername]\f[R]\]
.PP
\f[CB]jhsdb\f[R] \f[CB]debugd\f[R] (\f[CB]\-\-pid\f[R] \f[I]pid\f[R] |
\f[CB]\-\-exe\f[R] \f[I]executable\f[R] \f[CB]\-\-core\f[R]
\f[I]coredump\f[R]) [\f[I]options\f[R]]
.PP
\f[CB]jhsdb\f[R] \f[CB]jstack\f[R] (\f[CB]\-\-pid\f[R] \f[I]pid\f[R] |
\f[CB]\-\-exe\f[R] \f[I]executable\f[R] \f[CB]\-\-core\f[R] \f[I]coredump\f[R]
| \f[CB]\-\-connect\f[R] \f[I][server\-id\@]debugd\-host[:registryport]\f[R])
| \f[CB]\-\-connect\f[R] \f[I][serverid\@]debugd\-host[:registryport][/servername]\f[R])
[\f[I]options\f[R]]
.PP
\f[CB]jhsdb\f[R] \f[CB]jmap\f[R] (\f[CB]\-\-pid\f[R] \f[I]pid\f[R] |
\f[CB]\-\-exe\f[R] \f[I]executable\f[R] \f[CB]\-\-core\f[R] \f[I]coredump\f[R]
| \f[CB]\-\-connect\f[R] \f[I][server\-id\@]debugd\-host[:registryport]\f[R])
| \f[CB]\-\-connect\f[R] \f[I][serverid\@]debugd\-host[:registryport][/servername]\f[R])
[\f[I]options\f[R]]
.PP
\f[CB]jhsdb\f[R] \f[CB]jinfo\f[R] (\f[CB]\-\-pid\f[R] \f[I]pid\f[R] |
\f[CB]\-\-exe\f[R] \f[I]executable\f[R] \f[CB]\-\-core\f[R] \f[I]coredump\f[R]
| \f[CB]\-\-connect\f[R] \f[I][server\-id\@]debugd\-host[:registryport]\f[R])
| \f[CB]\-\-connect\f[R] \f[I][serverid\@]debugd\-host[:registryport][/servername]\f[R])
[\f[I]options\f[R]]
.PP
\f[CB]jhsdb\f[R] \f[CB]jsnap\f[R] (\f[CB]\-\-pid\f[R] \f[I]pid\f[R] |
\f[CB]\-\-exe\f[R] \f[I]executable\f[R] \f[CB]\-\-core\f[R] \f[I]coredump\f[R]
| \f[CB]\-\-connect\f[R] \f[I][server\-id\@]debugd\-host[:registryport]\f[R])
| \f[CB]\-\-connect\f[R] \f[I][serverid\@]debugd\-host[:registryport][/servername]\f[R])
[\f[I]options\f[R]]
.TP
.B \f[I]pid\f[R]
Expand All @@ -81,7 +81,7 @@ The core file to which the \f[CB]jhsdb\f[R] tool should attach.
.RS
.RE
.TP
.B \f[I][server\-id\@]debugd\-host[:registryport]\f[R]
.B \f[I][serverid\@]debugd\-host[:registryport][/servername]\f[R]
An optional server ID and the address of the remote debug server
(debugd).
.RS
Expand Down Expand Up @@ -158,9 +158,10 @@ Displays the options available for the \f[I]command\f[R].
.RE
.SH OPTIONS FOR THE DEBUGD MODE
.TP
.B \f[CB]\-\-serverid\f[R] \f[I]server\-id\f[R]
.B \f[CB]\-\-serverid\f[R] \f[I]serverid\f[R]
An optional unique ID for this debug server.
This is required if multiple debug servers are run on the same machine.
This is required if multiple debug servers are run on the same server instance.
It would be added to RMI object name for server instance.
.RS
.RE
.TP
Expand Down Expand Up @@ -198,6 +199,13 @@ If not specified, the system property is used.
If the system property is not set, a system hostname is used.
.RS
.RE
.TP
.B \f[CB]\-\-servername\f[R] \f[I]servername\f[R]
Sets the instance name of debugd server to distinguish SA debugee.
It is used for RMI object name for server instance.
If not specified, "SARemoteDebugger" will be used.
.RS
.RE
.SH OPTIONS FOR THE JINFO MODE
.TP
.B \f[CB]\-\-flags\f[R]
Expand Down
Expand Up @@ -54,7 +54,7 @@ public static void main(String[] args) throws Exception {
try {
theApp = LingeredApp.startApp();
System.out.println("Started LingeredApp with pid " + theApp.getPid());
debugd = new DebugdUtils(null);
debugd = new DebugdUtils();
debugd.attach(theApp.getPid());

JDKToolLauncher jhsdbLauncher = JDKToolLauncher.createUsingTestJDK("jhsdb");
Expand Down

1 comment on commit 37bc4e2

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.