1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-21 21:52:10 +02:00

Buf fix in MIInferior.

This commit is contained in:
Alain Magloire 2002-08-20 04:30:08 +00:00
parent 1c66d960ea
commit fa183e80b0
6 changed files with 242 additions and 182 deletions

View file

@ -4,14 +4,14 @@
*/ */
package org.eclipse.cdt.debug.mi.core; package org.eclipse.cdt.debug.mi.core;
import java.io.IOException; import java.io.IOException;
import org.eclipse.cdt.debug.mi.core.event.MIEvent; import org.eclipse.cdt.debug.mi.core.event.MIEvent;
/** /**
* Transmission command thread blocks on the command Queue * Event Thread blocks on the event Queue, wakes up
* and wake cmd are available and push them to gdb out channel. * when events are available and notify all the observers.
*/ */
public class EventThread extends Thread { public class EventThread extends Thread {
@ -22,29 +22,24 @@ public class EventThread extends Thread {
session = s; session = s;
} }
public void run () { public void run() {
try { // signal by the session of time to die.
while (true) { while (session.getChannelOutputStream() != null) {
MIEvent event = null; MIEvent event = null;
Queue eventQueue = session.getEventQueue(); Queue eventQueue = session.getEventQueue();
// removeItem() will block until an item is available. // removeItem() will block until an item is available.
try { try {
event = (MIEvent)eventQueue.removeItem(); event = (MIEvent) eventQueue.removeItem();
} catch (InterruptedException e) { } catch (InterruptedException e) {
// signal by the session of time to die. //e.printStackTrace();
if (session.getChannelOutputStream() == null) { }
throw new IOException(); try {
} if (event != null) {
//e.printStackTrace(); session.notifyObservers(event);
} }
try { } catch (Exception e) {
session.notifyObservers(event); e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} }
} catch (IOException e) {
//e.printStackTrace();
} }
} }
} }

View file

