Skip to content
Permalink
Browse files
8262520: Add SA Command Line Debugger support to connect to debug server
Reviewed-by: cjplummer, kevinw
  • Loading branch information
YaSuenag committed Mar 9, 2021
1 parent e5ce97b commit 70342e8513d05a05ebb4b38b5d75c6dda15dcfd2
@@ -36,7 +36,7 @@ <h3>Annotated output of CLHSDB help command</h3>
<code>
Available commands:
assert true | false <font color="red">turn on/off asserts in SA code</font>
attach pid | exec core <font color="red">attach SA to a process or core</font>
attach pid | exec core | debugserver <font color="red">attach SA to a process, core, or remote debug server</font>
buildreplayjars [all | boot | app] <font color="red">build jars for replay, boot.jar for bootclasses, app.jar for application classes</font>
class name <font color="red">find a Java class from debuggee and print oop</font>
classes <font color="red">print all loaded Java classes with Klass*</font>
@@ -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
@@ -33,6 +33,10 @@
public class CLHSDB {

public CLHSDB(JVMDebugger d) {
pid = -1;
execPath = null;
coreFilename = null;
debugServerName = null;
jvmDebugger = d;
}

@@ -42,10 +46,12 @@ public static void main(String[] args) {

public void run() {
// If jvmDebugger is already set, we have been given a JVMDebugger.
// Otherwise, if pidText != null we are supposed to attach to it.
// Finally, if execPath != null, it is the path of a jdk/bin/java
// Otherwise, if pid != -1 we are supposed to attach to it.
// If execPath != null, it is the path of a jdk/bin/java
// and coreFilename is the pathname of a core file we are
// supposed to attach to.
// Finally, if debugServerName != null, we are supposed to
// connect to remote debug server.

agent = new HotSpotAgent();

@@ -57,10 +63,12 @@ public void run() {

if (jvmDebugger != null) {
attachDebugger(jvmDebugger);
} else if (pidText != null) {
attachDebugger(pidText);
} else if (pid != -1) {
attachDebugger(pid);
} else if (execPath != null) {
attachDebugger(execPath, coreFilename);
} else if (debugServerName != null) {
connect(debugServerName);
}


@@ -71,21 +79,26 @@ public HotSpotAgent getAgent() {
public boolean isAttached() {
return attached;
}
public void attach(String pid) {
public void attach(int pid) {
attachDebugger(pid);
}
public void attach(String java, String core) {
attachDebugger(java, core);
}
public void attach(String debugServerName) {
connect(debugServerName);
}
public void detach() {
detachDebugger();
}
public void reattach() {
if (attached) {
detachDebugger();
}
if (pidText != null) {
attach(pidText);
if (pid != -1) {
attach(pid);
} else if (debugServerName != null) {
connect(debugServerName);
} else {
attach(execPath, coreFilename);
}
@@ -107,10 +120,10 @@ public void reattach() {
private JVMDebugger jvmDebugger;
private boolean attached;
// These had to be made data members because they are referenced in inner classes.
private String pidText;
private int pid;
private String execPath;
private String coreFilename;
private String debugServerName;

private void doUsage() {
System.out.println("Usage: java CLHSDB [[pid] | [path-to-java-executable [path-to-corefile]] | help ]");
@@ -122,6 +135,11 @@ private void doUsage() {
}

private CLHSDB(String[] args) {
pid = -1;
execPath = null;
coreFilename = null;
debugServerName = null;

switch (args.length) {
case (0):
break;
@@ -134,9 +152,7 @@ private CLHSDB(String[] args) {
// If all numbers, it is a PID to attach to
// Else, it is a pathname to a .../bin/java for a core file.
try {
int unused = Integer.parseInt(args[0]);
// If we get here, we have a PID and not a core file name
pidText = args[0];
pid = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
execPath = args[0];
coreFilename = "core";
@@ -163,17 +179,10 @@ private void attachDebugger(JVMDebugger d) {
/** NOTE we are in a different thread here than either the main
thread or the Swing/AWT event handler thread, so we must be very
careful when creating or removing widgets */
private void attachDebugger(String pidText) {
try {
this.pidText = pidText;
pid = Integer.parseInt(pidText);
}
catch (NumberFormatException e) {
System.err.print("Unable to parse process ID \"" + pidText + "\".\nPlease enter a number.");
}

private void attachDebugger(int pid) {
this.pid = pid;
try {
System.err.println("Attaching to process " + pid + ", please wait...");
System.out.println("Attaching to process " + pid + ", please wait...");

// FIXME: display exec'd debugger's output messages during this
// lengthy call
@@ -214,16 +223,17 @@ private void attachDebugger(final String executablePath, final String corePath)
/** NOTE we are in a different thread here than either the main
thread or the Swing/AWT event handler thread, so we must be very
careful when creating or removing widgets */
private void connect(final String remoteMachineName) {
private void connect(final String debugServerName) {
// Try to open this core file
try {
System.err.println("Connecting to debug server, please wait...");
agent.attach(remoteMachineName);
System.out.println("Connecting to debug server, please wait...");
agent.attach(debugServerName);
this.debugServerName = debugServerName;
attached = true;
}
catch (DebuggerException e) {
final String errMsg = formatMessage(e.getMessage(), 80);
System.err.println("Unable to connect to machine \"" + remoteMachineName + "\":\n\n" + errMsg);
System.err.println("Unable to connect to debug server \"" + debugServerName + "\":\n\n" + errMsg);
agent.detach();
e.printStackTrace();
return;
@@ -114,8 +114,9 @@
public abstract static class DebuggerInterface {
public abstract HotSpotAgent getAgent();
public abstract boolean isAttached();
public abstract void attach(String pid);
public abstract void attach(int pid);
public abstract void attach(String java, String core);
public abstract void attach(String debugServerName);
public abstract void detach();
public abstract void reattach();
}
@@ -382,12 +383,19 @@ public void doit(Tokens t) {
postAttach();
}
},
new Command("attach", "attach pid | exec core", true) {
new Command("attach", "attach pid | exec core | remote_server", true) {
public void doit(Tokens t) {
int tokens = t.countTokens();
if (tokens == 1) {
preAttach();
debugger.attach(t.nextToken());
String arg = t.nextToken();
try {
// Attempt to attach as a PID
debugger.attach(Integer.parseInt(arg));
} catch (NumberFormatException e) {
// Attempt to connect to remote debug server
debugger.attach(arg);
}
postAttach();
} else if (tokens == 2) {
preAttach();
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2020, 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
@@ -78,10 +78,10 @@ public static void main(String[] args) {
private JInternalFrame consoleFrame;
private WorkerThread workerThread;
// These had to be made data members because they are referenced in inner classes.
private String pidText;
private int pid;
private String execPath;
private String coreFilename;
private String debugServerName;

private void doUsage() {
System.out.println("Usage: java HSDB [[pid] | [path-to-java-executable [path-to-corefile]] | help ]");
@@ -94,10 +94,19 @@ private void doUsage() {
}

public HSDB(JVMDebugger d) {
pid = -1;
execPath = null;
coreFilename = null;
debugServerName = null;
jvmDebugger = d;
}

private HSDB(String[] args) {
pid = -1;
execPath = null;
coreFilename = null;
debugServerName = null;

switch (args.length) {
case (0):
break;
@@ -109,9 +118,7 @@ private HSDB(String[] args) {
// If all numbers, it is a PID to attach to
// Else, it is a pathname to a .../bin/java for a core file.
try {
int unused = Integer.parseInt(args[0]);
// If we get here, we have a PID and not a core file name
pidText = args[0];
pid = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
execPath = args[0];
coreFilename = "core";
@@ -422,17 +429,21 @@ public void run() {
});

// If jvmDebugger is already set, we have been given a JVMDebugger.
// Otherwise, if pidText != null we are supposed to attach to it.
// Finally, if execPath != null, it is the path of a jdk/bin/java
// Otherwise, if pid != -1 we are supposed to attach to it.
// If execPath != null, it is the path of a jdk/bin/java
// and coreFilename is the pathname of a core file we are
// supposed to attach to.
// Finally, if debugServerName != null, we are supposed to
// connect to remote debug server.

if (jvmDebugger != null) {
attach(jvmDebugger);
} else if (pidText != null) {
attach(pidText);
} else if (pid != -1) {
attach(pid);
} else if (execPath != null) {
attach(execPath, coreFilename);
} else if (debugServerName != null) {
connect(debugServerName);
}
}

@@ -456,7 +467,7 @@ public void actionPerformed(ActionEvent e) {
desktop.remove(attachDialog);
workerThread.invokeLater(new Runnable() {
public void run() {
attach(pidTextField.getText());
attach(Integer.parseInt(pidTextField.getText()));
}
});
}
@@ -1172,24 +1183,8 @@ private void attach(JVMDebugger d) {
/** NOTE we are in a different thread here than either the main
thread or the Swing/AWT event handler thread, so we must be very
careful when creating or removing widgets */
private void attach(String pidText) {
try {
this.pidText = pidText;
pid = Integer.parseInt(pidText);
}
catch (NumberFormatException e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
setMenuItemsEnabled(attachMenuItems, true);
JOptionPane.showInternalMessageDialog(desktop,
"Unable to parse process ID \"" + HSDB.this.pidText + "\".\nPlease enter a number.",
"Parse error",
JOptionPane.WARNING_MESSAGE);
}
});
return;
}

private void attach(int pid) {
this.pid = pid;
// Try to attach to this process
Runnable remover = new Runnable() {
public void run() {
@@ -1293,7 +1288,7 @@ public void run() {
/** NOTE we are in a different thread here than either the main
thread or the Swing/AWT event handler thread, so we must be very
careful when creating or removing widgets */
private void connect(final String remoteMachineName) {
private void connect(final String debugServerName) {
// Try to open this core file
Runnable remover = new Runnable() {
public void run() {
@@ -1313,7 +1308,7 @@ public void run() {
}
});

agent.attach(remoteMachineName);
agent.attach(debugServerName);
if (agent.getDebugger().hasConsole()) {
showDbgConsoleMenuItem.setEnabled(true);
}
@@ -1327,7 +1322,7 @@ public void run() {
public void run() {
setMenuItemsEnabled(attachMenuItems, true);
JOptionPane.showInternalMessageDialog(desktop,
"Unable to connect to machine \"" + remoteMachineName + "\":\n\n" + errMsg,
"Unable to connect to machine \"" + debugServerName + "\":\n\n" + errMsg,
"Unable to Connect",
JOptionPane.WARNING_MESSAGE);
}
@@ -1499,20 +1494,25 @@ public HotSpotAgent getAgent() {
public boolean isAttached() {
return attached;
}
public void attach(String pid) {
public void attach(int pid) {
HSDB.this.attach(pid);
}
public void attach(String java, String core) {
}
public void attach(String debugServerName) {
HSDB.this.connect(debugServerName);
}
public void detach() {
detachDebugger();
}
public void reattach() {
if (attached) {
detachDebugger();
}
if (pidText != null) {
attach(pidText);
if (pid != -1) {
attach(pid);
} else if (debugServerName != null) {
connect(debugServerName);
} else {
attach(execPath, coreFilename);
}
Loading

1 comment on commit 70342e8

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on 70342e8 Mar 9, 2021

Please sign in to comment.