1
0
Fork 0
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:
Alain Magloire 2004-11-11 03:02:58 +00:00
parent c1c8430638
commit dbd62a6ed4
10 changed files with 218 additions and 18 deletions

View file

@ -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

View file

@ -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));

View file

@ -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

View file

@ -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());

View file

@ -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());

View file

@ -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());

View file

@ -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$
}
}

View file

@ -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();
}
}

View file

@ -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;

View file

@ -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);