Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor.java')
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor.java637
1 files changed, 328 insertions, 309 deletions
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor.java
index 477b1c229b9..a2ce531140e 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/MIRunControlEventProcessor.java
@@ -7,10 +7,10 @@
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
- *
+ *
* Contributors:
* Wind River Systems - initial API and implementation
- * Ericsson - Additional handling of events
+ * Ericsson - Additional handling of events
* Mikhail Khodjaiants (Mentor Graphics) - Refactor common code in GDBControl* classes (bug 372795)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command;
@@ -77,107 +77,106 @@ import org.eclipse.cdt.dsf.service.DsfServicesTracker;
* generates corresponding MI events. The generated MI events are then
* received by other services and clients.
*/
-public class MIRunControlEventProcessor
- implements IEventProcessor
-{
+public class MIRunControlEventProcessor implements IEventProcessor {
private static final String STOPPED_REASON = "stopped"; //$NON-NLS-1$
-
+
+ /**
+ * The connection service that this event processor is registered with.
+ */
+ private final AbstractMIControl fCommandControl;
+
/**
- * The connection service that this event processor is registered with.
- */
- private final AbstractMIControl fCommandControl;
-
- /**
- * Container context used as the context for the run control events generated
- * by this processor.
- */
- private final ICommandControlDMContext fControlDmc;
-
- private final DsfServicesTracker fServicesTracker;
-
- /**
- * Creates the event processor and registers it as listener with the debugger
- * control.
- * @param connection
- * @param inferior
- * @since 1.1
- */
- public MIRunControlEventProcessor(AbstractMIControl connection, ICommandControlDMContext controlDmc) {
- fCommandControl = connection;
- fControlDmc = controlDmc;
- fServicesTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fCommandControl.getSession().getId());
- connection.addEventListener(this);
- connection.addCommandListener(this);
- }
-
- /**
- * This processor must be disposed before the control service is un-registered.
- */
- @Override
- public void dispose() {
- fCommandControl.removeEventListener(this);
- fCommandControl.removeCommandListener(this);
- fServicesTracker.dispose();
- }
-
+ * Container context used as the context for the run control events generated
+ * by this processor.
+ */
+ private final ICommandControlDMContext fControlDmc;
+
+ private final DsfServicesTracker fServicesTracker;
+
+ /**
+ * Creates the event processor and registers it as listener with the debugger
+ * control.
+ * @param connection
+ * @param inferior
+ * @since 1.1
+ */
+ public MIRunControlEventProcessor(AbstractMIControl connection, ICommandControlDMContext controlDmc) {
+ fCommandControl = connection;
+ fControlDmc = controlDmc;
+ fServicesTracker = new DsfServicesTracker(GdbPlugin.getBundleContext(), fCommandControl.getSession().getId());
+ connection.addEventListener(this);
+ connection.addCommandListener(this);
+ }
+
+ /**
+ * This processor must be disposed before the control service is un-registered.
+ */
+ @Override
+ public void dispose() {
+ fCommandControl.removeEventListener(this);
+ fCommandControl.removeCommandListener(this);
+ fServicesTracker.dispose();
+ }
+
@Override
- public void eventReceived(Object output) {
- for (MIOOBRecord oobr : ((MIOutput)output).getMIOOBRecords()) {
+ public void eventReceived(Object output) {
+ for (MIOOBRecord oobr : ((MIOutput) output).getMIOOBRecords()) {
List<MIEvent<?>> events = new LinkedList<MIEvent<?>>();
- if (oobr instanceof MIExecAsyncOutput) {
- MIExecAsyncOutput exec = (MIExecAsyncOutput) oobr;
- // Change of state.
- String state = exec.getAsyncClass();
- if ("stopped".equals(state)) { //$NON-NLS-1$
- // Re-set the thread and stack level to -1 when stopped event is recvd.
- // This is to synchronize the state between GDB back-end and AbstractMIControl.
- fCommandControl.resetCurrentThreadLevel();
- fCommandControl.resetCurrentStackLevel();
-
- MIResult[] results = exec.getMIResults();
- for (int i = 0; i < results.length; i++) {
- String var = results[i].getVariable();
- MIValue val = results[i].getMIValue();
- if (var.equals("reason")) { //$NON-NLS-1$
- if (val instanceof MIConst) {
- String reason = ((MIConst) val).getString();
- MIEvent<?> e = createEvent(reason, exec);
- if (e != null) {
- events.add(e);
- continue;
- }
- }
- }
- }
-
+ if (oobr instanceof MIExecAsyncOutput) {
+ MIExecAsyncOutput exec = (MIExecAsyncOutput) oobr;
+ // Change of state.
+ String state = exec.getAsyncClass();
+ if ("stopped".equals(state)) { //$NON-NLS-1$
+ // Re-set the thread and stack level to -1 when stopped event is recvd.
+ // This is to synchronize the state between GDB back-end and AbstractMIControl.
+ fCommandControl.resetCurrentThreadLevel();
+ fCommandControl.resetCurrentStackLevel();
+
+ MIResult[] results = exec.getMIResults();
+ for (int i = 0; i < results.length; i++) {
+ String var = results[i].getVariable();
+ MIValue val = results[i].getMIValue();
+ if (var.equals("reason")) { //$NON-NLS-1$
+ if (val instanceof MIConst) {
+ String reason = ((MIConst) val).getString();
+ MIEvent<?> e = createEvent(reason, exec);
+ if (e != null) {
+ events.add(e);
+ continue;
+ }
+ }
+ }
+ }
+
// GDB < 7.0 does not provide a reason when stopping on a
// catchpoint. However, the reason is contained in the
// stream records that precede the exec async output one.
// This is ugly, but we don't really have an alternative.
- if (events.isEmpty()) {
- MIStreamRecord[] streamRecords = ((MIOutput)output).getStreamRecords();
- for (MIStreamRecord streamRecord : streamRecords) {
- String log = streamRecord.getString();
- if (log.startsWith("Catchpoint ")) { //$NON-NLS-1$
- events.add(MICatchpointHitEvent.parse(getExecutionContext(exec), exec.getToken(), results, streamRecord));
- }
- }
- }
-
- // We were stopped for some unknown reason, for example
- // GDB for temporary breakpoints will not send the
- // "reason" ??? still fire a stopped event.
- if (events.isEmpty()) {
- MIEvent<?> e = createEvent(STOPPED_REASON, exec);
+ if (events.isEmpty()) {
+ MIStreamRecord[] streamRecords = ((MIOutput) output).getStreamRecords();
+ for (MIStreamRecord streamRecord : streamRecords) {
+ String log = streamRecord.getString();
+ if (log.startsWith("Catchpoint ")) { //$NON-NLS-1$
+ events.add(MICatchpointHitEvent.parse(getExecutionContext(exec), exec.getToken(),
+ results, streamRecord));
+ }
+ }
+ }
+
+ // We were stopped for some unknown reason, for example
+ // GDB for temporary breakpoints will not send the
+ // "reason" ??? still fire a stopped event.
+ if (events.isEmpty()) {
+ MIEvent<?> e = createEvent(STOPPED_REASON, exec);
if (e != null) {
events.add(e);
}
- }
+ }
- for (MIEvent<?> event : events) {
- fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
- }
- }
+ for (MIEvent<?> event : events) {
+ fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
+ }
+ }
} else if (oobr instanceof MIConsoleStreamOutput) {
MIConsoleStreamOutput stream = (MIConsoleStreamOutput) oobr;
if (stream.getCString().startsWith("Program terminated with signal")) {//$NON-NLS-1$
@@ -210,232 +209,252 @@ public class MIRunControlEventProcessor
fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
}
}
- }
- }
-
- // Now check for a oob command result. This happens on Windows when interrupting GDB.
- // In this case, GDB before 7.0 does not always send a *stopped event, so we must do it ourselves
- // Bug 304096 (if you have the patience to go through it :-))
- MIResultRecord rr = ((MIOutput)output).getMIResultRecord();
- if (rr != null) {
- int id = rr.getToken();
- String state = rr.getResultClass();
- if ("error".equals(state)) { //$NON-NLS-1$
-
- MIResult[] results = rr.getMIResults();
- for (int i = 0; i < results.length; i++) {
- String var = results[i].getVariable();
- MIValue val = results[i].getMIValue();
- if (var.equals("msg")) { //$NON-NLS-1$
- if (val instanceof MIConst) {
- String message = ((MIConst) val).getString();
- if (message.toLowerCase().startsWith("quit")) { //$NON-NLS-1$
- IRunControl runControl = fServicesTracker.getService(IRunControl.class);
- IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
- if (runControl != null && procService != null) {
- // We don't know which thread stopped so we simply create a container event.
- IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
-
- if (runControl.isSuspended(processContainerDmc) == false) {
- // Create an MISignalEvent because that is what the *stopped event should have been
- MIEvent<?> event = MISignalEvent.parse(processContainerDmc, id, rr.getMIResults());
- fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
- }
- }
- }
- }
- }
- }
- }
- }
- }
+ }
+ }
+
+ // Now check for a oob command result. This happens on Windows when interrupting GDB.
+ // In this case, GDB before 7.0 does not always send a *stopped event, so we must do it ourselves
+ // Bug 304096 (if you have the patience to go through it :-))
+ MIResultRecord rr = ((MIOutput) output).getMIResultRecord();
+ if (rr != null) {
+ int id = rr.getToken();
+ String state = rr.getResultClass();
+ if ("error".equals(state)) { //$NON-NLS-1$
+
+ MIResult[] results = rr.getMIResults();
+ for (int i = 0; i < results.length; i++) {
+ String var = results[i].getVariable();
+ MIValue val = results[i].getMIValue();
+ if (var.equals("msg")) { //$NON-NLS-1$
+ if (val instanceof MIConst) {
+ String message = ((MIConst) val).getString();
+ if (message.toLowerCase().startsWith("quit")) { //$NON-NLS-1$
+ IRunControl runControl = fServicesTracker.getService(IRunControl.class);
+ IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
+ if (runControl != null && procService != null) {
+ // We don't know which thread stopped so we simply create a container event.
+ IContainerDMContext processContainerDmc = procService
+ .createContainerContextFromGroupId(fControlDmc,
+ MIProcesses.UNIQUE_GROUP_ID);
+
+ if (runControl.isSuspended(processContainerDmc) == false) {
+ // Create an MISignalEvent because that is what the *stopped event should have been
+ MIEvent<?> event = MISignalEvent.parse(processContainerDmc, id,
+ rr.getMIResults());
+ fCommandControl.getSession().dispatchEvent(event,
+ fCommandControl.getProperties());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
/**
- * Create an execution context given an exec-async-output OOB record
- *
+ * Create an execution context given an exec-async-output OOB record
+ *
* @since 3.0
*/
- protected IExecutionDMContext getExecutionContext(MIExecAsyncOutput exec) {
- String threadId = null;
-
- MIResult[] results = exec.getMIResults();
- for (int i = 0; i < results.length; i++) {
- String var = results[i].getVariable();
- MIValue val = results[i].getMIValue();
-
- if (var.equals("thread-id")) { //$NON-NLS-1$
- if (val instanceof MIConst) {
- threadId = ((MIConst)val).getString();
- }
- }
- }
-
- IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
- if (procService == null) {
- return null;
- }
-
- IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
-
- IExecutionDMContext execDmc = processContainerDmc;
- if (threadId != null) {
- IProcessDMContext procDmc = DMContexts.getAncestorOfType(processContainerDmc, IProcessDMContext.class);
- IThreadDMContext threadDmc = procService.createThreadContext(procDmc, threadId);
- execDmc = procService.createExecutionContext(processContainerDmc, threadDmc, threadId);
- }
-
- return execDmc;
- }
-
- @ConfinedToDsfExecutor("")
- protected MIEvent<?> createEvent(String reason, MIExecAsyncOutput exec) {
- IExecutionDMContext execDmc = getExecutionContext(exec);
- MIEvent<?> event = null;
- if ("breakpoint-hit".equals(reason)) { //$NON-NLS-1$
- event = MIBreakpointHitEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
- } else if (
- "watchpoint-trigger".equals(reason) //$NON-NLS-1$
- || "read-watchpoint-trigger".equals(reason) //$NON-NLS-1$
- || "access-watchpoint-trigger".equals(reason)) { //$NON-NLS-1$
- event = MIWatchpointTriggerEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
- } else if ("watchpoint-scope".equals(reason)) { //$NON-NLS-1$
- event = MIWatchpointScopeEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
- } else if ("end-stepping-range".equals(reason)) { //$NON-NLS-1$
- event = MISteppingRangeEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
- } else if ("signal-received".equals(reason)) { //$NON-NLS-1$
- event = MISignalEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
- } else if ("location-reached".equals(reason)) { //$NON-NLS-1$
- event = MILocationReachedEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
- } else if ("function-finished".equals(reason)) { //$NON-NLS-1$
- event = MIFunctionFinishedEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
+ protected IExecutionDMContext getExecutionContext(MIExecAsyncOutput exec) {
+ String threadId = null;
+
+ MIResult[] results = exec.getMIResults();
+ for (int i = 0; i < results.length; i++) {
+ String var = results[i].getVariable();
+ MIValue val = results[i].getMIValue();
+
+ if (var.equals("thread-id")) { //$NON-NLS-1$
+ if (val instanceof MIConst) {
+ threadId = ((MIConst) val).getString();
+ }
+ }
+ }
+
+ IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
+ if (procService == null) {
+ return null;
+ }
+
+ IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(fControlDmc,
+ MIProcesses.UNIQUE_GROUP_ID);
+
+ IExecutionDMContext execDmc = processContainerDmc;
+ if (threadId != null) {
+ IProcessDMContext procDmc = DMContexts.getAncestorOfType(processContainerDmc, IProcessDMContext.class);
+ IThreadDMContext threadDmc = procService.createThreadContext(procDmc, threadId);
+ execDmc = procService.createExecutionContext(processContainerDmc, threadDmc, threadId);
+ }
+
+ return execDmc;
+ }
+
+ @ConfinedToDsfExecutor("")
+ protected MIEvent<?> createEvent(String reason, MIExecAsyncOutput exec) {
+ IExecutionDMContext execDmc = getExecutionContext(exec);
+ MIEvent<?> event = null;
+ if ("breakpoint-hit".equals(reason)) { //$NON-NLS-1$
+ event = MIBreakpointHitEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
+ } else if ("watchpoint-trigger".equals(reason) //$NON-NLS-1$
+ || "read-watchpoint-trigger".equals(reason) //$NON-NLS-1$
+ || "access-watchpoint-trigger".equals(reason)) { //$NON-NLS-1$
+ event = MIWatchpointTriggerEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
+ } else if ("watchpoint-scope".equals(reason)) { //$NON-NLS-1$
+ event = MIWatchpointScopeEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
+ } else if ("end-stepping-range".equals(reason)) { //$NON-NLS-1$
+ event = MISteppingRangeEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
+ } else if ("signal-received".equals(reason)) { //$NON-NLS-1$
+ event = MISignalEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
+ } else if ("location-reached".equals(reason)) { //$NON-NLS-1$
+ event = MILocationReachedEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
+ } else if ("function-finished".equals(reason)) { //$NON-NLS-1$
+ event = MIFunctionFinishedEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
} else if ("solib-event".equals(reason)) { //$NON-NLS-1$
event = MISharedLibEvent.parse(execDmc, exec.getToken(), exec.getMIResults(), null);
- } else if ("exited-normally".equals(reason) || "exited".equals(reason)) { //$NON-NLS-1$ //$NON-NLS-2$
- event = MIInferiorExitEvent.parse(fCommandControl.getContext(), exec.getToken(), exec.getMIResults());
- // Until we clean up the handling of all these events, we need to send the containerExited event
- // Only needed GDB < 7.0, because GDB itself does not yet send an MI event about the inferior terminating
- sendContainerExitedEvent();
- } else if ("exited-signalled".equals(reason)) { //$NON-NLS-1$
- event = MIInferiorSignalExitEvent.parse(fCommandControl.getContext(), exec.getToken(), exec.getMIResults());
- // Until we clean up the handling of all these events, we need to send the containerExited event
- // Only needed GDB < 7.0, because GDB itself does not yet send an MI event about the inferior terminating
- sendContainerExitedEvent();
- } else if (STOPPED_REASON.equals(reason)) {
- event = MIStoppedEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
- }
- return event;
- }
-
- private void sendContainerExitedEvent() {
- IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
- if (procService != null) {
- IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
-
- fCommandControl.getSession().dispatchEvent(
- new ContainerExitedDMEvent(processContainerDmc), fCommandControl.getProperties());
- }
- }
-
+ } else if ("exited-normally".equals(reason) || "exited".equals(reason)) { //$NON-NLS-1$ //$NON-NLS-2$
+ event = MIInferiorExitEvent.parse(fCommandControl.getContext(), exec.getToken(), exec.getMIResults());
+ // Until we clean up the handling of all these events, we need to send the containerExited event
+ // Only needed GDB < 7.0, because GDB itself does not yet send an MI event about the inferior terminating
+ sendContainerExitedEvent();
+ } else if ("exited-signalled".equals(reason)) { //$NON-NLS-1$
+ event = MIInferiorSignalExitEvent.parse(fCommandControl.getContext(), exec.getToken(), exec.getMIResults());
+ // Until we clean up the handling of all these events, we need to send the containerExited event
+ // Only needed GDB < 7.0, because GDB itself does not yet send an MI event about the inferior terminating
+ sendContainerExitedEvent();
+ } else if (STOPPED_REASON.equals(reason)) {
+ event = MIStoppedEvent.parse(execDmc, exec.getToken(), exec.getMIResults());
+ }
+ return event;
+ }
+
+ private void sendContainerExitedEvent() {
+ IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
+ if (procService != null) {
+ IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(fControlDmc,
+ MIProcesses.UNIQUE_GROUP_ID);
+
+ fCommandControl.getSession().dispatchEvent(new ContainerExitedDMEvent(processContainerDmc),
+ fCommandControl.getProperties());
+ }
+ }
+
@Override
- public void commandQueued(ICommandToken token) {
- // Do nothing.
- }
-
+ public void commandQueued(ICommandToken token) {
+ // Do nothing.
+ }
+
@Override
- public void commandSent(ICommandToken token) {
- // Do nothing.
- }
-
+ public void commandSent(ICommandToken token) {
+ // Do nothing.
+ }
+
@Override
- public void commandRemoved(ICommandToken token) {
- // Do nothing.
- }
-
+ public void commandRemoved(ICommandToken token) {
+ // Do nothing.
+ }
+
@Override
- public void commandDone(ICommandToken token, ICommandResult result) {
- ICommand<?> cmd = token.getCommand();
- MIInfo cmdResult = (MIInfo) result ;
- MIOutput output = cmdResult.getMIOutput();
- MIResultRecord rr = output.getMIResultRecord();
- if (rr != null) {
- int id = rr.getToken();
- // Check if the state changed.
- String state = rr.getResultClass();
- if ("running".equals(state)) { //$NON-NLS-1$
- int type = 0;
- // Check the type of command
- // if it was a step instruction set state stepping
-
- if (cmd instanceof MIExecNext) { type = MIRunningEvent.NEXT; }
- else if (cmd instanceof MIExecNextInstruction) { type = MIRunningEvent.NEXTI; }
- else if (cmd instanceof MIExecStep) { type = MIRunningEvent.STEP; }
- else if (cmd instanceof MIExecStepInstruction) { type = MIRunningEvent.STEPI; }
- else if (cmd instanceof MIExecUntil) { type = MIRunningEvent.UNTIL; }
- else if (cmd instanceof MIExecFinish) { type = MIRunningEvent.FINISH; }
- else if (cmd instanceof MIExecReturn) { type = MIRunningEvent.RETURN; }
- else if (cmd instanceof MIExecContinue) { type = MIRunningEvent.CONTINUE; }
- else { type = MIRunningEvent.CONTINUE; }
-
- IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
- if (procService != null) {
- IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
-
- fCommandControl.getSession().dispatchEvent(
- new MIRunningEvent(processContainerDmc, id, type), fCommandControl.getProperties());
- }
- } else if ("exit".equals(state)) { //$NON-NLS-1$
- // No need to do anything, terminate() will.
- // Send exited?
- } else if ("connected".equals(state)) { //$NON-NLS-1$
- // This will happen for a CORE or REMOTE session.
- // For a CORE session this is the only indication
- // that the inferior has 'started'. So we use
- // it to trigger the ContainerStarted event.
- // In the case of a REMOTE session, it is a proper
- // indicator as well but not if it is a remote attach.
- // For an attach session, it only indicates
- // that we are connected to a remote node but we still
- // need to wait until we are attached to the process before
- // sending the event, which will happen in the attaching code.
- IGDBBackend backendService = fServicesTracker.getService(IGDBBackend.class);
- if (backendService != null && backendService.getIsAttachSession() == false) {
- IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
- if (procService != null) {
- IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
-
- fCommandControl.getSession().dispatchEvent(
- new ContainerStartedDMEvent(processContainerDmc), fCommandControl.getProperties());
- }
- }
- } else if ("error".equals(state)) { //$NON-NLS-1$
- } else if ("done".equals(state)) { //$NON-NLS-1$
- // For GDBs older than 7.0, GDB does not trigger a *stopped event
- // when it stops due to a CLI command. We have to trigger the
- // MIStoppedEvent ourselves
- if (cmd instanceof CLICommand<?>) {
- // It is important to limit this to runControl operations (e.g., 'next', 'continue', 'jump')
- // There are other CLI commands that we use that could still be sent when the target is considered
- // running, due to timing issues.
- boolean isAttachingOperation = CLIEventProcessor.isAttachingOperation(((CLICommand<?>)cmd).getOperation());
- boolean isSteppingOperation = CLIEventProcessor.isSteppingOperation(((CLICommand<?>)cmd).getOperation());
- if (isSteppingOperation || isAttachingOperation) {
- IRunControl runControl = fServicesTracker.getService(IRunControl.class);
- IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
- if (runControl != null && procService != null) {
- // We don't know which thread stopped so we simply create a container event.
- IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
-
- // An attaching operation is debugging a new inferior and always stops it.
- // We should not check that the container is suspended, because at startup, we are considered
- // suspended, even though we can get a *stopped event.
- if (isAttachingOperation || runControl.isSuspended(processContainerDmc) == false) {
- MIEvent<?> event = MIStoppedEvent.parse(processContainerDmc, id, rr.getMIResults());
- fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
- }
- }
- }
- }
- }
- }
- }
+ public void commandDone(ICommandToken token, ICommandResult result) {
+ ICommand<?> cmd = token.getCommand();
+ MIInfo cmdResult = (MIInfo) result;
+ MIOutput output = cmdResult.getMIOutput();
+ MIResultRecord rr = output.getMIResultRecord();
+ if (rr != null) {
+ int id = rr.getToken();
+ // Check if the state changed.
+ String state = rr.getResultClass();
+ if ("running".equals(state)) { //$NON-NLS-1$
+ int type = 0;
+ // Check the type of command
+ // if it was a step instruction set state stepping
+
+ if (cmd instanceof MIExecNext) {
+ type = MIRunningEvent.NEXT;
+ } else if (cmd instanceof MIExecNextInstruction) {
+ type = MIRunningEvent.NEXTI;
+ } else if (cmd instanceof MIExecStep) {
+ type = MIRunningEvent.STEP;
+ } else if (cmd instanceof MIExecStepInstruction) {
+ type = MIRunningEvent.STEPI;
+ } else if (cmd instanceof MIExecUntil) {
+ type = MIRunningEvent.UNTIL;
+ } else if (cmd instanceof MIExecFinish) {
+ type = MIRunningEvent.FINISH;
+ } else if (cmd instanceof MIExecReturn) {
+ type = MIRunningEvent.RETURN;
+ } else if (cmd instanceof MIExecContinue) {
+ type = MIRunningEvent.CONTINUE;
+ } else {
+ type = MIRunningEvent.CONTINUE;
+ }
+
+ IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
+ if (procService != null) {
+ IContainerDMContext processContainerDmc = procService.createContainerContextFromGroupId(fControlDmc,
+ MIProcesses.UNIQUE_GROUP_ID);
+
+ fCommandControl.getSession().dispatchEvent(new MIRunningEvent(processContainerDmc, id, type),
+ fCommandControl.getProperties());
+ }
+ } else if ("exit".equals(state)) { //$NON-NLS-1$
+ // No need to do anything, terminate() will.
+ // Send exited?
+ } else if ("connected".equals(state)) { //$NON-NLS-1$
+ // This will happen for a CORE or REMOTE session.
+ // For a CORE session this is the only indication
+ // that the inferior has 'started'. So we use
+ // it to trigger the ContainerStarted event.
+ // In the case of a REMOTE session, it is a proper
+ // indicator as well but not if it is a remote attach.
+ // For an attach session, it only indicates
+ // that we are connected to a remote node but we still
+ // need to wait until we are attached to the process before
+ // sending the event, which will happen in the attaching code.
+ IGDBBackend backendService = fServicesTracker.getService(IGDBBackend.class);
+ if (backendService != null && backendService.getIsAttachSession() == false) {
+ IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
+ if (procService != null) {
+ IContainerDMContext processContainerDmc = procService
+ .createContainerContextFromGroupId(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
+
+ fCommandControl.getSession().dispatchEvent(new ContainerStartedDMEvent(processContainerDmc),
+ fCommandControl.getProperties());
+ }
+ }
+ } else if ("error".equals(state)) { //$NON-NLS-1$
+ } else if ("done".equals(state)) { //$NON-NLS-1$
+ // For GDBs older than 7.0, GDB does not trigger a *stopped event
+ // when it stops due to a CLI command. We have to trigger the
+ // MIStoppedEvent ourselves
+ if (cmd instanceof CLICommand<?>) {
+ // It is important to limit this to runControl operations (e.g., 'next', 'continue', 'jump')
+ // There are other CLI commands that we use that could still be sent when the target is considered
+ // running, due to timing issues.
+ boolean isAttachingOperation = CLIEventProcessor
+ .isAttachingOperation(((CLICommand<?>) cmd).getOperation());
+ boolean isSteppingOperation = CLIEventProcessor
+ .isSteppingOperation(((CLICommand<?>) cmd).getOperation());
+ if (isSteppingOperation || isAttachingOperation) {
+ IRunControl runControl = fServicesTracker.getService(IRunControl.class);
+ IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
+ if (runControl != null && procService != null) {
+ // We don't know which thread stopped so we simply create a container event.
+ IContainerDMContext processContainerDmc = procService
+ .createContainerContextFromGroupId(fControlDmc, MIProcesses.UNIQUE_GROUP_ID);
+
+ // An attaching operation is debugging a new inferior and always stops it.
+ // We should not check that the container is suspended, because at startup, we are considered
+ // suspended, even though we can get a *stopped event.
+ if (isAttachingOperation || runControl.isSuspended(processContainerDmc) == false) {
+ MIEvent<?> event = MIStoppedEvent.parse(processContainerDmc, id, rr.getMIResults());
+ fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}

Back to the top