8263342: Add --connect option to jhsdb hsdb/clhsdb

Reviewed-by: cjplummer, sspitsyn
This commit is contained in:
Yasumasa Suenaga 2021-03-23 06:27:20 +00:00
parent 6b4c654186
commit b2a52ea516
5 changed files with 126 additions and 16 deletions
src/jdk.hotspot.agent/share
test/hotspot/jtreg/serviceability/sa/sadebugd

@ -149,13 +149,12 @@ public class CLHSDB {
doUsage();
return;
}
// If all numbers, it is a PID to attach to
// Else, it is a pathname to a .../bin/java for a core file.
try {
// Attempt to attach as a PID
pid = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
execPath = args[0];
coreFilename = "core";
// Attempt to connect to remote debug server
debugServerName = args[0];
}
break;

@ -115,13 +115,12 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
if (args[0].equals("help") || args[0].equals("-help")) {
doUsage();
}
// If all numbers, it is a PID to attach to
// Else, it is a pathname to a .../bin/java for a core file.
try {
// Attempt to attach as a PID
pid = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
execPath = args[0];
coreFilename = "core";
// Attempt to connect to remote debug server
debugServerName = args[0];
}
break;

@ -161,7 +161,7 @@ public class SALauncher {
return debugdHelp();
case "hsdb":
case "clhsdb":
return commonHelp(toolName);
return commonHelpWithConnect(toolName);
default:
return launcherHelp();
}
@ -276,7 +276,8 @@ public class SALauncher {
private static void runCLHSDB(String[] oldArgs) {
Map<String, String> longOptsMap = Map.of("exe=", "exe",
"core=", "core",
"pid=", "pid");
"pid=", "pid",
"connect=", "connect");
Map<String, String> newArgMap = parseOptions(oldArgs, longOptsMap);
CLHSDB.main(buildAttachArgs(newArgMap, true));
}
@ -284,7 +285,8 @@ public class SALauncher {
private static void runHSDB(String[] oldArgs) {
Map<String, String> longOptsMap = Map.of("exe=", "exe",
"core=", "core",
"pid=", "pid");
"pid=", "pid",
"connect=", "connect");
Map<String, String> newArgMap = parseOptions(oldArgs, longOptsMap);
HSDB.main(buildAttachArgs(newArgMap, true));
}

@ -1,4 +1,4 @@
.\" Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
.\" Copyright (c) 2019, 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
@ -31,12 +31,12 @@ analyze the content of a core dump from a crashed Java Virtual Machine
.SH SYNOPSIS
.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]\-\-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\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]\-\-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\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]

@ -0,0 +1,110 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021 NTT DATA.
* 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.io.PrintStream;
import jdk.test.lib.JDKToolLauncher;
import jdk.test.lib.apps.LingeredApp;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.SA.SATestUtils;
import jtreg.SkippedException;
/**
* @test
* @bug 8263342
* @requires vm.hasSA
* @requires os.family != "windows"
* @library /test/lib
* @run main/othervm ClhsdbTestConnectArgument
*/
public class ClhsdbTestConnectArgument {
public static void main(String[] args) throws Exception {
SATestUtils.skipIfCannotAttach(); // throws SkippedException if attach not expected to work.
if (SATestUtils.needsPrivileges()) {
// This tests has issues if you try adding privileges on OSX. The debugd process cannot
// be killed if you do this (because it is a root process and the test is not), so the destroy()
// call fails to do anything, and then waitFor() will time out. If you try to manually kill it with
// a "sudo kill" command, that seems to work, but then leaves the LingeredApp it was
// attached to in a stuck state for some unknown reason, causing the stopApp() call
// to timeout. For that reason we don't run this test when privileges are needed. Note
// it does appear to run fine as root, so we still allow it to run on OSX when privileges
// are not required.
throw new SkippedException("Cannot run this test on OSX if adding privileges is required.");
}
System.out.println("Starting ClhsdbTestConnectArgument test");
LingeredApp theApp = null;
DebugdUtils debugd = null;
try {
theApp = LingeredApp.startApp();
System.out.println("Started LingeredApp with pid " + theApp.getPid());
debugd = new DebugdUtils(null);
debugd.attach(theApp.getPid());
JDKToolLauncher jhsdbLauncher = JDKToolLauncher.createUsingTestJDK("jhsdb");
jhsdbLauncher.addToolArg("clhsdb");
jhsdbLauncher.addToolArg("--connect");
jhsdbLauncher.addToolArg("localhost");
Process jhsdb = (SATestUtils.createProcessBuilder(jhsdbLauncher)).start();
OutputAnalyzer out = new OutputAnalyzer(jhsdb);
try (PrintStream console = new PrintStream(jhsdb.getOutputStream(), true)) {
console.println("echo true");
console.println("verbose true");
console.println("class java.lang.Object");
console.println("quit");
}
jhsdb.waitFor();
System.out.println(out.getStdout());
System.err.println(out.getStderr());
out.stderrShouldBeEmptyIgnoreDeprecatedWarnings();
out.shouldMatch("^java/lang/Object @0x[0-9a-f]+$"); // for "class java.lang.Object"
out.shouldHaveExitValue(0);
// This will detect most SA failures, including during the attach.
out.shouldNotMatch("^sun.jvm.hotspot.debugger.DebuggerException:.*$");
// This will detect unexpected exceptions, like NPEs and asserts, that are caught
// by sun.jvm.hotspot.CommandProcessor.
out.shouldNotMatch("^Error: .*$");
} catch (SkippedException se) {
throw se;
} catch (Exception ex) {
throw new RuntimeException("Test ERROR " + ex, ex);
} finally {
if (debugd != null) {
debugd.detach();
}
LingeredApp.stopApp(theApp);
}
System.out.println("Test PASSED");
}
}