1
0
Fork 0
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:
Marc Khouzam 2010-07-06 20:27:07 +00:00
parent 787f73eb3f
commit 78669bf6c1
12 changed files with 397 additions and 28 deletions

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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$
}

View file

@ -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

View file

@ -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>

View file

@ -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) {

View file

@ -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
{
/**

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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

View file

@ -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; }
}

View file

@ -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();