1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 09:46:02 +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 2004-11-09 Alain Magloire
Throw not implemented exception for exception breakpoint Throw not implemented exception for exception breakpoint

View file

@ -35,19 +35,19 @@ public class CLIProcessor {
* An attempt to discover the command type and * An attempt to discover the command type and
* fire an event if necessary. * fire an event if necessary.
*/ */
void process(CLICommand cmd) { void processStateChanges(CLICommand cmd) {
String operation = cmd.getOperation().trim(); 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(); String[] operations = exec.getParameters();
if (operations != null && operations.length > 0) { 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. // Get the command name.
int indx = operation.indexOf(' '); int indx = operation.indexOf(' ');
if (indx != -1) { if (indx != -1) {
@ -64,7 +64,37 @@ public class CLIProcessor {
session.getMIInferior().setRunning(); session.getMIInferior().setRunning();
MIEvent event = new MIRunningEvent(session, token, type); MIEvent event = new MIRunningEvent(session, token, type);
session.fireEvent(event); session.fireEvent(event);
} else if (isSettingBreakpoint(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) || isSettingWatchpoint(operation) ||
isChangeBreakpoint(operation) || isChangeBreakpoint(operation) ||
isDeletingBreakpoint(operation)) { isDeletingBreakpoint(operation)) {

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.MIExecInterrupt;
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.command.MIGDBShowPrompt;
import org.eclipse.cdt.debug.mi.core.command.MIInterpreterExecConsole; 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.MIEvent;
import org.eclipse.cdt.debug.mi.core.event.MIGDBExitEvent; 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.MIOutput;
import org.eclipse.cdt.debug.mi.core.output.MIParser; import org.eclipse.cdt.debug.mi.core.output.MIParser;
@ -157,6 +159,7 @@ public class MISession extends Observable {
postCommand(height, launchTimeout); postCommand(height, launchTimeout);
height.getMIInfo(); height.getMIInfo();
// Try to discover is "-interpreter-exec" is supported.
try { try {
MIInterpreterExecConsole echo = new MIInterpreterExecConsole("echo"); //$NON-NLS-1$ MIInterpreterExecConsole echo = new MIInterpreterExecConsole("echo"); //$NON-NLS-1$
postCommand(echo, launchTimeout); 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) { } catch (MIException exc) {
// Kill the Transmition thread. // Kill the Transmition thread.
if (txThread.isAlive()) { if (txThread.isAlive()) {
@ -258,9 +269,17 @@ public class MISession extends Observable {
} }
public boolean useExecConsole() { 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. * 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. * 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 { public void postCommand(Command cmd, long timeout) throws MIException {
@ -329,12 +350,24 @@ public class MISession extends Observable {
postCommand0(cmd, timeout); 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 { public synchronized void postCommand0(Command cmd, long timeout) throws MIException {
// TRACING: print the command; // TRACING: print the command;
MIPlugin.getDefault().debugLog(cmd.toString()); MIPlugin.getDefault().debugLog(cmd.toString());
txQueue.addCommand(cmd); txQueue.addCommand(cmd);
// do not wait around the answer.
if (timeout < 0) {
return;
}
// Wait for the response or timedout // Wait for the response or timedout
synchronized (cmd) { synchronized (cmd) {
// RxThread will set the MIOutput on the 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.ArrayList;
import java.util.List; 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.Command;
import org.eclipse.cdt.debug.mi.core.command.MIExecContinue; import org.eclipse.cdt.debug.mi.core.command.MIExecContinue;
import org.eclipse.cdt.debug.mi.core.command.MIExecFinish; 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.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.command.MIInterpreterExecConsole;
import org.eclipse.cdt.debug.mi.core.event.MIBreakpointHitEvent; 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.MIErrorEvent;
import org.eclipse.cdt.debug.mi.core.event.MIEvent; 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.MINotifyAsyncOutput;
import org.eclipse.cdt.debug.mi.core.output.MIOOBRecord; 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.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.MIResult;
import org.eclipse.cdt.debug.mi.core.output.MIResultRecord; import org.eclipse.cdt.debug.mi.core.output.MIResultRecord;
import org.eclipse.cdt.debug.mi.core.output.MIStatusAsyncOutput; import org.eclipse.cdt.debug.mi.core.output.MIStatusAsyncOutput;
@ -62,10 +65,13 @@ public class RxThread extends Thread {
final MISession session; final MISession session;
List oobList; List oobList;
CLIProcessor cli;
int prompt = 1; // 1 --> Primary prompt "(gdb)"; 2 --> Secondary Prompt ">"
public RxThread(MISession s) { public RxThread(MISession s) {
super("MI RX Thread"); //$NON-NLS-1$ super("MI RX Thread"); //$NON-NLS-1$
session = s; session = s;
cli = new CLIProcessor(session);
oobList = new ArrayList(); oobList = new ArrayList();
} }
@ -80,6 +86,7 @@ public class RxThread extends Thread {
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
// TRACING: print the output. // TRACING: print the output.
MIPlugin.getDefault().debugLog(line); MIPlugin.getDefault().debugLog(line);
setPrompt(line);
processMIOutput(line + "\n"); //$NON-NLS-1$ processMIOutput(line + "\n"); //$NON-NLS-1$
} }
} catch (IOException e) { } 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 * Search for the command in the RxQueue, set the MIOutput
* and notify() the other end. * and notify() the other end.
@ -184,6 +211,13 @@ public class RxThread extends Thread {
// Notify the waiting command. // Notify the waiting command.
if (cmd != null) { 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) { synchronized (cmd) {
// Set the accumulate console Stream // Set the accumulate console Stream
response.setMIOOBRecords(oobRecords); response.setMIOOBRecords(oobRecords);
@ -283,6 +317,8 @@ public class RxThread extends Thread {
if (console != null) { if (console != null) {
MIConsoleStreamOutput out = (MIConsoleStreamOutput) stream; MIConsoleStreamOutput out = (MIConsoleStreamOutput) stream;
String str = out.getString(); String str = out.getString();
// Process the console stream too.
setPrompt(str);
if (str != null) { if (str != null) {
try { try {
console.write(str.getBytes()); 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.CLICommand;
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.MIInterpreterExecConsole; 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(); String str = buf.toString().trim();
buf.setLength(0); buf.setLength(0);
Command cmd = null; 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 // Do not use the interpreterexec for stepping operation
// the UI will fall out of step. // 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); cmd = new MIInterpreterExecConsole(str);
} else { } else {
cmd = new CLICommand(str); cmd = new CLICommand(str);
} }
try { try {
session.postCommand(cmd); // Do not wait around for the answer.
session.postCommand(cmd, -1);
} catch (MIException e) { } catch (MIException e) {
//e.printStackTrace(); //e.printStackTrace();
throw new IOException(e.getMessage()); 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.CLICommand;
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.MIInterpreterExecConsole; 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 * Transmission command thread blocks on the command Queue
@ -35,6 +36,8 @@ public class TxThread extends Thread {
public void run () { public void run () {
try { try {
RxThread rxThread = session.getRxThread();
// signal by the session of time to die. // signal by the session of time to die.
OutputStream out; OutputStream out;
while ((out = session.getChannelOutputStream()) != null) { while ((out = session.getChannelOutputStream()) != null) {
@ -53,7 +56,7 @@ public class TxThread extends Thread {
if (str.length() > 0) { if (str.length() > 0) {
// Move to the RxQueue only if RxThread is alive. // Move to the RxQueue only if RxThread is alive.
Thread rx = session.getRxThread(); Thread rx = session.getRxThread();
if (rx != null && rx.isAlive()) { if (rx != null && rx.isAlive() && !(cmd instanceof RawCommand)) {
CommandQueue rxQueue = session.getRxQueue(); CommandQueue rxQueue = session.getRxQueue();
rxQueue.addCommand(cmd); rxQueue.addCommand(cmd);
} else { } else {
@ -65,9 +68,9 @@ public class TxThread extends Thread {
// Process the Command line to recognise patterns we may need to fire event. // Process the Command line to recognise patterns we may need to fire event.
if (cmd instanceof CLICommand) { if (cmd instanceof CLICommand) {
cli.process((CLICommand)cmd); cli.processStateChanges((CLICommand)cmd);
} else if (cmd instanceof MIInterpreterExecConsole) { } else if (cmd instanceof MIInterpreterExecConsole) {
cli.process((MIInterpreterExecConsole)cmd); cli.processStateChanges((MIInterpreterExecConsole)cmd);
} }
// shove in the pipe // shove in the pipe

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 class MIOutput {
public static final String terminator = "(gdb)"; //$NON-NLS-1$
public static final MIOOBRecord[] nullOOBRecord = new MIOOBRecord[0]; public static final MIOOBRecord[] nullOOBRecord = new MIOOBRecord[0];
MIResultRecord rr = null; MIResultRecord rr = null;
MIOOBRecord[] oobs = nullOOBRecord; MIOOBRecord[] oobs = nullOOBRecord;

View file

@ -90,6 +90,9 @@ import java.util.StringTokenizer;
*/ */
public class MIParser { 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. * Point of entry to create an AST for MI.
* *
@ -127,7 +130,7 @@ public class MIParser {
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(primaryPrompt)) {
//break; // Do nothing. //break; // Do nothing.
} else { } else {
MIOOBRecord band = processMIOOBRecord(token, id); MIOOBRecord band = processMIOOBRecord(token, id);