1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 22:52:11 +02:00

[302597] For MIStopped event that don't contain a threadId we must ask the backend for the threadId

This commit is contained in:
Marc Khouzam 2010-02-26 13:56:49 +00:00
parent 768a0c7393
commit d2cd2d381f
5 changed files with 148 additions and 31 deletions

View file

@ -32,6 +32,7 @@ import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIJump;
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIThread;
import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecContinue;
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecFinish;
@ -54,6 +55,7 @@ import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
import org.eclipse.cdt.dsf.mi.service.command.events.MIThreadCreatedEvent;
import org.eclipse.cdt.dsf.mi.service.command.events.MIThreadExitEvent;
import org.eclipse.cdt.dsf.mi.service.command.events.MIWatchpointTriggerEvent;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIThreadInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIThreadListIdsInfo;
import org.eclipse.cdt.dsf.service.AbstractDsfService;
@ -381,10 +383,29 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
IDMEvent<?> event = null;
// Find the container context, which is used in multi-threaded debugging.
IContainerDMContext containerDmc = DMContexts.getAncestorOfType(e.getDMContext(), IContainerDMContext.class);
final IContainerDMContext containerDmc = DMContexts.getAncestorOfType(e.getDMContext(), IContainerDMContext.class);
if (containerDmc != null) {
// Set the triggering context only if it's different than the container context.
// Set the triggering context only if it's not the container context, since we are looking for a thread.
IExecutionDMContext triggeringCtx = !e.getDMContext().equals(containerDmc) ? e.getDMContext() : null;
if (triggeringCtx == null) {
// Still no thread. Let's ask the bakend for one.
// We need a proper thread id for the debug view to select the right thread
// Bug 300096 comment #15 and Bug 302597
getConnection().queueCommand(
new CLIThread(containerDmc),
new DataRequestMonitor<CLIThreadInfo>(getExecutor(), null) {
@Override
protected void handleCompleted() {
IExecutionDMContext triggeringCtx2 = null;
if (isSuccess() && getData().getCurrentThread() != null) {
triggeringCtx2 = createMIExecutionContext(containerDmc, getData().getCurrentThread());
}
IDMEvent<?> event2 = new ContainerSuspendedEvent(containerDmc, e, triggeringCtx2);
getSession().dispatchEvent(event2, getProperties());
}
});
return;
}
event = new ContainerSuspendedEvent(containerDmc, e, triggeringCtx);
} else {
event = new SuspendedEvent(e.getDMContext(), e);

View file

@ -156,16 +156,7 @@ public class CLIEventProcessor
}
private void processStateChanges(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
int type = getSteppingOperationKind(operation);
if (type != -1) {
// if it was a step instruction set state running
@ -237,6 +228,14 @@ public class CLIEventProcessor
}
private static int getSteppingOperationKind(String operation) {
// Get the command name.
int indx = operation.indexOf(' ');
if (indx != -1) {
operation = operation.substring(0, indx).trim();
} else {
operation = operation.trim();
}
int type = -1;
/* execution commands: n, next, s, step, si, stepi, u, until, finish, return,
c, continue, fg */

View file

@ -14,8 +14,6 @@ package org.eclipse.cdt.dsf.mi.service.command;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
@ -292,24 +290,23 @@ public class MIRunControlEventProcessor
// when it stops due to a CLI command. We have to trigger the
// MIStoppedEvent ourselves
if (cmd instanceof CLICommand<?>) {
IRunControl runControl = fServicesTracker.getService(IRunControl.class);
if (runControl != null) {
IDMContext dmc = ((CLICommand<?>)cmd).getContext();
IExecutionDMContext execDmc =
DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);
if (execDmc == null) {
IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
if (procService != null) {
String groupId = MIProcesses.UNIQUE_GROUP_ID;
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId);
execDmc = procService.createContainerContext(procDmc, groupId);
}
}
if (execDmc != null && runControl.isSuspended(execDmc) == false) {
MIEvent<?> event = MIStoppedEvent.parse(execDmc, id, rr.getMIResults());
fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
}
// 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.
if (CLIEventProcessor.isSteppingOperation(((CLICommand<?>)cmd).getOperation())) {
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.
String groupId = MIProcesses.UNIQUE_GROUP_ID;
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId);
IContainerDMContext processContainerDmc = procService.createContainerContext(procDmc, groupId);
if (runControl.isSuspended(processContainerDmc) == false) {
MIEvent<?> event = MIStoppedEvent.parse(processContainerDmc, id, rr.getMIResults());
fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
}
}
}
}
}

View file

@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2010 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.command.output.CLIThreadInfo;
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
/**
*
* thread
*
* [Current thread is 1 (Thread 0xb7cc56b0 (LWP 5488))]
*
* @since 3.0
*
*/
public class CLIThread extends CLICommand<CLIThreadInfo> {
public CLIThread(IContainerDMContext ctx) {
super(ctx, "thread"); //$NON-NLS-1$
}
@Override
public CLIThreadInfo getResult(MIOutput output) {
return new CLIThreadInfo(output);
}
}

View file

@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (c) 2010 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.output;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* [Current thread is 1 (Thread 0xb7cc56b0 (LWP 5488))]
*
* @since 3.0
*/
public class CLIThreadInfo extends MIInfo {
private Integer fCurrentThread;
public CLIThreadInfo(MIOutput out) {
super(out);
parse();
}
public Integer getCurrentThread(){
return fCurrentThread;
}
protected void parse() {
if (isDone()) {
MIOutput out = getMIOutput();
MIOOBRecord[] oobs = out.getMIOOBRecords();
for (int i = 0; i < oobs.length; i++) {
if (oobs[i] instanceof MIConsoleStreamOutput) {
MIStreamRecord cons = (MIStreamRecord) oobs[i];
String str = cons.getString();
// We are interested in finding the current thread
parseThreadInfo(str.trim());
}
}
}
}
protected void parseThreadInfo(String str) {
// Fetch the OS ThreadId & Find the current thread
if(str.length() > 0 ){
Pattern pattern = Pattern.compile("Current thread is (\\d+)", Pattern.MULTILINE); //$NON-NLS-1$
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
String id = matcher.group(1).trim();
fCurrentThread = Integer.parseInt(id);
}
}
}
}