mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
2004-11-10 Alain Magloire
Fix for PR 51113 and PR 66268 It allow more flexibility in the GDB console, for example when gdb require interactive questions. * mi/org/eclipse/cdt/debug/mi/core/CLIProcessor.java * mi/org/eclipse/cdt/debug/mi/core/MISession.java * mi/org/eclipse/cdt/debug/mi/core/RxThread.java * mi/org/eclipse/cdt/debug/mi/core/SessionProcess.java * mi/org/eclipse/cdt/debug/mi/core/TxThread.java * mi/org/eclipse/cdt/debug/core/command/MIGDBShowPrompt.java * mi/org/eclipse/cdt/debug/core/command/RawCommand.java * mi/org/eclipse/cdt/debug/core/output/MIOutput.java * mi/org/eclipse/cdt/debug/core/output/MIParser.java
This commit is contained in:
parent
c1c8430638
commit
dbd62a6ed4
10 changed files with 218 additions and 18 deletions
|
@ -1,3 +1,18 @@
|
|||
2004-11-10 Alain Magloire
|
||||
Fix for PR 51113 and PR 66268
|
||||
It allow more flexibility in the GDB console, for example
|
||||
when gdb require interactive questions.
|
||||
|
||||
* mi/org/eclipse/cdt/debug/mi/core/CLIProcessor.java
|
||||
* mi/org/eclipse/cdt/debug/mi/core/MISession.java
|
||||
* mi/org/eclipse/cdt/debug/mi/core/RxThread.java
|
||||
* mi/org/eclipse/cdt/debug/mi/core/SessionProcess.java
|
||||
* mi/org/eclipse/cdt/debug/mi/core/TxThread.java
|
||||
* mi/org/eclipse/cdt/debug/core/command/MIGDBShowPrompt.java
|
||||
* mi/org/eclipse/cdt/debug/core/command/RawCommand.java
|
||||
* mi/org/eclipse/cdt/debug/core/output/MIOutput.java
|
||||
* mi/org/eclipse/cdt/debug/core/output/MIParser.java
|
||||
|
||||
2004-11-09 Alain Magloire
|
||||
Throw not implemented exception for exception breakpoint
|
||||
|
||||
|
|
|
@ -35,19 +35,19 @@ public class CLIProcessor {
|
|||
* An attempt to discover the command type and
|
||||
* fire an event if necessary.
|
||||
*/
|
||||
void process(CLICommand cmd) {
|
||||
void processStateChanges(CLICommand cmd) {
|
||||
String operation = cmd.getOperation().trim();
|
||||
process(cmd.getToken(), operation);
|
||||
processStateChanges(cmd.getToken(), operation);
|
||||
}
|
||||
|
||||
void process(MIInterpreterExecConsole exec) {
|
||||
void processStateChanges(MIInterpreterExecConsole exec) {
|
||||
String[] operations = exec.getParameters();
|
||||
if (operations != null && operations.length > 0) {
|
||||
process(exec.getToken(), operations[0]);
|
||||
processStateChanges(exec.getToken(), operations[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void process(int token, String operation) {
|
||||
void processStateChanges(int token, String operation) {
|
||||
// Get the command name.
|
||||
int indx = operation.indexOf(' ');
|
||||
if (indx != -1) {
|
||||
|
@ -64,10 +64,40 @@ public class CLIProcessor {
|
|||
session.getMIInferior().setRunning();
|
||||
MIEvent event = new MIRunningEvent(session, token, type);
|
||||
session.fireEvent(event);
|
||||
} else if (isSettingBreakpoint(operation) ||
|
||||
isSettingWatchpoint(operation) ||
|
||||
isChangeBreakpoint(operation) ||
|
||||
isDeletingBreakpoint(operation)) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An attempt to discover the command type and
|
||||
* fire an event if necessary.
|
||||
*/
|
||||
void processSettingChanges(CLICommand cmd) {
|
||||
String operation = cmd.getOperation().trim();
|
||||
processSettingChanges(cmd.getToken(), operation);
|
||||
}
|
||||
|
||||
void processSettingChanges(MIInterpreterExecConsole exec) {
|
||||
String[] operations = exec.getParameters();
|
||||
if (operations != null && operations.length > 0) {
|
||||
processSettingChanges(exec.getToken(), operations[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void processSettingChanges(int token, String operation) {
|
||||
// Get the command name.
|
||||
int indx = operation.indexOf(' ');
|
||||
if (indx != -1) {
|
||||
operation = operation.substring(0, indx).trim();
|
||||
} else {
|
||||
operation = operation.trim();
|
||||
}
|
||||
|
||||
// Check the type of command
|
||||
|
||||
if (isSettingBreakpoint(operation) ||
|
||||
isSettingWatchpoint(operation) ||
|
||||
isChangeBreakpoint(operation) ||
|
||||
isDeletingBreakpoint(operation)) {
|
||||
// We know something change, we just do not know what.
|
||||
// So the easiest way is to let the top layer handle it.
|
||||
session.fireEvent(new MIBreakpointChangedEvent(session, 0));
|
||||
|
|
|
@ -24,9 +24,11 @@ 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.MIGDBShowPrompt;
|
||||
import org.eclipse.cdt.debug.mi.core.command.MIInterpreterExecConsole;
|
||||
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;
|
||||
|
||||
|
@ -157,6 +159,7 @@ public class MISession extends Observable {
|
|||
postCommand(height, launchTimeout);
|
||||
height.getMIInfo();
|
||||
|
||||
// Try to discover is "-interpreter-exec" is supported.
|
||||
try {
|
||||
MIInterpreterExecConsole echo = new MIInterpreterExecConsole("echo"); //$NON-NLS-1$
|
||||
postCommand(echo, launchTimeout);
|
||||
|
@ -166,6 +169,14 @@ public class MISession extends Observable {
|
|||
//
|
||||
}
|
||||
|
||||
// Get GDB's prompt
|
||||
MIGDBShowPrompt prompt = new MIGDBShowPrompt();
|
||||
postCommand(prompt);
|
||||
MIGDBShowInfo infoPrompt = prompt.getMIGDBShowInfo();
|
||||
String value = infoPrompt.getValue();
|
||||
if (value != null && value.length() > 0) {
|
||||
parser.primaryPrompt = value.trim();
|
||||
}
|
||||
} catch (MIException exc) {
|
||||
// Kill the Transmition thread.
|
||||
if (txThread.isAlive()) {
|
||||
|
@ -258,9 +269,17 @@ public class MISession extends Observable {
|
|||
}
|
||||
|
||||
public boolean useExecConsole() {
|
||||
return useInterpreterExecConsole;
|
||||
return false;
|
||||
//return useInterpreterExecConsole;
|
||||
}
|
||||
|
||||
public boolean inPrimaryPrompt() {
|
||||
return rxThread.inPrimaryPrompt();
|
||||
}
|
||||
|
||||
public boolean inSecondaryPrompt() {
|
||||
return rxThread.inSecondaryPrompt();
|
||||
}
|
||||
/**
|
||||
* The debug session is a program being debug.
|
||||
*/
|
||||
|
@ -306,6 +325,8 @@ public class MISession extends Observable {
|
|||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
|
@ -329,12 +350,24 @@ public class MISession extends Observable {
|
|||
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;
|
||||
MIPlugin.getDefault().debugLog(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
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.io.OutputStream;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.debug.mi.core.command.CLICommand;
|
||||
import org.eclipse.cdt.debug.mi.core.command.Command;
|
||||
import org.eclipse.cdt.debug.mi.core.command.MIExecContinue;
|
||||
import org.eclipse.cdt.debug.mi.core.command.MIExecFinish;
|
||||
|
@ -26,6 +27,7 @@ import org.eclipse.cdt.debug.mi.core.command.MIExecReturn;
|
|||
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.MIExecUntil;
|
||||
import org.eclipse.cdt.debug.mi.core.command.MIInterpreterExecConsole;
|
||||
import org.eclipse.cdt.debug.mi.core.event.MIBreakpointHitEvent;
|
||||
import org.eclipse.cdt.debug.mi.core.event.MIErrorEvent;
|
||||
import org.eclipse.cdt.debug.mi.core.event.MIEvent;
|
||||
|
@ -48,6 +50,7 @@ import org.eclipse.cdt.debug.mi.core.output.MILogStreamOutput;
|
|||
import org.eclipse.cdt.debug.mi.core.output.MINotifyAsyncOutput;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIOOBRecord;
|
||||
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.MIResult;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIResultRecord;
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIStatusAsyncOutput;
|
||||
|
@ -62,10 +65,13 @@ public class RxThread extends Thread {
|
|||
|
||||
final MISession session;
|
||||
List oobList;
|
||||
CLIProcessor cli;
|
||||
int prompt = 1; // 1 --> Primary prompt "(gdb)"; 2 --> Secondary Prompt ">"
|
||||
|
||||
public RxThread(MISession s) {
|
||||
super("MI RX Thread"); //$NON-NLS-1$
|
||||
session = s;
|
||||
cli = new CLIProcessor(session);
|
||||
oobList = new ArrayList();
|
||||
}
|
||||
|
||||
|
@ -80,6 +86,7 @@ public class RxThread extends Thread {
|
|||
while ((line = reader.readLine()) != null) {
|
||||
// TRACING: print the output.
|
||||
MIPlugin.getDefault().debugLog(line);
|
||||
setPrompt(line);
|
||||
processMIOutput(line + "\n"); //$NON-NLS-1$
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@ -113,6 +120,26 @@ public class RxThread extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
void setPrompt(String line) {
|
||||
line = line.trim();
|
||||
MIParser parser = session.getMIParser();
|
||||
if (line.equals(parser.primaryPrompt)) {
|
||||
prompt = 1;
|
||||
} else if (line.equals(parser.secondaryPrompt)) {
|
||||
prompt = 2;
|
||||
} else {
|
||||
prompt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean inPrimaryPrompt() {
|
||||
return prompt == 1;
|
||||
}
|
||||
|
||||
public boolean inSecondaryPrompt() {
|
||||
return prompt == 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the command in the RxQueue, set the MIOutput
|
||||
* and notify() the other end.
|
||||
|
@ -184,6 +211,13 @@ public class RxThread extends Thread {
|
|||
|
||||
// Notify the waiting command.
|
||||
if (cmd != null) {
|
||||
// Process the Command line to recognise patterns we may need to fire event.
|
||||
if (cmd instanceof CLICommand) {
|
||||
cli.processSettingChanges((CLICommand)cmd);
|
||||
} else if (cmd instanceof MIInterpreterExecConsole) {
|
||||
cli.processSettingChanges((MIInterpreterExecConsole)cmd);
|
||||
}
|
||||
|
||||
synchronized (cmd) {
|
||||
// Set the accumulate console Stream
|
||||
response.setMIOOBRecords(oobRecords);
|
||||
|
@ -283,6 +317,8 @@ public class RxThread extends Thread {
|
|||
if (console != null) {
|
||||
MIConsoleStreamOutput out = (MIConsoleStreamOutput) stream;
|
||||
String str = out.getString();
|
||||
// Process the console stream too.
|
||||
setPrompt(str);
|
||||
if (str != null) {
|
||||
try {
|
||||
console.write(str.getBytes());
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.io.OutputStream;
|
|||
import org.eclipse.cdt.debug.mi.core.command.CLICommand;
|
||||
import org.eclipse.cdt.debug.mi.core.command.Command;
|
||||
import org.eclipse.cdt.debug.mi.core.command.MIInterpreterExecConsole;
|
||||
import org.eclipse.cdt.debug.mi.core.command.RawCommand;
|
||||
|
||||
/**
|
||||
*/
|
||||
|
@ -78,15 +79,26 @@ public class SessionProcess extends Process {
|
|||
String str = buf.toString().trim();
|
||||
buf.setLength(0);
|
||||
Command cmd = null;
|
||||
// 1-
|
||||
// if We have the secondary prompt it means
|
||||
// that GDB is waiting for more feedback, use a RawCommand
|
||||
// 2-
|
||||
// Do not use the interpreterexec for stepping operation
|
||||
// the UI will fall out of step.
|
||||
if (session.useExecConsole() && str.length() > 0 && !CLIProcessor.isSteppingOperation(str)) {
|
||||
// 3-
|
||||
// Normal Command Line Interface.
|
||||
boolean secondary = session.inSecondaryPrompt();
|
||||
if (secondary) {
|
||||
cmd = new RawCommand(str);
|
||||
} else if (session.useExecConsole() && str.length() > 0
|
||||
&& !CLIProcessor.isSteppingOperation(str)) {
|
||||
cmd = new MIInterpreterExecConsole(str);
|
||||
} else {
|
||||
cmd = new CLICommand(str);
|
||||
}
|
||||
try {
|
||||
session.postCommand(cmd);
|
||||
// Do not wait around for the answer.
|
||||
session.postCommand(cmd, -1);
|
||||
} catch (MIException e) {
|
||||
//e.printStackTrace();
|
||||
throw new IOException(e.getMessage());
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.io.OutputStream;
|
|||
import org.eclipse.cdt.debug.mi.core.command.CLICommand;
|
||||
import org.eclipse.cdt.debug.mi.core.command.Command;
|
||||
import org.eclipse.cdt.debug.mi.core.command.MIInterpreterExecConsole;
|
||||
import org.eclipse.cdt.debug.mi.core.command.RawCommand;
|
||||
|
||||
/**
|
||||
* Transmission command thread blocks on the command Queue
|
||||
|
@ -35,6 +36,8 @@ public class TxThread extends Thread {
|
|||
|
||||
public void run () {
|
||||
try {
|
||||
RxThread rxThread = session.getRxThread();
|
||||
|
||||
// signal by the session of time to die.
|
||||
OutputStream out;
|
||||
while ((out = session.getChannelOutputStream()) != null) {
|
||||
|
@ -53,7 +56,7 @@ public class TxThread extends Thread {
|
|||
if (str.length() > 0) {
|
||||
// Move to the RxQueue only if RxThread is alive.
|
||||
Thread rx = session.getRxThread();
|
||||
if (rx != null && rx.isAlive()) {
|
||||
if (rx != null && rx.isAlive() && !(cmd instanceof RawCommand)) {
|
||||
CommandQueue rxQueue = session.getRxQueue();
|
||||
rxQueue.addCommand(cmd);
|
||||
} else {
|
||||
|
@ -65,11 +68,11 @@ public class TxThread extends Thread {
|
|||
|
||||
// Process the Command line to recognise patterns we may need to fire event.
|
||||
if (cmd instanceof CLICommand) {
|
||||
cli.process((CLICommand)cmd);
|
||||
cli.processStateChanges((CLICommand)cmd);
|
||||
} else if (cmd instanceof MIInterpreterExecConsole) {
|
||||
cli.process((MIInterpreterExecConsole)cmd);
|
||||
cli.processStateChanges((MIInterpreterExecConsole)cmd);
|
||||
}
|
||||
|
||||
|
||||
// shove in the pipe
|
||||
if (out != null) {
|
||||
out.write(str.getBytes());
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2004 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.mi.core.command;
|
||||
|
||||
/**
|
||||
* -gdb-show prompt
|
||||
*/
|
||||
public class MIGDBShowPrompt extends MIGDBShow {
|
||||
|
||||
/**
|
||||
* @param params
|
||||
*/
|
||||
public MIGDBShowPrompt() {
|
||||
super(new String[] { "prompt" }); //$NON-NLS-1$
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2004 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.debug.mi.core.command;
|
||||
|
||||
import org.eclipse.cdt.debug.mi.core.output.MIOutput;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class RawCommand extends Command {
|
||||
|
||||
String fRaw;
|
||||
|
||||
public RawCommand(String operation) {
|
||||
fRaw = operation;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
if (fRaw == null) {
|
||||
fRaw = "\n"; //$NON-NLS-1$;
|
||||
} else if (! fRaw.endsWith("\n")) {
|
||||
fRaw += "\n"; //$NON-NLS-1$
|
||||
}
|
||||
return fRaw;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.debug.mi.core.command.Command#getMIOutput()
|
||||
*/
|
||||
public MIOutput getMIOutput() {
|
||||
return new MIOutput();
|
||||
}
|
||||
}
|
|
@ -15,7 +15,6 @@ package org.eclipse.cdt.debug.mi.core.output;
|
|||
*/
|
||||
public class MIOutput {
|
||||
|
||||
public static final String terminator = "(gdb)"; //$NON-NLS-1$
|
||||
public static final MIOOBRecord[] nullOOBRecord = new MIOOBRecord[0];
|
||||
MIResultRecord rr = null;
|
||||
MIOOBRecord[] oobs = nullOOBRecord;
|
||||
|
|
|
@ -90,6 +90,9 @@ import java.util.StringTokenizer;
|
|||
*/
|
||||
public class MIParser {
|
||||
|
||||
public String primaryPrompt = "(gdb)"; //$NON-NLS-1$
|
||||
public String secondaryPrompt = ">"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Point of entry to create an AST for MI.
|
||||
*
|
||||
|
@ -127,7 +130,7 @@ public class MIParser {
|
|||
if (token.charAt(0) == '^') {
|
||||
token.deleteCharAt(0);
|
||||
rr = processMIResultRecord(token, id);
|
||||
} else if (token.toString().startsWith(MIOutput.terminator)) {
|
||||
} else if (token.toString().startsWith(primaryPrompt)) {
|
||||
//break; // Do nothing.
|
||||
} else {
|
||||
MIOOBRecord band = processMIOOBRecord(token, id);
|
||||
|
|
Loading…
Add table
Reference in a new issue