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:
parent
768a0c7393
commit
d2cd2d381f
5 changed files with 148 additions and 31 deletions
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue