1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-01 05:15:43 +02:00

Redo the event dispatch now a permanent thread is use to

dispatch events.
This commit is contained in:
Alain Magloire 2002-08-15 05:58:08 +00:00
parent b8c5ededb8
commit 1354f9e661
21 changed files with 312 additions and 183 deletions

View file

@ -0,0 +1,53 @@
/*
* (c) Copyright QNX Software Systems Ltd. 2002.
* All Rights Reserved.
*/
package org.eclipse.cdt.debug.mi.core;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.debug.mi.core.command.Command;
/**
* Simple thread-safe Queue implemetation.
*/
public class CommandQueue extends Queue{
public CommandQueue() {
super();
}
public Command removeCommand(int id) {
//print("in removeCommand(" + id + ") - entering");
synchronized (list) {
int size = list.size();
for (int i = 0; i < size; i++) {
Command cmd = (Command)list.get(i);
int token = cmd.getToken();
if (token == id) {
list.remove(cmd);
return cmd;
}
}
}
return null;
}
public Command removeCommand() throws InterruptedException {
//print("in removeCommand() - entering");
return (Command)removeItem();
}
public void addCommand(Command cmd) {
//print("in addCommand() - entering");
addItem(cmd);
}
private static void print(String msg) {
String name = Thread.currentThread().getName();
System.out.println(name + ": " + msg);
}
}

View file

@ -0,0 +1,50 @@
/*
* (c) Copyright QNX Software Systems Ltd. 2002.
* All Rights Reserved.
*/
package org.eclipse.cdt.debug.mi.core;
import java.io.IOException;
import org.eclipse.cdt.debug.mi.core.event.MIEvent;
/**
* Transmission command thread blocks on the command Queue
* and wake cmd are available and push them to gdb out channel.
*/
public class EventThread extends Thread {
MISession session;
public EventThread(MISession s) {
super("MI Event Thread");
session = s;
}
public void run () {
try {
while (true) {
MIEvent event = null;
Queue eventQueue = session.getEventQueue();
// removeItem() will block until an item is available.
try {
event = (MIEvent)eventQueue.removeItem();
} catch (InterruptedException e) {
// signal by the session of time to die.
if (session.getChannelOutputStream() == null) {
throw new IOException();
}
//e.printStackTrace();
}
try {
session.notifyObservers(event);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException e) {
//e.printStackTrace();
}
}
}

View file

@ -8,6 +8,7 @@ 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.MIGDBShowExitCode; import org.eclipse.cdt.debug.mi.core.command.MIGDBShowExitCode;
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;
/** /**
@ -18,7 +19,7 @@ import org.eclipse.cdt.debug.mi.core.output.MIGDBShowExitCodeInfo;
* To enable and disable the creation of type comments go to * To enable and disable the creation of type comments go to
* Window>Preferences>Java>Code Generation. * Window>Preferences>Java>Code Generation.
*/ */
public class MIProcess extends Process { public class MIInferior extends Process {
public final static int SUSPENDED = 1; public final static int SUSPENDED = 1;
public final static int RUNNING = 2; public final static int RUNNING = 2;
@ -29,7 +30,7 @@ public class MIProcess extends Process {
MISession session; MISession session;
OutputStream out; OutputStream out;
MIProcess(MISession mi) { MIInferior(MISession mi) {
session = mi; session = mi;
out = new OutputStream() { out = new OutputStream() {
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
@ -39,6 +40,8 @@ public class MIProcess extends Process {
flush(); flush();
} }
} }
// Encapsulate the string sent to gdb in a fake command.
// and post it to the TxThread.
public void flush() throws IOException { public void flush() throws IOException {
CLICommand cmd = new CLICommand(buf.toString()) { CLICommand cmd = new CLICommand(buf.toString()) {
public void setToken(int token) { public void setToken(int token) {
@ -113,16 +116,13 @@ public class MIProcess extends Process {
if (!isTerminated()) { if (!isTerminated()) {
CommandFactory factory = session.getCommandFactory(); CommandFactory factory = session.getCommandFactory();
MIExecAbort abort = factory.createMIExecAbort(); MIExecAbort abort = factory.createMIExecAbort();
CLICommand yes = new CLICommand("yes") {
public void setToken() { }
};
try { try {
session.postCommand(abort); session.postCommand(abort);
session.postCommand(yes); setTerminated();
session.getRxThread().fireEvent(new MIInferiorExitEvent());
} catch (MIException e) { } catch (MIException e) {
} }
} }
// Do not wait for answer.
} }
public synchronized boolean isSuspended() { public synchronized boolean isSuspended() {

View file

@ -48,7 +48,7 @@ public class MIPlugin extends Plugin {
} }
public ICDISession createCSession(String program) throws IOException { public ICDISession createCSession(String program) throws IOException {
String[]args = new String[]{"gdb", "--quiet", "-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());
/* /*

View file

@ -13,6 +13,8 @@ import java.util.Observable;
import org.eclipse.cdt.debug.mi.core.command.Command; 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.MIGDBSet;
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;
@ -27,11 +29,13 @@ public class MISession extends Observable {
InputStream inChannel; InputStream inChannel;
OutputStream outChannel; OutputStream outChannel;
Thread txThread; TxThread txThread;
Thread rxThread; RxThread rxThread;
EventThread eventThread;
Queue txQueue; CommandQueue txQueue;
Queue rxQueue; CommandQueue rxQueue;
Queue eventQueue;
PipedInputStream miInPipe; PipedInputStream miInPipe;
PipedOutputStream miOutPipe; PipedOutputStream miOutPipe;
@ -46,7 +50,7 @@ public class MISession extends Observable {
long cmdTimeout = 10000; // 10 * 1000 (~ 10 secs); long cmdTimeout = 10000; // 10 * 1000 (~ 10 secs);
MIProcess process; MIInferior inferior;
/** /**
* Create the gdb session. * Create the gdb session.
@ -59,12 +63,15 @@ public class MISession extends Observable {
outChannel = o; outChannel = o;
factory = new CommandFactory(); factory = new CommandFactory();
parser = new MIParser(); parser = new MIParser();
txQueue = new Queue(); txQueue = new CommandQueue();
rxQueue = new Queue(); rxQueue = new CommandQueue();
eventQueue = new Queue();
txThread = new TxThread(this); txThread = new TxThread(this);
rxThread = new RxThread(this); rxThread = new RxThread(this);
eventThread = new EventThread(this);
txThread.start(); txThread.start();
rxThread.start(); rxThread.start();
eventThread.start();
try { try {
miOutPipe = new PipedOutputStream(); miOutPipe = new PipedOutputStream();
@ -76,7 +83,11 @@ public class MISession extends Observable {
} catch (IOException e) { } catch (IOException e) {
} }
process = new MIProcess(this); inferior = new MIInferior(this);
try {
postCommand(new MIGDBSet(new String[]{"confirm", "off"}));
} catch (MIException e) {
}
} }
/** /**
@ -157,25 +168,35 @@ public class MISession extends Observable {
public void postCommand(Command cmd, long timeout) throws MIException { public void postCommand(Command cmd, long timeout) throws MIException {
MIPlugin.getDefault().debugLog(cmd.toString()); MIPlugin.getDefault().debugLog(cmd.toString());
// Test if we 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");
} }
txQueue.addCommand(cmd); txQueue.addCommand(cmd);
// Wait for the response or timedout
synchronized (cmd) { synchronized (cmd) {
// RxThread will set the MIOutput on the cmd // Do not wait for command if time out is 0
// when the response arrive. if (timeout > 0) {
while (cmd.getMIOutput() == null) { // RxThread will set the MIOutput on the cmd
try { // when the response arrive.
cmd.wait(timeout); while (cmd.getMIOutput() == null) {
break; // Timeout or Notify try {
} catch (InterruptedException e) { cmd.wait(timeout);
if (cmd.getMIOutput() == null) {
throw new MIException("Timedout");
}
} catch (InterruptedException e) {
}
} }
} }
} }
} }
public MIProcess getMIProcess() { public MIInferior getMIInferior() {
return process; return inferior;
} }
public boolean isTerminated() { public boolean isTerminated() {
@ -187,9 +208,17 @@ public class MISession extends Observable {
*/ */
public void terminate() { public void terminate() {
process.destroy(); // Destroy any MI Inferior
inferior.destroy();
// Closing the channel will kill the RxThread. // send the exit.
try {
MIGDBExit exit = factory.createMIGDBExit();
postCommand(exit);
} catch (MIException e) {
}
// Explicitely close the channels
try { try {
inChannel.close(); inChannel.close();
} catch (IOException e) { } catch (IOException e) {
@ -200,9 +229,10 @@ public class MISession extends Observable {
outChannel.close(); outChannel.close();
} catch (IOException e) { } catch (IOException e) {
} }
// This is __needed__ to stop the txThread. // This is __needed__ to stop the txThread and eventThread.
outChannel = null; outChannel = null;
// Make sure all threads are gone.
try { try {
if (txThread.isAlive()) { if (txThread.isAlive()) {
txThread.interrupt(); txThread.interrupt();
@ -218,6 +248,14 @@ public class MISession extends Observable {
rxThread.join(); rxThread.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
try {
if (eventThread.isAlive()) {
eventThread.interrupt();
}
eventThread.join();
} catch (InterruptedException e) {
}
} }
/** /**
@ -241,14 +279,22 @@ public class MISession extends Observable {
return logOutPipe; return logOutPipe;
} }
Queue getTxQueue() { CommandQueue getTxQueue() {
return txQueue; return txQueue;
} }
Queue getRxQueue() { CommandQueue getRxQueue() {
return rxQueue; return rxQueue;
} }
Queue getEventQueue() {
return eventQueue;
}
RxThread getRxThread() {
return rxThread;
}
InputStream getChannelInputStream() { InputStream getChannelInputStream() {
return inChannel; return inChannel;
} }

View file

@ -8,65 +8,47 @@ import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.eclipse.cdt.debug.mi.core.command.Command;
/** /**
* Simple thread-safe Queue implemetation. * Simple thread-safe Queue implemetation.
*/ */
public class Queue { public class Queue {
private List list; protected List list;
public Queue() { public Queue() {
list = Collections.synchronizedList(new LinkedList()); list = Collections.synchronizedList(new LinkedList());
} }
public Command removeCommand(int id) { public Object removeItem() throws InterruptedException {
//print("in removeCommand(" + id + ") - entering"); //print("in removeItem() - entering");
synchronized (list) {
int size = list.size();
for (int i = 0; i < size; i++) {
Command cmd = (Command)list.get(i);
int token = cmd.getToken();
if (token == id) {
list.remove(cmd);
return cmd;
}
}
}
return null;
}
public Command removeCommand() throws InterruptedException {
//print("in removeCommand() - entering");
synchronized (list) { synchronized (list) {
while (list.isEmpty()) { while (list.isEmpty()) {
//print("in removeCommand() - about to wait()"); //print("in removeItem() - about to wait()");
list.wait(); list.wait();
//print("in removeCommand() - done with wait()"); //print("in removeItem() - done with wait()");
} }
// extract the new first cmd // extract the new first cmd
Command cmd = (Command)list.remove(0); Object item = list.remove(0);
//print("in removeCommand() - leaving"); //print("in removeItem() - leaving");
return cmd; return item;
} }
} }
public void addCommand(Command cmd) { public void addItem(Object item) {
//print("in addCommand() - entering"); //print("in addItem() - entering");
synchronized (list) { synchronized (list) {
// There will always be room to add to this List // There will always be room to add to this List
// because it expands as needed. // because it expands as needed.
list.add(cmd); list.add(item);
//print("in addCommand - just added: '" + cmd + "'"); //print("in addItem - just added: '" + cmd + "'");
// After adding, notify any and all waiting // After adding, notify any and all waiting
// threads that the list has changed. // threads that the list has changed.
list.notifyAll(); list.notifyAll();
//print("in addCommand() - just notified"); //print("in addItem() - just notified");
} }
//print("in addCommand() - leaving"); //print("in addItem() - leaving");
} }
private static void print(String msg) { private static void print(String msg) {

View file

@ -18,7 +18,6 @@ import org.eclipse.cdt.debug.mi.core.command.MIExecNextInstruction;
import org.eclipse.cdt.debug.mi.core.command.MIExecStep; import org.eclipse.cdt.debug.mi.core.command.MIExecStep;
import org.eclipse.cdt.debug.mi.core.command.MIExecStepInstruction; import org.eclipse.cdt.debug.mi.core.command.MIExecStepInstruction;
import org.eclipse.cdt.debug.mi.core.command.MIExecUntil; import org.eclipse.cdt.debug.mi.core.command.MIExecUntil;
import org.eclipse.cdt.debug.mi.core.event.EventThread;
import org.eclipse.cdt.debug.mi.core.event.MIBreakpointEvent; import org.eclipse.cdt.debug.mi.core.event.MIBreakpointEvent;
import org.eclipse.cdt.debug.mi.core.event.MIEvent; import org.eclipse.cdt.debug.mi.core.event.MIEvent;
import org.eclipse.cdt.debug.mi.core.event.MIExitEvent; import org.eclipse.cdt.debug.mi.core.event.MIExitEvent;
@ -68,30 +67,12 @@ public class RxThread extends Thread {
while (true) { while (true) {
String line; String line;
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
// Testing on GNU/Linux where target stream output
// is entertwine with MI out,
// comment out the if/else below and just use:
// processMIOutput(line);
// at least for testing.
// We accumulate until we see the gdb terminator.
MIPlugin.getDefault().debugLog(line); MIPlugin.getDefault().debugLog(line);
if (line.startsWith(MIOutput.terminator)) { processMIOutput(line + "\n");
// discard termination
processMIOutput(buffer.toString());
buffer = new StringBuffer();
} else if (line.startsWith(MITargetStreamOutput.startTag)) {
// Process Target output immediately.
processMIOutput(line + "\n");
} else {
buffer.append(line).append('\n');
}
} }
} }
} catch (IOException e) { } catch (IOException e) {
MIEvent event = new MIExitEvent(); fireEvent(new MIExitEvent());
Thread eventTread = new EventThread(session, new MIEvent[]{event});
eventTread.start();
//e.printStackTrace(); //e.printStackTrace();
} }
} }
@ -106,7 +87,7 @@ MIPlugin.getDefault().debugLog(line);
MIOutput response = session.parse(buffer); MIOutput response = session.parse(buffer);
if (response != null) { if (response != null) {
List list = new ArrayList(); List list = new ArrayList();
Queue rxQueue = session.getRxQueue(); CommandQueue rxQueue = session.getRxQueue();
// Notify any command waiting for a ResultRecord. // Notify any command waiting for a ResultRecord.
MIResultRecord rr = response.getMIResultRecord(); MIResultRecord rr = response.getMIResultRecord();
@ -135,11 +116,11 @@ MIPlugin.getDefault().debugLog(line);
} else { } else {
type = MIRunningEvent.CONTINUE; type = MIRunningEvent.CONTINUE;
} }
session.getMIProcess().setRunning(); session.getMIInferior().setRunning();
MIEvent event = new MIRunningEvent(type); MIEvent event = new MIRunningEvent(type);
fireEvents(new MIEvent[]{event}); fireEvent(event);
} else if ("exit".equals(state)) { } else if ("exit".equals(state)) {
session.getMIProcess().setTerminated(); session.getMIInferior().setTerminated();
} }
// Notify the waiting command. // Notify the waiting command.
@ -180,11 +161,12 @@ 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)) {
session.getMIProcess().setSuspended(); session.getMIInferior().setSuspended();
} }
MIResult[] results = exec.getMIResults(); MIResult[] results = exec.getMIResults();
@ -194,13 +176,22 @@ MIPlugin.getDefault().debugLog(line);
if (var.equals("reason")) { if (var.equals("reason")) {
if (val instanceof MIConst) { if (val instanceof MIConst) {
String reason = ((MIConst)val).getString(); String reason = ((MIConst)val).getString();
MIEvent e = createEvent(reason, exec); e = createEvent(reason, exec);
if (e != null) { if (e != null) {
list.add(e); list.add(e);
} }
} }
} }
} }
// HACK: GDB for temporary breakpoints will not send the
// "reason" ??? Fake this as breakpoint-hit
if (e == null) {
e = createEvent("breakpoint-hit", exec);
if (e != null) {
list.add(e);
}
}
} else if (async instanceof MIStatusAsyncOutput) { } else if (async instanceof MIStatusAsyncOutput) {
// Nothing done .. but what about +download?? // Nothing done .. but what about +download??
} else if (async instanceof MINotifyAsyncOutput) { } else if (async instanceof MINotifyAsyncOutput) {
@ -318,19 +309,25 @@ 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.getMIProcess().setTerminated(); session.getMIInferior().setTerminated();
event = new MIInferiorExitEvent(); event = new MIInferiorExitEvent();
} else if ("exited-signalled".equals(reason)) { } else if ("exited-signalled".equals(reason)) {
session.getMIProcess().setTerminated(); session.getMIInferior().setTerminated();
event = new MIInferiorExitEvent();
} else if ("exited".equals(reason)) {
session.getMIInferior().setTerminated();
event = new MIInferiorExitEvent(); event = new MIInferiorExitEvent();
} }
return event; return event;
} }
public void fireEvents(MIEvent[] events) { public void fireEvents(MIEvent[] events) {
if (events.length > 0) { for (int i = 0; i < events.length; i++) {
Thread eventTread = new EventThread(session, events); fireEvent(events[i]);
eventTread.start();
} }
} }
public void fireEvent(MIEvent event) {
session.getEventQueue().addItem(event);
}
} }

View file

@ -30,7 +30,7 @@ public class TxThread extends Thread {
try { try {
while (true) { while (true) {
Command cmd = null; Command cmd = null;
Queue 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();
@ -54,7 +54,7 @@ public class TxThread extends Thread {
// a valid token, this is to permit input(HACK!) // a valid token, this is to permit input(HACK!)
// or commands that do not want to wait for responses. // or commands that do not want to wait for responses.
if (cmd.getToken() > 0) { if (cmd.getToken() > 0) {
Queue rxQueue = session.getRxQueue(); CommandQueue rxQueue = session.getRxQueue();
rxQueue.addCommand(cmd); rxQueue.addCommand(cmd);
} }
} }

View file

@ -30,8 +30,10 @@ import org.eclipse.cdt.debug.mi.core.command.MIExecRun;
import org.eclipse.cdt.debug.mi.core.command.MIExecStep; import org.eclipse.cdt.debug.mi.core.command.MIExecStep;
import org.eclipse.cdt.debug.mi.core.command.MIExecStepInstruction; import org.eclipse.cdt.debug.mi.core.command.MIExecStepInstruction;
import org.eclipse.cdt.debug.mi.core.command.MITargetDetach; import org.eclipse.cdt.debug.mi.core.command.MITargetDetach;
import org.eclipse.cdt.debug.mi.core.command.MIThreadListIds;
import org.eclipse.cdt.debug.mi.core.output.MIDataEvaluateExpressionInfo; import org.eclipse.cdt.debug.mi.core.output.MIDataEvaluateExpressionInfo;
import org.eclipse.cdt.debug.mi.core.output.MIInfo; import org.eclipse.cdt.debug.mi.core.output.MIInfo;
import org.eclipse.cdt.debug.mi.core.output.MIThreadListIdsInfo;
/** /**
*/ */
@ -57,6 +59,16 @@ public class CTarget implements ICDITarget {
threadList.remove(cthread); threadList.remove(cthread);
} }
boolean containsCThread(int id) {
for (int i = 0; i < threadList.size(); i++) {
CThread cthread = (CThread)threadList.get(i);
if (cthread.getId() == id) {
return true;
}
}
return false;
}
CThread[] getCThreads() { CThread[] getCThreads() {
return (CThread[])threadList.toArray(new CThread[threadList.size()]); return (CThread[])threadList.toArray(new CThread[threadList.size()]);
} }
@ -109,7 +121,7 @@ public class CTarget implements ICDITarget {
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#getProcess() * @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#getProcess()
*/ */
public Process getProcess() { public Process getProcess() {
return session.getMISession().getMIProcess(); return session.getMISession().getMIInferior();
} }
/** /**
@ -144,7 +156,29 @@ public class CTarget implements ICDITarget {
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#getThreads() * @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#getThreads()
*/ */
public ICDIThread[] getThreads() throws CDIException { public ICDIThread[] getThreads() throws CDIException {
return new ICDIThread[0]; MISession mi = session.getMISession();
CommandFactory factory = mi.getCommandFactory();
MIThreadListIds tids = factory.createMIThreadListIds();
try {
mi.postCommand(tids);
MIThreadListIdsInfo info = tids.getMIThreadListIdsInfo();
int[] ids = info.getThreadIds();
if (ids != null && ids.length > 0) {
for (int i = 0; i < ids.length; i++) {
if (! containsCThread(ids[i])) {
addCThread(new CThread(this, ids[i]));
}
}
} else {
// HACK create a dummy thread
if (threadList.size() == 0) {
addCThread(new CThread(this, 1));
}
}
} catch (MIException e) {
throw new CDIException(e.toString());
}
return (ICDIThread[])getCThreads();
} }
/** /**
@ -158,21 +192,21 @@ public class CTarget implements ICDITarget {
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#isStepping() * @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#isStepping()
*/ */
public boolean isStepping() { public boolean isStepping() {
return session.getMISession().getMIProcess().isRunning(); return session.getMISession().getMIInferior().isRunning();
} }
/** /**
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#isSuspended() * @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#isSuspended()
*/ */
public boolean isSuspended() { public boolean isSuspended() {
return session.getMISession().getMIProcess().isSuspended(); return session.getMISession().getMIInferior().isSuspended();
} }
/** /**
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#isTerminated() * @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#isTerminated()
*/ */
public boolean isTerminated() { public boolean isTerminated() {
return session.getMISession().getMIProcess().isTerminated(); return session.getMISession().getMIInferior().isTerminated();
} }
/** /**
@ -198,7 +232,9 @@ public class CTarget implements ICDITarget {
*/ */
public void resume() throws CDIException { public void resume() throws CDIException {
MISession mi = session.getMISession(); MISession mi = session.getMISession();
if (mi.getMIProcess().isSuspended()) { if (mi.getMIInferior().isRunning() || mi.getMIInferior().isStepping()) {
throw new CDIException("Inferior already running");
} else if (mi.getMIInferior().isSuspended()) {
CommandFactory factory = mi.getCommandFactory(); CommandFactory factory = mi.getCommandFactory();
MIExecContinue cont = factory.createMIExecContinue(); MIExecContinue cont = factory.createMIExecContinue();
try { try {
@ -210,8 +246,11 @@ public class CTarget implements ICDITarget {
} catch (MIException e) { } catch (MIException e) {
throw new CDIException(e.toString()); throw new CDIException(e.toString());
} }
} else if (mi.getMIInferior().isTerminated()) {
restart();
} else { } else {
restart(); restart();
//throw new CDIException("Unknow state");
} }
} }
@ -309,7 +348,7 @@ public class CTarget implements ICDITarget {
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#terminate() * @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#terminate()
*/ */
public void terminate() throws CDIException { public void terminate() throws CDIException {
session.getMISession().getMIProcess().destroy(); session.getMISession().getMIInferior().destroy();
} }
/** /**

View file

@ -6,9 +6,9 @@ import org.eclipse.cdt.debug.core.cdi.model.ICDIThread;
import org.eclipse.cdt.debug.mi.core.MIException; import org.eclipse.cdt.debug.mi.core.MIException;
import org.eclipse.cdt.debug.mi.core.MISession; import org.eclipse.cdt.debug.mi.core.MISession;
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.MIStackListFrames; import org.eclipse.cdt.debug.mi.core.command.MIStackListArguments;
import org.eclipse.cdt.debug.mi.core.output.MIFrame; import org.eclipse.cdt.debug.mi.core.output.MIFrame;
import org.eclipse.cdt.debug.mi.core.output.MIStackListFramesInfo; import org.eclipse.cdt.debug.mi.core.output.MIStackListArgumentsInfo;
/** /**
* @author alain * @author alain
@ -32,7 +32,7 @@ public class CThread extends CObject implements ICDIThread {
} }
public String toString() { public String toString() {
return "thread-" + Integer.toString(id); return Integer.toString(id);
} }
/** /**
@ -48,10 +48,12 @@ public class CThread extends CObject implements ICDIThread {
public ICDIStackFrame[] getStackFrames() throws CDIException { public ICDIStackFrame[] getStackFrames() throws CDIException {
MISession mi = getCTarget().getCSession().getMISession(); MISession mi = getCTarget().getCSession().getMISession();
CommandFactory factory = mi.getCommandFactory(); CommandFactory factory = mi.getCommandFactory();
MIStackListFrames frames = factory.createMIStackListFrames(); //MIStackListFrames frames = factory.createMIStackListFrames();
MIStackListArguments frames = factory.createMIStackListArguments(true);
try { try {
mi.postCommand(frames); mi.postCommand(frames);
MIStackListFramesInfo info = frames.getMIStackListFramesInfo(); //MIStackListFramesInfo info = frames.getMIStackListFramesInfo();
MIStackListArgumentsInfo info = frames.getMIStackListArgumentsInfo();
if (info == null) { if (info == null) {
throw new CDIException("Timedout"); throw new CDIException("Timedout");
} }

View file

@ -34,12 +34,10 @@ public class EventManager extends SessionObject implements ICDIEventManager {
public CDIObserver(ICDIEventListener l) { public CDIObserver(ICDIEventListener l) {
listener = l; listener = l;
} }
public void update(Observable o, Object args) { public void update(Observable o, Object arg) {
MIEvent[] events = (MIEvent[])args; MIEvent event = (MIEvent)arg;
for (int i = 0; i < events.length; i++) { ICDIEvent cdiEvent = EventAdapter.getCDIEvent(getCSession(), event);
ICDIEvent cdiEvent = EventAdapter.getCDIEvent(getCSession(), events[i]); listener.handleDebugEvent(cdiEvent);
listener.handleDebugEvent(cdiEvent);
}
} }
} }

View file

@ -34,14 +34,14 @@ public class Variable extends CObject implements ICDIVariable {
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#getTypeName() * @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#getTypeName()
*/ */
public String getTypeName() throws CDIException { public String getTypeName() throws CDIException {
return null; return "";
} }
/** /**
* @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#getValue() * @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#getValue()
*/ */
public ICDIValue getValue() throws CDIException { public ICDIValue getValue() throws CDIException {
return null; return new Value(getCTarget(), arg.getValue());
} }
/** /**

View file

@ -49,6 +49,10 @@ public class MIStackListArguments extends MICommand
setParameters(params); setParameters(params);
} }
public MIStackListArgumentsInfo getMIStackListArgumentsInfo() throws MIException {
return (MIStackListArgumentsInfo)getMIInfo();
}
public MIInfo getMIInfo() throws MIException { public MIInfo getMIInfo() throws MIException {
MIInfo info = null; MIInfo info = null;
MIOutput out = getMIOutput(); MIOutput out = getMIOutput();

View file

@ -25,6 +25,10 @@ public class MIThreadListIds extends MICommand
super("-thread-list-ids"); super("-thread-list-ids");
} }
public MIThreadListIdsInfo getMIThreadListIdsInfo() throws MIException {
return (MIThreadListIdsInfo)getMIInfo();
}
public MIInfo getMIInfo() throws MIException { public MIInfo getMIInfo() throws MIException {
MIInfo info = null; MIInfo info = null;
MIOutput out = getMIOutput(); MIOutput out = getMIOutput();

View file

@ -1,27 +0,0 @@
package org.eclipse.cdt.debug.mi.core.event;
import org.eclipse.cdt.debug.mi.core.MISession;
/*
* (c) Copyright QNX Software Systems Ltd. 2002.
* All Rights Reserved.
*/
public class EventThread extends Thread {
final MISession session;
final MIEvent[] events;
public EventThread(MISession s, MIEvent[] evts) {
super("MI Event Thread");
session = s;
events = evts;
setDaemon(true);
}
/*
*/
public void run () {
session.notifyObservers(events);
}
}

View file

@ -25,61 +25,38 @@ public class MIDataReadMemoryInfo extends MIInfo {
public MIDataReadMemoryInfo(MIOutput rr) { public MIDataReadMemoryInfo(MIOutput rr) {
super(rr); super(rr);
parse();
} }
public long getAddress() { public long getAddress() {
if (memories == null) {
parse();
}
return addr; return addr;
} }
public long getNumberBytes() { public long getNumberBytes() {
if (memories == null) {
parse();
}
return numBytes; return numBytes;
} }
public long getTotalBytes() { public long getTotalBytes() {
if (memories == null) {
parse();
}
return totalBytes; return totalBytes;
} }
public long getNextRow() { public long getNextRow() {
if (memories == null) {
parse();
}
return nextRow; return nextRow;
} }
public long getPreviousRow() { public long getPreviousRow() {
if (memories == null) {
parse();
}
return prevRow; return prevRow;
} }
public long getNextPage() { public long getNextPage() {
if (memories == null) {
parse();
}
return nextPage; return nextPage;
} }
public long getPreviousPage() { public long getPreviousPage() {
if (memories == null) {
parse();
}
return prevPage; return prevPage;
} }
public MIMemory[] getMemories() { public MIMemory[] getMemories() {
if (memories == null) {
parse();
}
return memories; return memories;
} }
/* /*

View file

@ -116,13 +116,13 @@ public class MIParser {
token.delete(0, i); token.delete(0, i);
} }
// Process ResultRecord | Out-Of-Band Records // ResultRecord ||| Out-Of-Band Records
if (token.length() > 0) { if (token.length() > 0) {
if (token.charAt(0) == '^') { if (token.charAt(0) == '^') {
token.deleteCharAt(0); token.deleteCharAt(0);
rr = processMIResultRecord(token, id); rr = processMIResultRecord(token, id);
} else if(token.toString().startsWith(MIOutput.terminator)) { } else if(token.toString().startsWith(MIOutput.terminator)) {
break; //break; // Do nothing.
} else { } else {
MIOOBRecord band = processMIOOBRecord(token, id); MIOOBRecord band = processMIOOBRecord(token, id);
if (band != null) { if (band != null) {
@ -131,15 +131,14 @@ public class MIParser {
} }
} }
} }
MIOOBRecord[] bands = MIOOBRecord[] bands = (MIOOBRecord[]) oobs.toArray(new MIOOBRecord[oobs.size()]);
(MIOOBRecord[]) oobs.toArray(new MIOOBRecord[oobs.size()]);
mi.setMIOOBRecords(bands); mi.setMIOOBRecords(bands);
mi.setMIResultRecord(rr); mi.setMIResultRecord(rr);
return mi; return mi;
} }
/** /**
* Assuming '^' was deleted. * Assuming '^' was deleted from the Result Record.
*/ */
private MIResultRecord processMIResultRecord(StringBuffer buffer, int id) { private MIResultRecord processMIResultRecord(StringBuffer buffer, int id) {
MIResultRecord rr = new MIResultRecord(); MIResultRecord rr = new MIResultRecord();
@ -174,6 +173,7 @@ public class MIParser {
} }
/** /**
* Find OutOfBand Records depending on the starting token.
*/ */
private MIOOBRecord processMIOOBRecord(StringBuffer buffer, int id) { private MIOOBRecord processMIOOBRecord(StringBuffer buffer, int id) {
MIOOBRecord oob = null; MIOOBRecord oob = null;
@ -235,7 +235,8 @@ public class MIParser {
} }
/** /**
* Assuming that the usual leading comma was consume. * Assuming that the usual leading comma was consumed.
* Extract the MI Result comma seperated responses.
*/ */
private MIResult[] processMIResults(StringBuffer buffer) { private MIResult[] processMIResults(StringBuffer buffer) {
List aList = new ArrayList(); List aList = new ArrayList();
@ -255,7 +256,7 @@ public class MIParser {
/** /**
* Construct the MIResult. Characters will be consume/delete * Construct the MIResult. Characters will be consume/delete
* has moving forward constructing the AST. * moving forward constructing the AST.
*/ */
private MIResult processMIResult(StringBuffer buffer) { private MIResult processMIResult(StringBuffer buffer) {
MIResult result = new MIResult(); MIResult result = new MIResult();
@ -353,6 +354,14 @@ public class MIParser {
return list; return list;
} }
/*
* MI C-String rather MICOnst values are enclose in double quotes
* and any double quotes or backslash in the string are escaped.
* Assuming the starting double quote was removed.
* This method will stop at the closing double quote remove the extra
* backslach escaping and return the string __without__ the enclosing double quotes
* The orignal StringBuffer will move forward.
*/
private String translateCString(StringBuffer buffer) { private String translateCString(StringBuffer buffer) {
boolean escape = false; boolean escape = false;
boolean closingQuotes = false; boolean closingQuotes = false;

View file

@ -20,7 +20,7 @@ public class MIStackListArgumentsInfo extends MIInfo {
super(out); super(out);
} }
public MIFrame[] getFrames() { public MIFrame[] getMIFrames() {
if (frames == null) { if (frames == null) {
parse(); parse();
} }

View file

@ -23,7 +23,7 @@ public class MIStackListFramesInfo extends MIInfo {
if (frames == null) { if (frames == null) {
parse(); parse();
} }
return null; return frames;
} }
void parse() { void parse() {

View file

@ -14,19 +14,14 @@ public class MIThreadSelectInfo extends MIInfo {
public MIThreadSelectInfo(MIOutput out) { public MIThreadSelectInfo(MIOutput out) {
super(out); super(out);
parse();
} }
public int getNewThreadId() { public int getNewThreadId() {
if (frame == null) {
parse();
}
return threadId; return threadId;
} }
public MIFrame getFrame() { public MIFrame getFrame() {
if (frame == null) {
parse();
}
return frame; return frame;
} }

View file

@ -15,7 +15,7 @@ import java.util.List;
*/ */
public class MIVarListChildrenInfo extends MIInfo { public class MIVarListChildrenInfo extends MIInfo {
MIChild[] children = new MIChild[0]; MIChild[] children;
int numchild; int numchild;
public MIVarListChildrenInfo(MIOutput record) { public MIVarListChildrenInfo(MIOutput record) {