@ -3,65 +3,71 @@ package org.eclipse.cdt.debug.mi.core;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import org.eclipse.cdt.debug.mi.core.command.CLICommand; import org.eclipse.cdt.debug.mi.core.command.CLICommand;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory; import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIExecAbort; import org.eclipse.cdt.debug.mi.core.command.MIExecAbort;
import org.eclipse.cdt.debug.mi.core.command.MIGDBExit;
import org.eclipse.cdt.debug.mi.core.command.MIGDBShowExitCode; import org.eclipse.cdt.debug.mi.core.command.MIGDBShowExitCode;
import org.eclipse.cdt.debug.mi.core.event.MIExitEvent;
import org.eclipse.cdt.debug.mi.core.event.MIInferiorExitEvent; import org.eclipse.cdt.debug.mi.core.event.MIInferiorExitEvent;
import org.eclipse.cdt.debug.mi.core.output.MIGDBShowExitCodeInfo; import org.eclipse.cdt.debug.mi.core.output.MIGDBShowExitCodeInfo;
/** /**
* @author alain
*
* To change this generated comment edit the template variable "typecomment":
* Window>Preferences>Java>Templates.
* To enable and disable the creation of type comments go to
* Window>Preferences>Java>Code Generation.
*/ */
public class MIInferior extends Process { public class MIInferior extends Process {
public final static int SUSPENDED = 1; final static int SUSPENDED = 1;
public final static int RUNNING = 2; final static int RUNNING = 2;
public final static int TERMINATED = 4; final static int TERMINATED = 4;
boolean connected = false;
int state = 0; int state = 0;
MISession session; MISession session;
OutputStream out; OutputStream out;
PipedInputStream in;
PipedOutputStream inPiped;
PipedInputStream err;
PipedOutputStream errPiped;
MIInferior(MISession mi) { MIInferior(MISession mi) {
session = mi; session = mi;
out = new OutputStream() {
StringBuffer buf = new StringBuffer();
public void write(int b) throws IOException {
buf.append(b);
if (b == '\n') {
flush();
}
}
// Encapsulate the string sent to gdb in a fake command.
// and post it to the TxThread.
public void flush() throws IOException {
CLICommand cmd = new CLICommand(buf.toString()) {
public void setToken(int token) {
// override to do nothing;
}
};
try {
session.postCommand(cmd);
} catch (MIException e) {
throw new IOException("no mi session");
}
}
};
} }
/** /**
* @see java.lang.Process#getOutputStream() * @see java.lang.Process#getOutputStream()
*/ */
public OutputStream getOutputStream() { public OutputStream getOutputStream() {
if (out == null) {
out = new OutputStream() {
StringBuffer buf = new StringBuffer();
public void write(int b) throws IOException {
buf.append(b);
if (b == '\n') {
flush();
}
}
// Encapsulate the string sent to gdb in a fake command.
// and post it to the TxThread.
public void flush() throws IOException {
CLICommand cmd = new CLICommand(buf.toString()) {
public void setToken(int token) {
// override to do nothing;
}
};
try {
session.postCommand(cmd);
} catch (MIException e) {
throw new IOException("no mi session");
}
}
};
}
return out; return out;
} }
@ -69,15 +75,30 @@ public class MIInferior extends Process {
* @see java.lang.Process#getInputStream() * @see java.lang.Process#getInputStream()
*/ */
public InputStream getInputStream() { public InputStream getInputStream() {
return session.getTargetStream(); if (in == null) {
try {
inPiped = new PipedOutputStream();
in = new PipedInputStream(inPiped);
} catch (IOException e) {
}
}
return in;
} }
/** /**
* @see java.lang.Process#getErrorStream() * @see java.lang.Process#getErrorStream()
*/ */
public InputStream getErrorStream() { public InputStream getErrorStream() {
// FIXME the same as output?? // FIXME: We do not have any err stream from gdb/mi
return session.getTargetStream(); // so this gdb err channel instead.
if (err == null) {
try {
errPiped = new PipedOutputStream();
err = new PipedInputStream(errPiped);
} catch (IOException e) {
}
}
return err;
} }
/** /**
@ -96,7 +117,7 @@ public class MIInferior extends Process {
* @see java.lang.Process#exitValue() * @see java.lang.Process#exitValue()
*/ */
public int exitValue() { public int exitValue() {
if (isTerminated()) { if (isTerminated() && !session.isTerminated()) {
CommandFactory factory = session.getCommandFactory(); CommandFactory factory = session.getCommandFactory();
MIGDBShowExitCode code = factory.createMIGDBShowExitCode(); MIGDBShowExitCode code = factory.createMIGDBShowExitCode();
try { try {
@ -114,29 +135,15 @@ public class MIInferior extends Process {
* @see java.lang.Process#destroy() * @see java.lang.Process#destroy()
*/ */
public void destroy() { public void destroy() {
/*
if (!isTerminated()) { if (!isTerminated()) {
CommandFactory factory = session.getCommandFactory(); CommandFactory factory = session.getCommandFactory();
MIExecAbort abort = factory.createMIExecAbort(); MIExecAbort abort = factory.createMIExecAbort();
try { try {
session.postCommand(abort); session.postCommand(abort);
setTerminated();
session.getRxThread().fireEvent(new MIInferiorExitEvent()); session.getRxThread().fireEvent(new MIInferiorExitEvent());
} catch (MIException e) { } catch (MIException e) {
} }
} setTerminated();
*/
if (!isTerminated()) {
if (!isSuspended())
{
// interrupt execution
}
CommandFactory factory = session.getCommandFactory();
MIGDBExit exit = factory.createMIGDBExit();
try {
session.postCommand(exit);
} catch (MIException e) {
}
} }
} }
@ -152,6 +159,18 @@ public class MIInferior extends Process {
return state == TERMINATED; return state == TERMINATED;
} }
public boolean isConnected() {
return connected;
}
public synchronized void setConnected() {
connected = true;
}
public synchronized void setDisConnected() {
connected = false;
}
public synchronized void setSuspended() { public synchronized void setSuspended() {
state = SUSPENDED; state = SUSPENDED;
} }
@ -162,6 +181,31 @@ public class MIInferior extends Process {
public synchronized void setTerminated() { public synchronized void setTerminated() {
state = TERMINATED; state = TERMINATED;
// Close the streams.
try {
if (inPiped != null) {
inPiped.close();
inPiped = null;
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (errPiped != null) {
errPiped.close();
errPiped = null;
}
} catch (IOException e) {
e.printStackTrace();
}
notifyAll(); notifyAll();
} }
public OutputStream getPipedOutputStream() {
return inPiped;
}
public OutputStream getPipedErrorStream() {
return errPiped;
}
} }

View file

@ -51,10 +51,10 @@ public class MIPlugin extends Plugin {
String[]args = new String[]{"gdb", "-q", "-i", "mi", program}; String[]args = new String[]{"gdb", "-q", "-i", "mi", program};
Process gdb = Runtime.getRuntime().exec(args); Process gdb = Runtime.getRuntime().exec(args);
MISession session = createMISession(gdb.getInputStream(), gdb.getOutputStream()); MISession session = createMISession(gdb.getInputStream(), gdb.getOutputStream());
/* ///*
try { try {
CommandFactory factory = session.getCommandFactory(); CommandFactory factory = session.getCommandFactory();
MIBreakInsert bkpt= factory.createMIBreakInsert(true, false, null, 0, "main"); MIBreakInsert bkpt= factory.createMIBreakInsert(true, false, null, 0, "routine");
session.postCommand(bkpt); session.postCommand(bkpt);
MIInfo info = bkpt.getMIInfo(); MIInfo info = bkpt.getMIInfo();
if (info == null) { if (info == null) {
@ -63,7 +63,7 @@ public class MIPlugin extends Plugin {
} catch (MIException e) { } catch (MIException e) {
throw new IOException("Failed to attach"); throw new IOException("Failed to attach");
} }
*/ //*/
return new CSession(session); return new CSession(session);
} }

View file

@ -15,6 +15,7 @@ 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.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIGDBExit; 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.MIGDBSet;
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
import org.eclipse.cdt.debug.mi.core.output.MIOutput; import org.eclipse.cdt.debug.mi.core.output.MIOutput;
import org.eclipse.cdt.debug.mi.core.output.MIParser; import org.eclipse.cdt.debug.mi.core.output.MIParser;
@ -39,10 +40,6 @@ public class MISession extends Observable {
PipedInputStream miInPipe; PipedInputStream miInPipe;
PipedOutputStream miOutPipe; PipedOutputStream miOutPipe;
PipedInputStream targetInPipe;
PipedOutputStream targetOutPipe;
PipedInputStream logInPipe;
PipedOutputStream logOutPipe;
CommandFactory factory; CommandFactory factory;
@ -61,59 +58,62 @@ public class MISession extends Observable {
public MISession(InputStream i, OutputStream o) { public MISession(InputStream i, OutputStream o) {
inChannel = i; inChannel = i;
outChannel = o; outChannel = o;
factory = new CommandFactory(); factory = new CommandFactory();
parser = new MIParser(); parser = new MIParser();
txQueue = new CommandQueue(); txQueue = new CommandQueue();
rxQueue = new CommandQueue(); rxQueue = new CommandQueue();
eventQueue = new Queue(); eventQueue = new Queue();
txThread = new TxThread(this); txThread = new TxThread(this);
rxThread = new RxThread(this); rxThread = new RxThread(this);
eventThread = new EventThread(this); eventThread = new EventThread(this);
txThread.start(); txThread.start();
rxThread.start(); rxThread.start();
eventThread.start(); eventThread.start();
try {
miOutPipe = new PipedOutputStream();
miInPipe = new PipedInputStream(miOutPipe);
targetOutPipe = new PipedOutputStream();
targetInPipe = new PipedInputStream(targetOutPipe);
logOutPipe = new PipedOutputStream();
logInPipe = new PipedInputStream(logOutPipe);
} catch (IOException e) {
}
inferior = new MIInferior(this); inferior = new MIInferior(this);
try { try {
postCommand(new MIGDBSet(new String[]{"confirm", "off"})); // Disable a certain number of irritations from gdb.
// Like confirmation and screen size.
MIInfo info;
MIGDBSet confirm = new MIGDBSet(new String[]{"confirm", "off"});
postCommand(confirm);
info = confirm.getMIInfo();
MIGDBSet width = new MIGDBSet(new String[]{"width", "99999999"});
postCommand(width);
info = confirm.getMIInfo();
MIGDBSet height = new MIGDBSet(new String[]{"height", "99999999"});
postCommand(height);
info = confirm.getMIInfo();
} catch (MIException e) { } catch (MIException e) {
// FIXME: Do not catch the exception but pass it up.
} }
} }
/** /**
* get Console Stream. * get MI Console Stream.
*/ */
public InputStream getMIStream() { public InputStream getMIStream() {
if (miInPipe == null) {
try {
miOutPipe = new PipedOutputStream();
miInPipe = new PipedInputStream(miOutPipe);
} catch (IOException e) {
}
}
return miInPipe; return miInPipe;
} }
/** /**
* Get Target Stream. * For example the CDI/MI bridge uses the command
*/
public InputStream getTargetStream() {
return targetInPipe;
}
/**
* Get Log Stream
*/
public InputStream getLogStream() {
return logInPipe;
}
/**
* For example the CDI/MI adapters uses the command
* factory to create MI commands this allow overloading. * factory to create MI commands this allow overloading.
*/ */
public CommandFactory getCommandFactory() { public CommandFactory getCommandFactory() {
@ -121,21 +121,21 @@ public class MISession extends Observable {
} }
/** /**
* Set a new factory to use in CDI/MI adapters. * Set a new factory to use for command.
*/ */
public void setCommandFactory(CommandFactory f) { public void setCommandFactory(CommandFactory f) {
factory = f; factory = f;
} }
/** /**
* Return the MI main parser. * Return the MI parser.
*/ */
public MIParser getMIParser() { public MIParser getMIParser() {
return parser; return parser;
} }
/** /**
* Reset the parser. * Reset the MI parser.
*/ */
public void setMIParser(MIParser p) { public void setMIParser(MIParser p) {
parser = p; parser = p;
@ -156,6 +156,7 @@ public class MISession extends Observable {
} }
/** /**
* equivalent to:
* postCommand(cmd, 10 secs) * postCommand(cmd, 10 secs)
*/ */
public void postCommand(Command cmd) throws MIException { public void postCommand(Command cmd) throws MIException {
@ -163,13 +164,14 @@ public class MISession extends Observable {
} }
/** /**
* Sends a command to gdb. * Sends a command to gdb, and wait(timeout) for a response.
*/ */
public void postCommand(Command cmd, long timeout) throws MIException { static int number = 1;
public synchronized void postCommand(Command cmd, long timeout) throws MIException {
MIPlugin.getDefault().debugLog(cmd.toString()); MIPlugin.getDefault().debugLog(number++ + " " + cmd.toString());
// Test if we in a sane state. // Test if we are in a sane state.
if (!txThread.isAlive() || !rxThread.isAlive()) { if (!txThread.isAlive() || !rxThread.isAlive()) {
throw new MIException("{R,T}xThread terminated"); throw new MIException("{R,T}xThread terminated");
} }
@ -178,53 +180,57 @@ public class MISession extends Observable {
// Wait for the response or timedout // Wait for the response or timedout
synchronized (cmd) { synchronized (cmd) {
// Do not wait for command if time out is 0 // RxThread will set the MIOutput on the cmd
if (timeout > 0) { // when the response arrive.
// RxThread will set the MIOutput on the cmd while (cmd.getMIOutput() == null) {
// when the response arrive. try {
while (cmd.getMIOutput() == null) { cmd.wait(timeout);
try { if (cmd.getMIOutput() == null) {
cmd.wait(timeout); throw new MIException("Timedout");
if (cmd.getMIOutput() == null) {
throw new MIException("Timedout");
}
} catch (InterruptedException e) {
} }
} catch (InterruptedException e) {
} }
} }
} }
} }
/**
* Return the inferior "Process".
*/
public MIInferior getMIInferior() { public MIInferior getMIInferior() {
return inferior; return inferior;
} }
/**
* Check if the gdb session is terminated.
*/
public boolean isTerminated() { public boolean isTerminated() {
return (!txThread.isAlive() || !rxThread.isAlive()); return (!txThread.isAlive() || !rxThread.isAlive());
} }
/** /**
* Close the MISession. * Terminate the MISession.
*/ */
public void terminate() { public void terminate() {
// Destroy any MI Inferior // Destroy any MI Inferior(Process)
inferior.destroy(); inferior.destroy();
// send the exit. // send the exit(-gdb-exit).
try { try {
MIGDBExit exit = factory.createMIGDBExit(); MIGDBExit exit = factory.createMIGDBExit();
postCommand(exit); postCommand(exit);
} catch (MIException e) { } catch (MIException e) {
} }
// Explicitely close the channels // Close the input GDB prompt
try { try {
inChannel.close(); inChannel.close();
} catch (IOException e) { } catch (IOException e) {
} }
inChannel = null; inChannel = null;
// Close the output GDB prompt
try { try {
outChannel.close(); outChannel.close();
} catch (IOException e) { } catch (IOException e) {
@ -232,30 +238,39 @@ public class MISession extends Observable {
// This is __needed__ to stop the txThread and eventThread. // This is __needed__ to stop the txThread and eventThread.
outChannel = null; outChannel = null;
// Make sure all threads are gone. // Kill the Transmition thread.
try { try {
if (txThread.isAlive()) { if (txThread.isAlive()) {
txThread.interrupt(); txThread.interrupt();
} }
txThread.join(); txThread.join(cmdTimeout);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
// Kill the Receiving Thread.
try { try {
if (rxThread.isAlive()) { if (rxThread.isAlive()) {
rxThread.interrupt(); rxThread.interrupt();
} }
rxThread.join(); rxThread.join(cmdTimeout);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
// Kill the event Thread.
try { try {
if (eventThread.isAlive()) { if (eventThread.isAlive()) {
eventThread.interrupt(); eventThread.interrupt();
} }
eventThread.join(); eventThread.join(cmdTimeout);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
// Destroy the MI console stream.
try {
miOutPipe.close();
miInPipe = null;
} catch (IOException e) {
}
} }
/** /**
@ -271,14 +286,6 @@ public class MISession extends Observable {
return miOutPipe; return miOutPipe;
} }
OutputStream getTargetPipe() {
return targetOutPipe;
}
OutputStream getLogPipe() {
return logOutPipe;
}
CommandQueue getTxQueue() { CommandQueue getTxQueue() {
return txQueue; return txQueue;
} }

View file

@ -44,15 +44,17 @@ import org.eclipse.cdt.debug.mi.core.output.MITargetStreamOutput;
import org.eclipse.cdt.debug.mi.core.output.MIValue; import org.eclipse.cdt.debug.mi.core.output.MIValue;
/** /**
* Receiving thread of gdb, read the input channel. * Receiving thread of gdb response output.
*/ */
public class RxThread extends Thread { public class RxThread extends Thread {
final MISession session; final MISession session;
List oobList;
public RxThread(MISession s) { public RxThread(MISession s) {
super("MI RX Thread"); super("MI RX Thread");
session = s; session = s;
oobList = new ArrayList();
} }
/* /*
@ -62,7 +64,6 @@ public class RxThread extends Thread {
public void run () { public void run () {
BufferedReader reader = BufferedReader reader =
new BufferedReader(new InputStreamReader(session.getChannelInputStream())); new BufferedReader(new InputStreamReader(session.getChannelInputStream()));
StringBuffer buffer = new StringBuffer();
try { try {
while (true) { while (true) {
String line; String line;
@ -121,20 +122,33 @@ MIPlugin.getDefault().debugLog(line);
fireEvent(event); fireEvent(event);
} else if ("exit".equals(state)) { } else if ("exit".equals(state)) {
session.getMIInferior().setTerminated(); session.getMIInferior().setTerminated();
fireEvent(new MIExitEvent()); MIEvent event = new MIExitEvent();
fireEvent(event);
} else if ("connected".equals(state)) {
session.getMIInferior().setConnected();
} }
// Clear the accumulate oobList on each new Result Command
// response.
MIOOBRecord [] oobRecords =
(MIOOBRecord[])oobList.toArray(new MIOOBRecord[0]);
oobList.clear();
// Notify the waiting command. // Notify the waiting command.
if (cmd != null) { if (cmd != null) {
synchronized (cmd) { synchronized (cmd) {
// Set the accumulate console Stream
response.setMIOOBRecords(oobRecords);
cmd.setMIOutput(response); cmd.setMIOutput(response);
cmd.notifyAll(); cmd.notifyAll();
} }
} }
// Some result record contains informaton specific to oob. // Some result record contains informaton specific to oob.
// This will happen when CLI-Command is use, for example // This will happen when CLI-Command is use, for example
// doing "run" will block and return a breakpointhit // doing "run" will block and return a breakpointhit
processMIOOBRecord(rr, list); processMIOOBRecord(rr, list);
} }
// Process OOBs // Process OOBs
@ -162,35 +176,33 @@ MIPlugin.getDefault().debugLog(line);
void processMIOOBRecord(MIAsyncRecord async, List list) { void processMIOOBRecord(MIAsyncRecord async, List list) {
if (async instanceof MIExecAsyncOutput) { if (async instanceof MIExecAsyncOutput) {
MIExecAsyncOutput exec = (MIExecAsyncOutput)async; MIExecAsyncOutput exec = (MIExecAsyncOutput)async;
MIEvent e = null;
// Change of state. // Change of state.
String state = exec.getAsyncClass(); String state = exec.getAsyncClass();
if ("stopped".equals(state)) { if ("stopped".equals(state)) {
MIEvent e = null;
session.getMIInferior().setSuspended(); session.getMIInferior().setSuspended();
} MIResult[] results = exec.getMIResults();
for (int i = 0; i < results.length; i++) {
MIResult[] results = exec.getMIResults(); String var = results[i].getVariable();
for (int i = 0; i < results.length; i++) { MIValue val = results[i].getMIValue();
String var = results[i].getVariable(); if (var.equals("reason")) {
MIValue val = results[i].getMIValue(); if (val instanceof MIConst) {
if (var.equals("reason")) { String reason =((MIConst)val).getString();
if (val instanceof MIConst) { e = createEvent(reason, exec);
String reason = ((MIConst)val).getString(); if (e != null) {
e = createEvent(reason, exec); list.add(e);
if (e != null) { }
list.add(e);
} }
} }
} }
}
// HACK: GDB for temporary breakpoints will not send the // HACK: GDB for temporary breakpoints will not send the
// "reason" ??? Fake this as breakpoint-hit // "reason" ??? Fake this as breakpoint-hit
if (e == null) { if (e == null) {
e = createEvent("breakpoint-hit", exec); e = createEvent("breakpoint-hit", exec);
if (e != null) { if (e != null) {
list.add(e); list.add(e);
}
} }
} }
} else if (async instanceof MIStatusAsyncOutput) { } else if (async instanceof MIStatusAsyncOutput) {
@ -214,8 +226,11 @@ MIPlugin.getDefault().debugLog(line);
} }
} }
} }
// Accumulate the Console Stream Output response for parsing.
// Some commands will put valuable info in the Console Stream.
oobList.add(stream);
} else if (stream instanceof MITargetStreamOutput) { } else if (stream instanceof MITargetStreamOutput) {
OutputStream target = session.getTargetPipe(); OutputStream target = session.getMIInferior().getPipedOutputStream();
if (target != null) { if (target != null) {
MITargetStreamOutput out = (MITargetStreamOutput)stream; MITargetStreamOutput out = (MITargetStreamOutput)stream;
String str = out.getString(); String str = out.getString();
@ -228,7 +243,7 @@ MIPlugin.getDefault().debugLog(line);
} }
} }
} else if (stream instanceof MILogStreamOutput) { } else if (stream instanceof MILogStreamOutput) {
OutputStream log = session.getLogPipe(); OutputStream log = session.getMIInferior().getPipedErrorStream();
if (log != null) { if (log != null) {
MILogStreamOutput out = (MILogStreamOutput)stream; MILogStreamOutput out = (MILogStreamOutput)stream;
String str = out.getString(); String str = out.getString();
@ -310,13 +325,13 @@ MIPlugin.getDefault().debugLog(line);
event = new MIFunctionFinishedEvent(rr); event = new MIFunctionFinishedEvent(rr);
} }
} else if ("exited-normally".equals(reason)) { } else if ("exited-normally".equals(reason)) {
// session.getMIInferior().setTerminated(); session.getMIInferior().setTerminated();
event = new MIInferiorExitEvent(); event = new MIInferiorExitEvent();
} else if ("exited-signalled".equals(reason)) { } else if ("exited-signalled".equals(reason)) {
// session.getMIInferior().setTerminated(); session.getMIInferior().setTerminated();
event = new MIInferiorExitEvent(); event = new MIInferiorExitEvent();
} else if ("exited".equals(reason)) { } else if ("exited".equals(reason)) {
// session.getMIInferior().setTerminated(); session.getMIInferior().setTerminated();
event = new MIInferiorExitEvent(); event = new MIInferiorExitEvent();
} }
return event; return event;

View file

@ -28,17 +28,14 @@ public class TxThread extends Thread {
public void run () { public void run () {
try { try {
while (true) { // signal by the session of time to die.
while (session.getChannelOutputStream() != null) {
Command cmd = null; Command cmd = null;
CommandQueue txQueue = session.getTxQueue(); CommandQueue txQueue = session.getTxQueue();
// removeCommand() will block until a command is available. // removeCommand() will block until a command is available.
try { try {
cmd = txQueue.removeCommand(); cmd = txQueue.removeCommand();
} catch (InterruptedException e) { } catch (InterruptedException e) {
// signal by the session of time to die.
if (session.getChannelOutputStream() == null) {
throw new IOException();
}
//e.printStackTrace(); //e.printStackTrace();
} }
@ -55,8 +52,10 @@ public class TxThread extends Thread {
// shove in the pipe // shove in the pipe
String str = cmd.toString(); String str = cmd.toString();
OutputStream out = session.getChannelOutputStream(); OutputStream out = session.getChannelOutputStream();
out.write(str.getBytes()); if (out != null) {
out.flush(); out.write(str.getBytes());
out.flush();
}
} }
} }
} catch (IOException e) { } catch (IOException e) {