mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-13 19:25:38 +02:00
Bug 318230: Use GDB 7.1 support for displaying cores for threads and processes in a label within the debug view.
This commit is contained in:
parent
787f73eb3f
commit
78669bf6c1
12 changed files with 397 additions and 28 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2009 Ericsson and others.
|
||||
* Copyright (c) 2006, 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
|
||||
|
@ -27,7 +27,9 @@ import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
|
|||
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.ui.viewmodel.launch.AbstractContainerVMNode;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ExecutionContextLabelText;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ILaunchVMConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.IGdbThreadDMData;
|
||||
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor;
|
||||
|
@ -36,18 +38,27 @@ import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
|
|||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelAttribute;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelColumnInfo;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelImage;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.properties.LabelText;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.properties.PropertiesBasedLabelProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.properties.VMDelegatingPropertiesUpdate;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoProvider;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
||||
import org.eclipse.debug.ui.DebugUITools;
|
||||
import org.eclipse.debug.ui.IDebugUIConstants;
|
||||
import org.eclipse.ui.IMemento;
|
||||
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class ContainerVMNode extends AbstractContainerVMNode
|
||||
implements IElementMementoProvider
|
||||
implements IElementLabelProvider, IElementMementoProvider
|
||||
{
|
||||
public ContainerVMNode(AbstractDMVMProvider provider, DsfSession session) {
|
||||
super(provider, session);
|
||||
|
@ -58,6 +69,37 @@ public class ContainerVMNode extends AbstractContainerVMNode
|
|||
return "ContainerVMNode(" + getSession().getId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IElementLabelProvider createLabelProvider() {
|
||||
PropertiesBasedLabelProvider provider = new PropertiesBasedLabelProvider();
|
||||
|
||||
provider.setColumnInfo(
|
||||
PropertiesBasedLabelProvider.ID_COLUMN_NO_COLUMNS,
|
||||
new LabelColumnInfo(new LabelAttribute[] {
|
||||
new GdbExecutionContextLabelText(
|
||||
MessagesForGdbLaunchVM.ContainerVMNode_No_columns__text_format,
|
||||
new String[] {
|
||||
ExecutionContextLabelText.PROP_NAME_KNOWN,
|
||||
PROP_NAME,
|
||||
ExecutionContextLabelText.PROP_ID_KNOWN,
|
||||
ILaunchVMConstants.PROP_ID,
|
||||
IGdbLaunchVMConstants.PROP_CORES_ID_KNOWN,
|
||||
IGdbLaunchVMConstants.PROP_CORES_ID }),
|
||||
new LabelText(MessagesForGdbLaunchVM.ContainerVMNode_No_columns__Error__label, new String[0]),
|
||||
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_DEBUG_TARGET_SUSPENDED)) {
|
||||
{ setPropertyNames(new String[] { ILaunchVMConstants.PROP_IS_SUSPENDED }); }
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(IStatus status, java.util.Map<String,Object> properties) {
|
||||
return Boolean.TRUE.equals(properties.get(ILaunchVMConstants.PROP_IS_SUSPENDED));
|
||||
};
|
||||
},
|
||||
new LabelImage(DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_DEBUG_TARGET)),
|
||||
}));
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
|
||||
IProcesses processService = getServicesTracker().getService(IProcesses.class);
|
||||
|
@ -98,6 +140,11 @@ public class ContainerVMNode extends AbstractContainerVMNode
|
|||
parentUpdates[i] = new VMDelegatingPropertiesUpdate(updates[i], countringRm);
|
||||
count++;
|
||||
|
||||
if (update.getProperties().contains(PROP_NAME) ||
|
||||
update.getProperties().contains(ILaunchVMConstants.PROP_ID) ||
|
||||
update.getProperties().contains(IGdbLaunchVMConstants.PROP_CORES_ID))
|
||||
{
|
||||
|
||||
IProcesses processService = getServicesTracker().getService(IProcesses.class);
|
||||
final IProcessDMContext procDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IProcessDMContext.class);
|
||||
|
||||
|
@ -119,6 +166,7 @@ public class ContainerVMNode extends AbstractContainerVMNode
|
|||
});
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
countringRm.setDoneCount(count);
|
||||
}
|
||||
|
@ -129,6 +177,21 @@ public class ContainerVMNode extends AbstractContainerVMNode
|
|||
protected void fillThreadDataProperties(IPropertiesUpdate update, IThreadDMData data) {
|
||||
update.setProperty(PROP_NAME, data.getName());
|
||||
update.setProperty(ILaunchVMConstants.PROP_ID, data.getId());
|
||||
|
||||
String coresStr = null;
|
||||
if (data instanceof IGdbThreadDMData) {
|
||||
String[] cores = ((IGdbThreadDMData)data).getCores();
|
||||
if (cores != null) {
|
||||
StringBuffer str = new StringBuffer();
|
||||
for (String core : cores) {
|
||||
str.append(core + ","); //$NON-NLS-1$
|
||||
}
|
||||
if (str.length() > 0) {
|
||||
coresStr = str.substring(0, str.length() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
update.setProperty(IGdbLaunchVMConstants.PROP_CORES_ID, coresStr);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,13 +29,18 @@ public class GdbExecutionContextLabelText extends ExecutionContextLabelText {
|
|||
if (IGdbLaunchVMConstants.PROP_OS_ID_KNOWN.equals(propertyName)) {
|
||||
return properties.get(IGdbLaunchVMConstants.PROP_OS_ID) != null ? 1 : 0;
|
||||
}
|
||||
if (IGdbLaunchVMConstants.PROP_CORES_ID_KNOWN.equals(propertyName)) {
|
||||
return properties.get(IGdbLaunchVMConstants.PROP_CORES_ID) != null ? 1 : 0;
|
||||
}
|
||||
return super.getPropertyValue(propertyName, status, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkProperty(String propertyName, IStatus status, Map<String, Object> properties) {
|
||||
if (IGdbLaunchVMConstants.PROP_OS_ID_KNOWN.equals(propertyName) ||
|
||||
IGdbLaunchVMConstants.PROP_OS_ID.equals(propertyName))
|
||||
IGdbLaunchVMConstants.PROP_OS_ID.equals(propertyName) ||
|
||||
IGdbLaunchVMConstants.PROP_CORES_ID_KNOWN.equals(propertyName) ||
|
||||
IGdbLaunchVMConstants.PROP_CORES_ID.equals(propertyName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2009 Wind River Systems and others.
|
||||
* Copyright (c) 2008, 2010 Wind River Systems 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
|
||||
|
@ -22,5 +22,11 @@ public interface IGdbLaunchVMConstants {
|
|||
*/
|
||||
public static final String PROP_OS_ID_KNOWN = "os_id_known"; //$NON-NLS-1$
|
||||
|
||||
public static final String PROP_CORES_ID = "cores_id"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Value <code>0</code> means it's not known. Value <code>1</code>, means it's known.
|
||||
*/
|
||||
public static final String PROP_CORES_ID_KNOWN = "cores_id_known"; //$NON-NLS-1$
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2009 Wind River Systems and others.
|
||||
* Copyright (c) 2008, 2010 Wind River Systems 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
|
||||
|
@ -19,6 +19,8 @@ import org.eclipse.osgi.util.NLS;
|
|||
public class MessagesForGdbLaunchVM extends NLS {
|
||||
public static String ThreadVMNode_No_columns__text_format;
|
||||
public static String ThreadVMNode_No_columns__Error__label;
|
||||
public static String ContainerVMNode_No_columns__text_format;
|
||||
public static String ContainerVMNode_No_columns__Error__label;
|
||||
|
||||
static {
|
||||
// initialize resource bundle
|
||||
|
|
|
@ -15,12 +15,23 @@
|
|||
# {3} - ID
|
||||
# {4} - OS Thread ID available, 0=not available/1=available
|
||||
# {5} - OS Thread ID
|
||||
# {6} - 0=running/1=suspended
|
||||
# {7} - state change reason available, 0=not available/1=available
|
||||
# {8} - state change reason
|
||||
# {9} - state change details available, 0=not available/1=available
|
||||
# {10}- state change details
|
||||
ThreadVMNode_No_columns__text_format={0,choice,0#Thread|1#{1}}{2,choice,0#|1# [{3}]}{4,choice,0#|1# {5}} ({6,choice,0#Running|1#Suspended}{7,choice,0#|1# : {8}}{9,choice,0#|1# : {10}})
|
||||
# {6} - Core available, 0=not available/1=available
|
||||
# {7} - Core
|
||||
# {8} - 0=running/1=suspended
|
||||
# {9} - state change reason available, 0=not available/1=available
|
||||
# {10} - state change reason
|
||||
# {11} - state change details available, 0=not available/1=available
|
||||
# {12} - state change details
|
||||
ThreadVMNode_No_columns__text_format={0,choice,0#Thread|1#{1}}{2,choice,0#|1# [{3}]}{4,choice,0#|1# {5}}{6,choice,0#|1# [core: {7}]} ({8,choice,0#Running|1#Suspended}{9,choice,0#|1# : {10}}{11,choice,0#|1# : {12}})
|
||||
|
||||
ThreadVMNode_No_columns__Error__label=<unavailable>
|
||||
|
||||
# {0} - name available, 0=not available/1=available
|
||||
# {1} - name
|
||||
# {2} - ID available, 0=not available/1=available
|
||||
# {3} - ID
|
||||
# {4} - Cores available, 0=not available/1=available
|
||||
# {5} - Cores
|
||||
ContainerVMNode_No_columns__text_format={0,choice,0#Process|1#{1}}{2,choice,0#|1# [{3}]}{4,choice,0#|1# [cores: {5}]}
|
||||
|
||||
ContainerVMNode_No_columns__Error__label=<unavailable>
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData;
|
|||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.AbstractThreadVMNode;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ExecutionContextLabelText;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ILaunchVMConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.IGdbThreadDMData;
|
||||
import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
|
@ -74,6 +75,8 @@ public class ThreadVMNode extends AbstractThreadVMNode
|
|||
ILaunchVMConstants.PROP_ID,
|
||||
IGdbLaunchVMConstants.PROP_OS_ID_KNOWN,
|
||||
IGdbLaunchVMConstants.PROP_OS_ID,
|
||||
IGdbLaunchVMConstants.PROP_CORES_ID_KNOWN,
|
||||
IGdbLaunchVMConstants.PROP_CORES_ID,
|
||||
ILaunchVMConstants.PROP_IS_SUSPENDED,
|
||||
ExecutionContextLabelText.PROP_STATE_CHANGE_REASON_KNOWN,
|
||||
ILaunchVMConstants.PROP_STATE_CHANGE_REASON,
|
||||
|
@ -117,14 +120,14 @@ public class ThreadVMNode extends AbstractThreadVMNode
|
|||
update.setProperty(ILaunchVMConstants.PROP_ID, Integer.toString(execDmc.getThreadId()));
|
||||
}
|
||||
|
||||
IProcesses processService = getServicesTracker().getService(IProcesses.class);
|
||||
final IThreadDMContext threadDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IThreadDMContext.class);
|
||||
|
||||
if (update.getProperties().contains(PROP_NAME) ||
|
||||
update.getProperties().contains(IGdbLaunchVMConstants.PROP_OS_ID))
|
||||
update.getProperties().contains(IGdbLaunchVMConstants.PROP_OS_ID) ||
|
||||
update.getProperties().contains(IGdbLaunchVMConstants.PROP_CORES_ID))
|
||||
{
|
||||
//
|
||||
if (processService == null || threadDmc == null) {
|
||||
IProcesses processService = getServicesTracker().getService(IProcesses.class);
|
||||
final IThreadDMContext threadDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IThreadDMContext.class);
|
||||
|
||||
if (processService == null || threadDmc == null) {
|
||||
update.setStatus(DsfUIPlugin.newErrorStatus(IDsfStatusConstants.INVALID_HANDLE, "Service or handle invalid", null)); //$NON-NLS-1$
|
||||
} else {
|
||||
processService.getExecutionData(
|
||||
|
@ -153,6 +156,20 @@ public class ThreadVMNode extends AbstractThreadVMNode
|
|||
update.setProperty(PROP_NAME, data.getName());
|
||||
}
|
||||
update.setProperty(IGdbLaunchVMConstants.PROP_OS_ID, data.getId());
|
||||
|
||||
if (data instanceof IGdbThreadDMData) {
|
||||
String[] cores = ((IGdbThreadDMData)data).getCores();
|
||||
if (cores != null) {
|
||||
StringBuffer str = new StringBuffer();
|
||||
for (String core : cores) {
|
||||
str.append(core + ","); //$NON-NLS-1$
|
||||
}
|
||||
if (str.length() > 0) {
|
||||
String coresStr = str.substring(0, str.length() - 1);
|
||||
update.setProperty(IGdbLaunchVMConstants.PROP_CORES_ID, coresStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String produceThreadElementName(String viewName, IMIExecutionDMContext execCtx) {
|
||||
|
|
|
@ -75,10 +75,7 @@ import org.osgi.framework.BundleContext;
|
|||
|
||||
/**
|
||||
* This class implements the IProcesses interface for GDB 7.0
|
||||
* Actually, I'm not sure what the next version of GDB will be, so technically,
|
||||
* it is the one after GDB 6.8, as long as it contains multi-process support,
|
||||
* which really mean it supports the new -list-thread-groups command.
|
||||
*
|
||||
* which supports the new -list-thread-groups command.
|
||||
*/
|
||||
public class GDBProcesses_7_0 extends AbstractDsfService
|
||||
implements IGDBProcesses, ICachingService, IEventListener {
|
||||
|
@ -216,9 +213,10 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
|||
|
||||
/**
|
||||
* Context representing a thread.
|
||||
* @since 3.1
|
||||
*/
|
||||
@Immutable
|
||||
private static class MIThreadDMC extends AbstractDMContext
|
||||
protected static class MIThreadDMC extends AbstractDMContext
|
||||
implements IThreadDMContext
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,238 @@
|
|||
/*******************************************************************************
|
||||
* 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.gdb.service;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.concurrent.ImmediateExecutor;
|
||||
import org.eclipse.cdt.dsf.concurrent.Immutable;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.datamodel.DMContexts;
|
||||
import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerResumedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.BufferedCommandControl;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIProcessDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo.IThreadGroupInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo.IThreadGroupInfoExtension;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIThread;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIThreadInfoInfo;
|
||||
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
/**
|
||||
* This class implements the IProcesses interface for GDB 7.1
|
||||
* which provides new information about cores for threads and processes.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
public class GDBProcesses_7_1 extends GDBProcesses_7_0 {
|
||||
|
||||
@Immutable
|
||||
protected static class MIThreadDMData_7_1 extends MIThreadDMData implements IGdbThreadDMData {
|
||||
final String[] fCores;
|
||||
|
||||
public MIThreadDMData_7_1(String name, String id, String[] cores) {
|
||||
super(name, id);
|
||||
fCores = cores;
|
||||
}
|
||||
|
||||
public String[] getCores() { return fCores; }
|
||||
}
|
||||
|
||||
private CommandFactory fCommandFactory;
|
||||
// This cache is used when we send command to get the cores.
|
||||
// The value of the cores can change at any time, but we provide
|
||||
// an updated value whenever there is a suspended event.
|
||||
private CommandCache fCommandForCoresCache;
|
||||
private IGDBControl fCommandControl;
|
||||
|
||||
public GDBProcesses_7_1(DsfSession session) {
|
||||
super(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(final RequestMonitor requestMonitor) {
|
||||
super.initialize(new RequestMonitor(getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
doInitialize(requestMonitor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes this service after our superclass's initialize()
|
||||
* method succeeds.
|
||||
*
|
||||
* @param requestMonitor
|
||||
* The call-back object to notify when this service's
|
||||
* initialization is done.
|
||||
*/
|
||||
private void doInitialize(RequestMonitor requestMonitor) {
|
||||
fCommandControl = getServicesTracker().getService(IGDBControl.class);
|
||||
|
||||
// This caches stores the result of a command when received; also, this cache
|
||||
// is manipulated when receiving events. Currently, events are received after
|
||||
// three scheduling of the executor, while command results after only one. This
|
||||
// can cause problems because command results might be processed before an event
|
||||
// that actually arrived before the command result.
|
||||
// To solve this, we use a bufferedCommandControl that will delay the command
|
||||
// result by two scheduling of the executor.
|
||||
// See bug 280461
|
||||
fCommandForCoresCache = new CommandCache(getSession(),
|
||||
new BufferedCommandControl(fCommandControl, getExecutor(), 2));
|
||||
fCommandForCoresCache.setContextAvailable(fCommandControl.getContext(), true);
|
||||
|
||||
fCommandFactory = getServicesTracker().getService(IMICommandControl.class).getCommandFactory();
|
||||
getSession().addServiceEventListener(this, null);
|
||||
|
||||
requestMonitor.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown(RequestMonitor requestMonitor) {
|
||||
getSession().removeServiceEventListener(this);
|
||||
|
||||
super.shutdown(requestMonitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getExecutionData(final IThreadDMContext dmc, final DataRequestMonitor<IThreadDMData> rm) {
|
||||
if (dmc instanceof IMIProcessDMContext) {
|
||||
// Starting with GDB 7.1, we can obtain the list of cores a process is currently
|
||||
// running on (each core that has a thread of that process).
|
||||
// We have to use -list-thread-groups to obtain that information
|
||||
super.getExecutionData(dmc, new DataRequestMonitor<IThreadDMData>(ImmediateExecutor.getInstance(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
final IThreadDMData firstLevelData = getData();
|
||||
|
||||
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
|
||||
final String groupId = ((IMIProcessDMContext)dmc).getProcId();
|
||||
fCommandForCoresCache.execute(
|
||||
fCommandFactory.createMIListThreadGroups(controlDmc),
|
||||
new DataRequestMonitor<MIListThreadGroupsInfo>(ImmediateExecutor.getInstance(), rm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
String[] cores = null;
|
||||
if (isSuccess()) {
|
||||
IThreadGroupInfo[] groups = getData().getGroupList();
|
||||
if (groups != null) {
|
||||
for (IThreadGroupInfo group : groups) {
|
||||
if (group.getGroupId().equals(groupId)) {
|
||||
if (group instanceof IThreadGroupInfoExtension) {
|
||||
cores = ((IThreadGroupInfoExtension)group).getCores();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rm.setData(new MIThreadDMData_7_1(firstLevelData.getName(),
|
||||
firstLevelData.getId(),
|
||||
cores));
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (dmc instanceof MIThreadDMC) {
|
||||
// Starting with GDB 7.1, we can obtain the core on which a thread
|
||||
// is currently located. The info is a new field in -thread-info
|
||||
final MIThreadDMC threadDmc = (MIThreadDMC)dmc;
|
||||
|
||||
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
|
||||
fCommandForCoresCache.execute(fCommandFactory.createMIThreadInfo(controlDmc, threadDmc.getId()),
|
||||
new DataRequestMonitor<MIThreadInfoInfo>(ImmediateExecutor.getInstance(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
IThreadDMData threadData = null;
|
||||
if (getData().getThreadList().length != 0) {
|
||||
MIThread thread = getData().getThreadList()[0];
|
||||
if (thread.getThreadId().equals(threadDmc.getId())) {
|
||||
String core = thread.getCore();
|
||||
threadData = new MIThreadDMData_7_1("", thread.getOsId(), //$NON-NLS-1$
|
||||
core == null ? null : new String[] { core });
|
||||
}
|
||||
}
|
||||
|
||||
if (threadData != null) {
|
||||
rm.setData(threadData);
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Could not get thread info", null)); //$NON-NLS-1$
|
||||
}
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid DMC type", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched_7_1(IResumedDMEvent e) {
|
||||
if (e instanceof IContainerResumedDMEvent) {
|
||||
// This will happen in all-stop mode
|
||||
fCommandForCoresCache.setContextAvailable(e.getDMContext(), false);
|
||||
} else {
|
||||
// This will happen in non-stop mode
|
||||
// Keep target available for Container commands
|
||||
}
|
||||
}
|
||||
|
||||
// Something has suspended, core allocation could have changed
|
||||
// during the time it was running.
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched_7_1(ISuspendedDMEvent e) {
|
||||
if (e instanceof IContainerSuspendedDMEvent) {
|
||||
// This will happen in all-stop mode
|
||||
fCommandForCoresCache.setContextAvailable(fCommandControl.getContext(), true);
|
||||
} else {
|
||||
// This will happen in non-stop mode
|
||||
}
|
||||
|
||||
fCommandForCoresCache.reset();
|
||||
}
|
||||
|
||||
// Event handler when a thread or threadGroup starts, core allocation
|
||||
// could have changed
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched_7_1(IStartedDMEvent e) {
|
||||
fCommandForCoresCache.reset();
|
||||
}
|
||||
|
||||
// Event handler when a thread or a threadGroup exits, core allocation
|
||||
// could have changed
|
||||
@DsfServiceEventHandler
|
||||
public void eventDispatched_7_1(IExitedDMEvent e) {
|
||||
fCommandForCoresCache.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushCache(IDMContext context) {
|
||||
fCommandForCoresCache.reset(context);
|
||||
super.flushCache(context);
|
||||
}
|
||||
}
|
|
@ -44,6 +44,7 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
|
|||
|
||||
// This should eventually be "7.0" once GDB 7.0 is released
|
||||
private static final String GDB_7_0_VERSION = "6.8.50.20090218"; //$NON-NLS-1$
|
||||
private static final String GDB_7_1_VERSION = "7.1"; //$NON-NLS-1$
|
||||
private static final String GDB_7_2_VERSION = "7.1.50"; //$NON-NLS-1$
|
||||
|
||||
private final String fVersion;
|
||||
|
@ -133,6 +134,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
|
|||
|
||||
@Override
|
||||
protected IProcesses createProcessesService(DsfSession session) {
|
||||
if (GDB_7_1_VERSION.compareTo(fVersion) <= 0) {
|
||||
return new GDBProcesses_7_1(session);
|
||||
}
|
||||
if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) {
|
||||
return new GDBProcesses_7_0(session);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2009 Ericsson and others.
|
||||
* Copyright (c) 2008, 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
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
* Ericsson - added support for core-awareness
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service;
|
||||
|
||||
|
@ -15,6 +16,24 @@ import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
|||
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
||||
|
||||
public interface IGDBProcesses extends IMIProcesses {
|
||||
|
||||
/**
|
||||
* This interface extends the DSF ThreadDMData to provide
|
||||
* the cores on which a process or a thread is located.
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
public interface IGdbThreadDMData extends IThreadDMData {
|
||||
/**
|
||||
* @return The list of identifiers of the cores on which the thread
|
||||
* or process is currently located. A thread will typically
|
||||
* be located on a single core at a time, while a process will
|
||||
* be located on all cores on which one of the process' threads
|
||||
* is located. Returns null if the information is not available.
|
||||
*/
|
||||
String[] getCores();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all execution contexts belonging to a container. This call is synchronous,
|
||||
* unlike the call to getProcessesBeingDebugged(). However, some services may not be able
|
||||
|
|
|
@ -159,8 +159,15 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
|||
String getDesciption();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.1
|
||||
*/
|
||||
public interface IThreadGroupInfoExtension extends IThreadGroupInfo {
|
||||
String[] getCores();
|
||||
}
|
||||
|
||||
@Immutable
|
||||
private static class ThreadGroupInfo implements IThreadGroupInfo {
|
||||
private static class ThreadGroupInfo implements IThreadGroupInfoExtension {
|
||||
final String fGroupId;
|
||||
final String fDescription;
|
||||
final String fName;
|
||||
|
@ -208,6 +215,7 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
|||
public String getName() { return fName; }
|
||||
|
||||
public String getDesciption() { return fDescription; }
|
||||
public String[] getCores() { return fCores; }
|
||||
|
||||
// The following are not used yet, but it's good to keep
|
||||
// them as a way to document what is available from GDB.
|
||||
|
@ -216,8 +224,6 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
|||
@SuppressWarnings("unused")
|
||||
public String getUser() { return fUser; }
|
||||
@SuppressWarnings("unused")
|
||||
public String[] getCores() { return fCores; }
|
||||
@SuppressWarnings("unused")
|
||||
public String getExecutable() { return fExecutable; }
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public class MIThread {
|
|||
* Available since GDB 7.1
|
||||
* @since 3.1
|
||||
*/
|
||||
public String getCore() { return fCore; }
|
||||
public String getCore() { return fCore; }
|
||||
|
||||
public static MIThread parse(MITuple tuple) {
|
||||
MIResult[] results = tuple.getMIResults();
|
||||
|
|
Loading…
Add table
Reference in a new issue