mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 18:26:01 +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.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
|
||||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
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.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.MICommand;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecContinue;
|
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecContinue;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecFinish;
|
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.MIThreadCreatedEvent;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.events.MIThreadExitEvent;
|
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.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.MIInfo;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIThreadListIdsInfo;
|
import org.eclipse.cdt.dsf.mi.service.command.output.MIThreadListIdsInfo;
|
||||||
import org.eclipse.cdt.dsf.service.AbstractDsfService;
|
import org.eclipse.cdt.dsf.service.AbstractDsfService;
|
||||||
|
@ -381,10 +383,29 @@ public class MIRunControl extends AbstractDsfService implements IMIRunControl, I
|
||||||
|
|
||||||
IDMEvent<?> event = null;
|
IDMEvent<?> event = null;
|
||||||
// Find the container context, which is used in multi-threaded debugging.
|
// 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) {
|
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;
|
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);
|
event = new ContainerSuspendedEvent(containerDmc, e, triggeringCtx);
|
||||||
} else {
|
} else {
|
||||||
event = new SuspendedEvent(e.getDMContext(), e);
|
event = new SuspendedEvent(e.getDMContext(), e);
|
||||||
|
|
|
@ -156,16 +156,7 @@ public class CLIEventProcessor
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processStateChanges(int token, String operation) {
|
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
|
// Check the type of command
|
||||||
|
|
||||||
int type = getSteppingOperationKind(operation);
|
int type = getSteppingOperationKind(operation);
|
||||||
if (type != -1) {
|
if (type != -1) {
|
||||||
// if it was a step instruction set state running
|
// if it was a step instruction set state running
|
||||||
|
@ -237,6 +228,14 @@ public class CLIEventProcessor
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getSteppingOperationKind(String operation) {
|
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;
|
int type = -1;
|
||||||
/* execution commands: n, next, s, step, si, stepi, u, until, finish, return,
|
/* execution commands: n, next, s, step, si, stepi, u, until, finish, return,
|
||||||
c, continue, fg */
|
c, continue, fg */
|
||||||
|
|
|
@ -14,8 +14,6 @@ package org.eclipse.cdt.dsf.mi.service.command;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
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.IRunControl;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
|
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
|
||||||
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
|
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
|
// when it stops due to a CLI command. We have to trigger the
|
||||||
// MIStoppedEvent ourselves
|
// MIStoppedEvent ourselves
|
||||||
if (cmd instanceof CLICommand<?>) {
|
if (cmd instanceof CLICommand<?>) {
|
||||||
IRunControl runControl = fServicesTracker.getService(IRunControl.class);
|
// It is important to limit this to runControl operations (e.g., 'next', 'continue', 'jump')
|
||||||
if (runControl != null) {
|
// There are other CLI commands that we use that could still be sent when the target is considered
|
||||||
IDMContext dmc = ((CLICommand<?>)cmd).getContext();
|
// running, due to timing issues.
|
||||||
IExecutionDMContext execDmc =
|
if (CLIEventProcessor.isSteppingOperation(((CLICommand<?>)cmd).getOperation())) {
|
||||||
DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);
|
IRunControl runControl = fServicesTracker.getService(IRunControl.class);
|
||||||
|
IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
|
||||||
if (execDmc == null) {
|
if (runControl != null && procService != null) {
|
||||||
IMIProcesses procService = fServicesTracker.getService(IMIProcesses.class);
|
// We don't know which thread stopped so we simply create a container event.
|
||||||
if (procService != null) {
|
String groupId = MIProcesses.UNIQUE_GROUP_ID;
|
||||||
String groupId = MIProcesses.UNIQUE_GROUP_ID;
|
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId);
|
||||||
IProcessDMContext procDmc = procService.createProcessContext(fControlDmc, groupId);
|
IContainerDMContext processContainerDmc = procService.createContainerContext(procDmc, groupId);
|
||||||
execDmc = procService.createContainerContext(procDmc, groupId);
|
|
||||||
}
|
if (runControl.isSuspended(processContainerDmc) == false) {
|
||||||
}
|
MIEvent<?> event = MIStoppedEvent.parse(processContainerDmc, id, rr.getMIResults());
|
||||||
if (execDmc != null && runControl.isSuspended(execDmc) == false) {
|
fCommandControl.getSession().dispatchEvent(event, fCommandControl.getProperties());
|
||||||
MIEvent<?> event = MIStoppedEvent.parse(execDmc, 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