diff options
Diffstat (limited to 'debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/MISession.java')
-rw-r--r-- | debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/MISession.java | 896 |
1 files changed, 0 insertions, 896 deletions
diff --git a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/MISession.java b/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/MISession.java deleted file mode 100644 index 2962e2c49b9..00000000000 --- a/debug/org.eclipse.cdt.debug.mi.core/mi/org/eclipse/cdt/debug/mi/core/MISession.java +++ /dev/null @@ -1,896 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2012 QNX Software Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * QNX Software Systems - Initial API and implementation - * Hewlett-Packard Development Company - fix for bug 109733 - *******************************************************************************/ -package org.eclipse.cdt.debug.mi.core; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.util.Observable; - -import org.eclipse.cdt.debug.mi.core.command.Command; -import org.eclipse.cdt.debug.mi.core.command.CommandFactory; -import org.eclipse.cdt.debug.mi.core.command.MIExecInterrupt; -import org.eclipse.cdt.debug.mi.core.command.MIGDBExit; -import org.eclipse.cdt.debug.mi.core.command.MIGDBSet; -import org.eclipse.cdt.debug.mi.core.command.MIGDBShowExitCode; -import org.eclipse.cdt.debug.mi.core.command.MIGDBShowPrompt; -import org.eclipse.cdt.debug.mi.core.command.MIInterpreterExecConsole; -import org.eclipse.cdt.debug.mi.core.command.MIVersion; -import org.eclipse.cdt.debug.mi.core.event.MIEvent; -import org.eclipse.cdt.debug.mi.core.event.MIGDBExitEvent; -import org.eclipse.cdt.debug.mi.core.output.MIGDBShowInfo; -import org.eclipse.cdt.debug.mi.core.output.MIOutput; -import org.eclipse.cdt.debug.mi.core.output.MIParser; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; - -/** - * Represents a GDB/MI session. - * Note that on GNU/Linux the target stream is not - * preceded by the token '@' until this is fix, on GNU/Linux - * there a good change to confuse the parser. - */ -public class MISession extends Observable { - - /** - * Normal program debuging. - */ - public final static int PROGRAM = 0; - /** - * Attach to a running process debuging. - */ - public final static int ATTACH = 1; - /** - * PostMortem analysis. - */ - public final static int CORE = 2; - - /** - * Timeout value for a very long time. - */ - public final static int FOREVER = Integer.MAX_VALUE; - - boolean terminated; - boolean useInterpreterExecConsole; - boolean verboseMode = false; - boolean breakpointsWithFullName = false; - - // hold the type of the session(post-mortem, attach etc ..) - int sessionType; - - Process sessionProcess; - MIProcess gdbProcess; - InputStream inChannel; - InputStream inErrChannel; - OutputStream outChannel; - - TxThread txThread; - RxThread rxThread; - ErrorThread errorThread; - EventThread eventThread; - - CommandQueue txQueue; - CommandQueue rxQueue; - Queue eventQueue; - - PipedInputStream miInConsolePipe; - PipedOutputStream miOutConsolePipe; - PipedInputStream miInLogPipe; - PipedOutputStream miOutLogPipe; - - - CommandFactory factory; - - MIParser parser; - - long cmdTimeout; - - MIInferior inferior; - - /** - * @param process - * @param tty - * @param type - * @param commandTimeout - * @param launchTimeout - * @param miVersion - * @param monitor - * @throws MIException - * @deprecated - */ - @Deprecated - public MISession(MIProcess process, IMITTY tty, int type, int commandTimeout, int launchTimeout, String miVersion, IProgressMonitor monitor) throws MIException { - this(process, tty, type, new CommandFactory(miVersion), commandTimeout, launchTimeout, monitor); - } - - - /** - * Create the gdb session. Assume MIVersion 1 - * - * @deprecated use the other constructors with the MIVersion - * @param Process gdb Process. - * @param pty Terminal to use for the inferior. - * @param timeout time in milliseconds to wait for command response. - * @param type the type of debugin session. - * @deprecated - */ - @Deprecated - public MISession(MIProcess process, IMITTY tty, int commandTimeout, int type, int launchTimeout) throws MIException { - this(process, tty, type, commandTimeout, launchTimeout, MIVersion.MI1, new NullProgressMonitor()); - if (useExecConsole()) { - // if exec console is present, assume MI2 supported - setCommandFactory(new CommandFactory(MIVersion.MI2)); - } - } - - /** - * Create the gdb session. - * - * @param type the type of debugging session. - * @param commandFactory the MI command factory - * @param Process gdb Process. - * @param pty Terminal to use for the inferior. - * @param timeout time in milliseconds to wait for command response. - * @deprecated - */ - @Deprecated - public MISession(MIProcess process, IMITTY tty, int type, CommandFactory commandFactory, int commandTimeout, int launchTimeout, IProgressMonitor monitor) throws MIException { - gdbProcess = process; - inChannel = process.getInputStream(); - inErrChannel = process.getErrorStream(); - outChannel = process.getOutputStream(); - - factory = commandFactory; - cmdTimeout = commandTimeout; - - sessionType = type; - - parser = new MIParser(); - - inferior = new MIInferior(this, tty); - - txQueue = new CommandQueue(); - rxQueue = new CommandQueue(); - eventQueue = new Queue(); - - txThread = new TxThread(this); - rxThread = new RxThread(this); - errorThread = new ErrorThread(this); - eventThread = new EventThread(this); - - // initialize/setup - setup(launchTimeout, new NullProgressMonitor()); - } - - /** - * Constructor for MISession. Creates MI wrapper for the given gdb process. - * - * @param type the type of debugging session: <code>PROGRAM</code>, <code>ATTACH</code> or <code>CORE</code> - * @param commandFactory the set of gdb/mi commands supported by given gdb - * @param Process a gdb process - * @param pty terminal to use for the inferior. - * @param timeout time in milliseconds to wait for command response. - * - * @since 3.1 - */ - public MISession(MIProcess process, IMITTY tty, int type, CommandFactory commandFactory, int commandTimeout) throws MIException { - gdbProcess = process; - inChannel = process.getInputStream(); - inErrChannel = process.getErrorStream(); - outChannel = process.getOutputStream(); - - factory = commandFactory; - cmdTimeout = commandTimeout; - - sessionType = type; - - parser = new MIParser(); - - inferior = new MIInferior(this, tty); - - txQueue = new CommandQueue(); - rxQueue = new CommandQueue(); - eventQueue = new Queue(); - - txThread = new TxThread(this); - rxThread = new RxThread(this); - errorThread = new ErrorThread(this); - eventThread = new EventThread(this); - - setup(); - - txThread.start(); - rxThread.start(); - errorThread.start(); - eventThread.start(); - } - - /** - * No need to pass a progress monitor and a launch timeout. - * @since 3.1 - */ - protected void setup() throws MIException { - // The Process may have terminated earlier because - // of bad arguments etc .. check this here and bail out. - try { - gdbProcess.exitValue(); - InputStream err = gdbProcess.getErrorStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(err)); - String line = null; - try { - line = reader.readLine(); - reader.close(); - } catch (Exception e) { - // the reader may throw a NPE. - } - if (line == null) { - line = MIPlugin.getResourceString("src.MISession.Process_Terminated"); //$NON-NLS-1$ - } - throw new MIException(line); - } catch (IllegalThreadStateException e) { - // Ok, it means the process is alive. - } - } - - /** - * Initializes the gdb session. - * @since 3.1 - */ - public void start() throws MIException { - try { - initialize(); - } catch (MIException exc) { - // Kill the Transmition thread. - if (txThread.isAlive()) { - txThread.interrupt(); - } - // Kill the Receiving Thread. - if (rxThread.isAlive()) { - rxThread.interrupt(); - } - // Kill the Error reading Thread. - if (errorThread.isAlive()) { - errorThread.interrupt(); - } - // Kill the event Thread. - if (eventThread.isAlive()) { - eventThread.interrupt(); - } - // rethrow up the exception. - throw exc; - } - } - - /** - * @deprecated use <code>setup()</code> without parameters - */ - @Deprecated - protected void setup(int launchTimeout, IProgressMonitor monitor) throws MIException { - // The Process may have terminated earlier because - // of bad arguments etc .. check this here and bail out. - try { - gdbProcess.exitValue(); - InputStream err = gdbProcess.getErrorStream(); - BufferedReader reader = new BufferedReader(new InputStreamReader(err)); - String line = null; - try { - line = reader.readLine(); - reader.close(); - } catch (Exception e) { - // the reader may throw a NPE. - } - if (line == null) { - line = MIPlugin.getResourceString("src.MISession.Process_Terminated"); //$NON-NLS-1$ - } - throw new MIException(line); - } catch (IllegalThreadStateException e) { - // Ok, it means the process is alive. - } - - if (monitor.isCanceled()) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Process_Terminated")); //$NON-NLS-1$ - } - - txThread.start(); - rxThread.start(); - errorThread.start(); - eventThread.start(); - - try { - if (monitor.isCanceled()) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Process_Terminated")); //$NON-NLS-1$ - } - - initialize(launchTimeout, monitor); - } catch (MIException exc) { - // Kill the Transmition thread. - if (txThread.isAlive()) { - txThread.interrupt(); - } - // Kill the Receiving Thread. - if (rxThread.isAlive()) { - rxThread.interrupt(); - } - // Kill the Error Thread. - if (errorThread.isAlive()) { - errorThread.interrupt(); - } - // Kill the event Thread. - if (eventThread.isAlive()) { - eventThread.interrupt(); - } - // rethrow up the exception. - throw exc; - } - } - - /** - * Turns off the "confirm" option of gdb. - * Sets witdth and height of gdb session to 0. - * @since 3.1 - */ - protected void initialize() throws MIException { - // Disable a certain number of irritations from gdb. - // Like confirmation and screen size. - MIGDBSet confirm = getCommandFactory().createMIGDBSet(new String[]{"confirm", "off"}); //$NON-NLS-1$ //$NON-NLS-2$ - postCommand(confirm); - confirm.getMIInfo(); - - MIGDBSet width = getCommandFactory().createMIGDBSet(new String[]{"width", "0"}); //$NON-NLS-1$ //$NON-NLS-2$ - postCommand(width); - width.getMIInfo(); - - MIGDBSet height = getCommandFactory().createMIGDBSet(new String[]{"height", "0"}); //$NON-NLS-1$ //$NON-NLS-2$ - postCommand(height); - height.getMIInfo(); - - useInterpreterExecConsole = canUseInterpreterExecConsole(); - - String prompt = getCLIPrompt(); - if (prompt != null) { - getMIParser().cliPrompt = prompt; - } - } - - /** - * @deprecated use <code>initialize()</code> without parameters - */ - @Deprecated - protected void initialize(int launchTimeout, IProgressMonitor monitor) throws MIException { - // Disable a certain number of irritations from gdb. - // Like confirmation and screen size. - MIGDBSet confirm = getCommandFactory().createMIGDBSet(new String[]{"confirm", "off"}); //$NON-NLS-1$ //$NON-NLS-2$ - postCommand(confirm, launchTimeout); - confirm.getMIInfo(); - if (monitor.isCanceled()) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Process_Terminated")); //$NON-NLS-1$ - } - - MIGDBSet width = getCommandFactory().createMIGDBSet(new String[]{"width", "0"}); //$NON-NLS-1$ //$NON-NLS-2$ - postCommand(width, launchTimeout); - width.getMIInfo(); - if (monitor.isCanceled()) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Process_Terminated")); //$NON-NLS-1$ - } - - MIGDBSet height = getCommandFactory().createMIGDBSet(new String[]{"height", "0"}); //$NON-NLS-1$ //$NON-NLS-2$ - postCommand(height, launchTimeout); - height.getMIInfo(); - if (monitor.isCanceled()) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Process_Terminated")); //$NON-NLS-1$ - } - - useInterpreterExecConsole = canUseInterpreterExecConsole(); - if (monitor.isCanceled()) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Process_Terminated")); //$NON-NLS-1$ - } - - String prompt = getCLIPrompt(); - if (monitor.isCanceled()) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Process_Terminated")); //$NON-NLS-1$ - } - if (prompt != null) { - getMIParser().cliPrompt = prompt; - } - } - - protected boolean canUseInterpreterExecConsole() { - // Try to discover if "-interpreter-exec" is supported. - try { - MIInterpreterExecConsole echo = getCommandFactory().createMIInterpreterExecConsole("echo"); //$NON-NLS-1$ - postCommand(echo); - echo.getMIInfo(); - return true; - } catch (MIException e) { - // - } - return false; - } - - protected String getCLIPrompt() throws MIException { - // Get GDB's prompt - MIGDBShowPrompt prompt = getCommandFactory().createMIGDBShowPrompt(); - postCommand(prompt); - MIGDBShowInfo infoPrompt = prompt.getMIGDBShowInfo(); - String value = infoPrompt.getValue(); - if (value != null && value.length() > 0) { - return value.trim(); - } - return null; - } - - /** - * get MI Console Stream. - * The parser will make available the MI console stream output. - */ - public InputStream getMIConsoleStream() { - if (miInConsolePipe == null) { - try { - miOutConsolePipe = new PipedOutputStream(); - miInConsolePipe = new PipedInputStream(miOutConsolePipe); - } catch (IOException e) { - } - } - return miInConsolePipe; - } - - /** - * get MI Console Stream. - * The parser will make available the MI console stream output. - */ - public InputStream getMILogStream() { - if (miInLogPipe == null) { - try { - miOutLogPipe = new PipedOutputStream(); - miInLogPipe = new PipedInputStream(miOutLogPipe); - } catch (IOException e) { - } - } - return miInLogPipe; - } - - /** - * For example the CDI/MI bridge uses the command - * factory to create MI commands this allow overloading. - */ - public CommandFactory getCommandFactory() { - return factory; - } - - /** - * Set a new factory to use for command. - */ - public void setCommandFactory(CommandFactory f) { - factory = f; - } - - /** - * Return the MI parser. - */ - public MIParser getMIParser() { - return parser; - } - - /** - * Reset the MI parser. - */ - public void setMIParser(MIParser p) { - parser = p; - } - - /** - * Set the type of session this is. - * Certain action will base on that, for example - * the inferior will not try to kill/destroy a - * attach session disconnected. - */ - public int getSessionType() { - return sessionType; - } - - public void setSessionType(int type) { - sessionType = type; - } - - public boolean useExecConsole() { - return useInterpreterExecConsole; - } - - public boolean inPrimaryPrompt() { - return rxThread.inPrimaryPrompt(); - } - - public boolean inSecondaryPrompt() { - return rxThread.inSecondaryPrompt(); - } - /** - * The debug session is a program being debug. - */ - public boolean isProgramSession() { - return sessionType == PROGRAM; - } - - /** - * The debug session is a program being attach to. - */ - public boolean isAttachSession() { - return sessionType == ATTACH; - } - - /** - * The debug session is a core being analysed. - */ - public boolean isCoreSession() { - return sessionType == CORE; - } - - /** - * Reset the default Command Timeout. - */ - public void setCommandTimeout(long timeout) { - cmdTimeout = timeout; - } - - /** - * Return the default Command Timeout, default 10 secs. - */ - public long getCommandTimeout() { - return cmdTimeout; - } - - /** - * equivalent to: - * postCommand(cmd, cmdTimeout) - */ - public void postCommand(Command cmd) throws MIException { - postCommand(cmd, cmdTimeout); - } - - /** - * Sends a command to gdb, and wait(timeout) for a response. - * if timeout < 0 the wait will be skipped. - * - */ - public void postCommand(Command cmd, long timeout) throws MIException { - - // Test if we are in a sane state. - if (!txThread.isAlive() || !rxThread.isAlive()) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Thread_Terminated")); //$NON-NLS-1$ - } - - // Test if we are in the right state? - if (inferior.isRunning()) { - // REMINDER: if we support -exec-interrupt - // Let it throught: - if (!(cmd instanceof MIExecInterrupt)) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Target_not_suspended")); //$NON-NLS-1$ - } - } - - if (inferior.isTerminated()) { - // the only thing that can call postCommand when the inferior is in a TERMINATED - // state is MIGDBShowExitCode, for when MIInferior is computing error code. - if (!(cmd instanceof MIGDBShowExitCode)) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Inferior_Terminated")); //$NON-NLS-1$ - } - } - - if (isTerminated()) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Session_terminated")); //$NON-NLS-1$ - } - postCommand0(cmd, timeout); - } - - /** - * if timeout < 0 the operation will not try to way for - * answer from gdb. - * - * @param cmd - * @param timeout - * @throws MIException - */ - public synchronized void postCommand0(Command cmd, long timeout) throws MIException { - // TRACING: print the command; - if (MIPlugin.DEBUG) { - MIPlugin.getDefault().debugLog(cmd.toString()); - } - - if (isVerboseModeEnabled()) - writeToConsole(cmd.toString()); - - txQueue.addCommand(cmd); - - // do not wait around the answer. - if (timeout < 0) { - return; - } - // Wait for the response or timedout - synchronized (cmd) { - // RxThread will set the MIOutput on the cmd - // when the response arrive. - while (cmd.getMIOutput() == null) { - try { - cmd.wait(timeout); - if (cmd.getMIOutput() == null) { - throw new MIException(MIPlugin.getResourceString("src.MISession.Target_not_responding")); //$NON-NLS-1$ - } - } catch (InterruptedException e) { - } - } - } - } - - /** - * Return the inferior "Process". - */ - public MIInferior getMIInferior() { - return inferior; - } - - /** - * Set the inferior "Process". - */ - public void setMIInferior(MIInferior inferior) { - this.inferior = inferior; - } - - /** - * Return the "gdb" Process. - */ - public MIProcess getGDBProcess() { - return gdbProcess; - } - - /** - * Return a "fake" Process that will - * encapsulate the call input/output of gdb. - */ - public Process getSessionProcess() { - if (sessionProcess == null) { - sessionProcess = new SessionProcess(this); - } - return sessionProcess; - } - - /** - * Check if the gdb session is terminated. - */ - public boolean isTerminated() { - return terminated; - } - - /** - * Terminate the MISession. - */ - public void terminate() { - - // Sanity check. - if (isTerminated()) { - return; - } - - terminated = true; - - // Destroy any MI Inferior(Process) and streams. - inferior.destroy(); - - // {in,out}Channel is use as predicate/condition - // in the {RX,TX,Event}Thread to detect termination - // and bail out. So they are set to null. - InputStream inGDB = inChannel; - inChannel = null; - OutputStream outGDB = outChannel; - outChannel = null; - - // Although we will close the pipe(). It is cleaner - // to give a chance to gdb to cleanup. - // send the exit(-gdb-exit). But we only wait a maximum of 2 sec. - MIGDBExit exit = getCommandFactory().createMIGDBExit(); - try { - postCommand0(exit, 2000); - } catch (MIException e) { - //ignore any exception at this point. - } - - // Make sure gdb is killed. - // FIX: the destroy() must be call before closing gdb streams - // on windows if the order is not follow the close() will hang. - if (gdbProcess != null) { - gdbProcess.destroy(); - } - - // Close the input GDB prompt - try { - if (inGDB != null) - inGDB.close(); - } catch (IOException e) { - } - - // Close the output GDB prompt - try { - if (outGDB != null) - outGDB.close(); - } catch (IOException e) { - } - - // Destroy the MI console stream. - try { - miInConsolePipe = null; - if (miOutConsolePipe != null) { - miOutConsolePipe.close(); - } - } catch (IOException e) { - } - - // Destroy the MI log stream. - try { - miInLogPipe = null; - if (miOutLogPipe != null) { - miOutLogPipe.close(); - } - } catch (IOException e) { - } - - // Kill the Transmition thread. - try { - if (txThread.isAlive()) { - txThread.interrupt(); - txThread.join(cmdTimeout); - } - } catch (InterruptedException e) { - } - - // Kill the Receiving Thread. - try { - if (rxThread.isAlive()) { - rxThread.interrupt(); - rxThread.join(cmdTimeout); - } - } catch (InterruptedException e) { - } - // Kill the Error Thread. - try { - if (errorThread.isAlive()) { - errorThread.interrupt(); - errorThread.join(cmdTimeout); - } - } catch (InterruptedException e) { - } - // Kill the event Thread ... if it is not us. - if (!eventThread.equals(Thread.currentThread())) { - // Kill the event Thread. - try { - if (eventThread.isAlive()) { - eventThread.interrupt(); - eventThread.join(cmdTimeout); - } - } catch (InterruptedException e) { - } - } - - // Tell the observers that the session is terminated - notifyObservers(new MIGDBExitEvent(this, 0)); - - // Should not be necessary but just to be safe. - deleteObservers(); - } - - /** - * Notify the observers of new MI OOB events. - */ - @Override - public void notifyObservers(Object arg) { - setChanged(); - super.notifyObservers(arg); - } - - OutputStream getConsolePipe() { - if (miOutConsolePipe == null) { - getMIConsoleStream(); - } - return miOutConsolePipe; - } - - OutputStream getLogPipe() { - if (miOutLogPipe == null) { - getMILogStream(); - } - return miOutLogPipe; - } - - CommandQueue getTxQueue() { - return txQueue; - } - - CommandQueue getRxQueue() { - return rxQueue; - } - - Queue getEventQueue() { - return eventQueue; - } - - public RxThread getRxThread() { - return rxThread; - } - - InputStream getChannelInputStream() { - return inChannel; - } - - InputStream getChannelErrorStream() { - return inErrChannel; - } - - OutputStream getChannelOutputStream() { - return outChannel; - } - - MIOutput parse(String buffer) { - return parser.parse(buffer); - } - - public void fireEvents(MIEvent[] events) { - if (events != null && events.length > 0) { - for (int i = 0; i < events.length; i++) { - fireEvent(events[i]); - } - } - } - - public void fireEvent(MIEvent event) { - if (event != null) { - getEventQueue().addItem(event); - } - } - - protected void writeToConsole(String text) { - OutputStream console = getConsolePipe(); - if (console != null) { - try { - console.write(text.getBytes()); - console.flush(); - } - catch(IOException e) { - } - } - } - - public void enableVerboseMode(boolean enabled) { - verboseMode = enabled; - } - - public boolean isVerboseModeEnabled() { - return verboseMode; - } - - - /** - * getter for breakpointsWithFullName - * @return true when debugger should set breakpoints using full file name - */ - public final boolean isBreakpointsWithFullName() { - return breakpointsWithFullName; - } - - /** - * setter for breakpointsWithFullName - * set to true when debugger should set breakpoints using full file name, default is false - */ - public final void setBreakpointsWithFullName(boolean breakpointsWithFullName) { - this.breakpointsWithFullName = breakpointsWithFullName; - } -} |