Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdb/Debuggee.java
41161 views
/*1* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package nsk.share.jdb;2425import nsk.share.*;26import nsk.share.jpda.*;27import nsk.share.jdi.ArgumentHandler;2829import java.io.*;3031/**32* Interface defining methods to control mirror of debuggee (i.e. debugged VM).33*/34public interface Debuggee {3536/** Default prefix for log messages. */37public static final String LOG_PREFIX = "debuggee> ";38public static final String DEBUGEE_STDOUT_LOG_PREFIX = "debuggee.stdout> ";39public static final String DEBUGEE_STDERR_LOG_PREFIX = "debuggee.stderr> ";4041/**42* Launch debuggee.43*44* @throws IOException45*/46public void launch (String[] args) throws IOException;4748/** Return exit status. */49public int getStatus ();5051/** Check whether the process has been terminated. */52public boolean terminated();5354/** Kill the debuggee VM. */55public void killDebuggee ();5657/** Wait until the debuggee VM shutdown or crash. */58public int waitForDebuggee () throws InterruptedException;5960/** Get a pipe to write to the debuggee's stdin stream. */61public OutputStream getInPipe ();6263/** Get a pipe to read the debuggee's stdout stream. */64public InputStream getOutPipe ();6566/** Get a pipe to read the debuggee's stderr stream. */67public InputStream getErrPipe ();6869/** Redirect stdout stream to <code>Log</code> */70public void redirectStdout(Log log, String prefix);7172/** Redirect stderr stream to <code>Log</code> */73public void redirectStderr(Log log, String prefix);74}7576/**77* Mirror of locally launched debuggee.78*/79final class LocalLaunchedDebuggee extends LocalProcess implements Debuggee {8081private IORedirector stdoutRedirector = null;82private IORedirector stderrRedirector = null;83private IORedirector stdinRedirector = null;8485/** Messages prefix. */86protected String prefix = LOG_PREFIX;8788/** Launcher that creates this debuggee. */89private Launcher launcher = null;9091/** Enwrap the existing <code>VM</code> mirror. */92LocalLaunchedDebuggee (Launcher launcher) {93super();94this.launcher = launcher;95}9697/**98* Launch debuggee on local host.99*/100public void launch(String[] args) throws IOException {101launcher.display("Starting local debuggee.");102103super.launch(args);104redirectStdout(launcher.getLog(), DEBUGEE_STDOUT_LOG_PREFIX );105redirectStderr(launcher.getLog(), DEBUGEE_STDERR_LOG_PREFIX);106}107108/** Kill the debuggee VM. */109public void killDebuggee () {110super.kill();111if (stdinRedirector != null) {112stdinRedirector.cancel();113}114if (stdoutRedirector != null) {115stdoutRedirector.cancel();116}117if (stderrRedirector != null) {118stderrRedirector.cancel();119}120}121122123/**124* Wait until the debuggee VM shutdown or crash,125* and let finish its stdout, stderr, and stdin126* redirectors (if any).127*128* @return Debuggee process exit code.129*/130public int waitForDebuggee () throws InterruptedException {131int timeout = launcher.getJdbArgumentHandler().getWaitTime() * 60 * 1000;132int exitCode;133try {134exitCode = super.waitFor();135if (stdinRedirector != null) {136if (stdinRedirector.isAlive()) {137stdinRedirector.join(timeout);138if (stdinRedirector.isAlive()) {139launcher.complain("Timeout for waiting STDIN redirector exceeded");140stdinRedirector.interrupt();141}142}143stdinRedirector = null;144};145if (stdoutRedirector != null) {146if (stdoutRedirector.isAlive()) {147stdoutRedirector.join(timeout);148if (stdoutRedirector.isAlive()) {149launcher.complain("Timeout for waiting STDOUT redirector exceeded");150stdoutRedirector.interrupt();151}152}153stdoutRedirector = null;154};155if (stderrRedirector != null) {156if (stderrRedirector.isAlive()) {157stderrRedirector.join(timeout);158if (stderrRedirector.isAlive()) {159launcher.complain("Timeout for waiting STDERR redirector exceeded");160stderrRedirector.interrupt();161}162}163stderrRedirector = null;164};165} catch (InterruptedException ie) {166ie.printStackTrace(launcher.getLog().getOutStream());167throw new Failure("Caught exception while waiting for LocalProcess termination: \n\t" + ie);168}169return exitCode;170}171172/**173* Get a pipe to write to the debuggee's stdin stream,174* or throw TestBug exception is redirected.175*/176public OutputStream getInPipe () {177if (stdinRedirector != null)178throw new TestBug("debuggee's stdin is redirected");179return getStdin();180}181182/**183* Get a pipe to read the debuggee's stdout stream,184* or throw TestBug exception is redirected.185*/186public InputStream getOutPipe () {187if (stdoutRedirector != null)188throw new TestBug("debuggee's stdout is redirected");189return getStdout();190}191192/**193* Get a pipe to read the debuggee's stderr stream,194* or throw TestBug exception is redirected.195*/196public InputStream getErrPipe () {197if (stderrRedirector != null)198throw new TestBug("debuggee's stderr is redirected");199return getStderr();200}201202// --------------------------------------------------- //203204/**205* Start thread redirecting the debuggee's stdout to the206* given <code>Log</code>. If the debuggee's stdout207* was already redirected, the TestBug exception is thrown.208*209* @throws nsk.share.TestBug210*/211public void redirectStdout(Log log, String prefix) {212if (stdoutRedirector != null) {213throw new TestBug("Debuggee's stdout already redirected.");214}215stdoutRedirector = new IORedirector(new BufferedReader(new InputStreamReader(getStdout())), log, prefix);216stdoutRedirector.start();217}218219220/**221* Start thread redirecting the debuggee's stderr to the222* given <code>Log</code>. If the debuggee's stderr223* was already redirected, the TestBug exception is thrown.224*225* @throws nsk.share.TestBug226*/227public void redirectStderr(Log log, String prefix) {228if (stderrRedirector != null) {229throw new TestBug("Debuggee's stdout already redirected.");230}231stderrRedirector = new IORedirector(new BufferedReader(new InputStreamReader(getStderr())), log, prefix);232stderrRedirector.start();233}234}235236237/**238* Mirror of remotely launched debuggee.239*/240final class RemoteLaunchedDebuggee implements Debuggee {241242/** Launcher that creates this debuggee. */243private Launcher launcher = null;244245/** Enwrap the existing <code>VM</code> mirror. */246RemoteLaunchedDebuggee (Launcher launcher) {247super();248this.launcher = launcher;249}250251/**252* Launch debugee on remote host via <code>Launcher</code> object.253*/254public void launch(String[] args) throws IOException {255String cmdLine = ArgumentHandler.joinArguments(args, "\"");256launcher.display("Starting remote java process:\n" + cmdLine);257launcher.launchRemoteProcess(args);258}259260/** Return exit status of the debuggee VM. */261public int getStatus () {262return launcher.getRemoteProcessStatus();263}264265/** Check whether the debuggee VM has been terminated. */266public boolean terminated () {267return launcher.isRemoteProcessTerminated();268}269270// ---------------------------------------------- //271272/** Kill the debuggee VM. */273public void killDebuggee () {274launcher.killRemoteProcess();275}276277/** Wait until the debuggee VM shutdown or crash. */278public int waitForDebuggee () {279return launcher.waitForRemoteProcess();280}281282/** Get a pipe to write to the debuggee's stdin stream. */283public OutputStream getInPipe () {284return null;285}286287/** Get a pipe to read the debuggee's stdout stream. */288public InputStream getOutPipe () {289return null;290}291292/** Get a pipe to read the debuggee's stderr stream. */293public InputStream getErrPipe () {294return null;295}296297public void redirectStdout(Log log, String prefix) {298}299300public void redirectStderr(Log log, String prefix) {301}302303}304305306