mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-14 03:35:37 +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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* 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;
|
||||||
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.debug.ui.viewmodel.launch.AbstractContainerVMNode;
|
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.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.internal.ui.DsfUIPlugin;
|
||||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
import org.eclipse.cdt.dsf.ui.concurrent.ViewerCountingRequestMonitor;
|
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.AbstractDMVMProvider;
|
||||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
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.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.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.IChildrenUpdate;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementCompareRequest;
|
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.IElementMementoProvider;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
|
import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementMementoRequest;
|
||||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
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;
|
import org.eclipse.ui.IMemento;
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("restriction")
|
@SuppressWarnings("restriction")
|
||||||
public class ContainerVMNode extends AbstractContainerVMNode
|
public class ContainerVMNode extends AbstractContainerVMNode
|
||||||
implements IElementMementoProvider
|
implements IElementLabelProvider, IElementMementoProvider
|
||||||
{
|
{
|
||||||
public ContainerVMNode(AbstractDMVMProvider provider, DsfSession session) {
|
public ContainerVMNode(AbstractDMVMProvider provider, DsfSession session) {
|
||||||
super(provider, session);
|
super(provider, session);
|
||||||
|
@ -58,6 +69,37 @@ public class ContainerVMNode extends AbstractContainerVMNode
|
||||||
return "ContainerVMNode(" + getSession().getId() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
|
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
|
@Override
|
||||||
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
|
protected void updateElementsInSessionThread(final IChildrenUpdate update) {
|
||||||
IProcesses processService = getServicesTracker().getService(IProcesses.class);
|
IProcesses processService = getServicesTracker().getService(IProcesses.class);
|
||||||
|
@ -98,6 +140,11 @@ public class ContainerVMNode extends AbstractContainerVMNode
|
||||||
parentUpdates[i] = new VMDelegatingPropertiesUpdate(updates[i], countringRm);
|
parentUpdates[i] = new VMDelegatingPropertiesUpdate(updates[i], countringRm);
|
||||||
count++;
|
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);
|
IProcesses processService = getServicesTracker().getService(IProcesses.class);
|
||||||
final IProcessDMContext procDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IProcessDMContext.class);
|
final IProcessDMContext procDmc = findDmcInPath(update.getViewerInput(), update.getElementPath(), IProcessDMContext.class);
|
||||||
|
|
||||||
|
@ -119,6 +166,7 @@ public class ContainerVMNode extends AbstractContainerVMNode
|
||||||
});
|
});
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
countringRm.setDoneCount(count);
|
countringRm.setDoneCount(count);
|
||||||
}
|
}
|
||||||
|
@ -129,6 +177,21 @@ public class ContainerVMNode extends AbstractContainerVMNode
|
||||||
protected void fillThreadDataProperties(IPropertiesUpdate update, IThreadDMData data) {
|
protected void fillThreadDataProperties(IPropertiesUpdate update, IThreadDMData data) {
|
||||||
update.setProperty(PROP_NAME, data.getName());
|
update.setProperty(PROP_NAME, data.getName());
|
||||||
update.setProperty(ILaunchVMConstants.PROP_ID, data.getId());
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,9 @@ public class GdbExecutionContextLabelText extends ExecutionContextLabelText {
|
||||||
protected Object getPropertyValue(String propertyName, IStatus status, Map<String, Object> properties) {
|
protected Object getPropertyValue(String propertyName, IStatus status, Map<String, Object> properties) {
|
||||||
if (IGdbLaunchVMConstants.PROP_OS_ID_KNOWN.equals(propertyName)) {
|
if (IGdbLaunchVMConstants.PROP_OS_ID_KNOWN.equals(propertyName)) {
|
||||||
return properties.get(IGdbLaunchVMConstants.PROP_OS_ID) != null ? 1 : 0;
|
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);
|
return super.getPropertyValue(propertyName, status, properties);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +38,9 @@ public class GdbExecutionContextLabelText extends ExecutionContextLabelText {
|
||||||
@Override
|
@Override
|
||||||
protected boolean checkProperty(String propertyName, IStatus status, Map<String, Object> properties) {
|
protected boolean checkProperty(String propertyName, IStatus status, Map<String, Object> properties) {
|
||||||
if (IGdbLaunchVMConstants.PROP_OS_ID_KNOWN.equals(propertyName) ||
|
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;
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* 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_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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -19,6 +19,8 @@ import org.eclipse.osgi.util.NLS;
|
||||||
public class MessagesForGdbLaunchVM extends NLS {
|
public class MessagesForGdbLaunchVM extends NLS {
|
||||||
public static String ThreadVMNode_No_columns__text_format;
|
public static String ThreadVMNode_No_columns__text_format;
|
||||||
public static String ThreadVMNode_No_columns__Error__label;
|
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 {
|
static {
|
||||||
// initialize resource bundle
|
// initialize resource bundle
|
||||||
|
|
|
@ -15,12 +15,23 @@
|
||||||
# {3} - ID
|
# {3} - ID
|
||||||
# {4} - OS Thread ID available, 0=not available/1=available
|
# {4} - OS Thread ID available, 0=not available/1=available
|
||||||
# {5} - OS Thread ID
|
# {5} - OS Thread ID
|
||||||
# {6} - 0=running/1=suspended
|
# {6} - Core available, 0=not available/1=available
|
||||||
# {7} - state change reason available, 0=not available/1=available
|
# {7} - Core
|
||||||
# {8} - state change reason
|
# {8} - 0=running/1=suspended
|
||||||
# {9} - state change details available, 0=not available/1=available
|
# {9} - state change reason available, 0=not available/1=available
|
||||||
# {10}- state change details
|
# {10} - state change reason
|
||||||
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}})
|
# {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>
|
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.AbstractThreadVMNode;
|
||||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.ExecutionContextLabelText;
|
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.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.internal.ui.DsfUIPlugin;
|
||||||
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
|
||||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
|
@ -74,7 +75,9 @@ public class ThreadVMNode extends AbstractThreadVMNode
|
||||||
ILaunchVMConstants.PROP_ID,
|
ILaunchVMConstants.PROP_ID,
|
||||||
IGdbLaunchVMConstants.PROP_OS_ID_KNOWN,
|
IGdbLaunchVMConstants.PROP_OS_ID_KNOWN,
|
||||||
IGdbLaunchVMConstants.PROP_OS_ID,
|
IGdbLaunchVMConstants.PROP_OS_ID,
|
||||||
ILaunchVMConstants.PROP_IS_SUSPENDED,
|
IGdbLaunchVMConstants.PROP_CORES_ID_KNOWN,
|
||||||
|
IGdbLaunchVMConstants.PROP_CORES_ID,
|
||||||
|
ILaunchVMConstants.PROP_IS_SUSPENDED,
|
||||||
ExecutionContextLabelText.PROP_STATE_CHANGE_REASON_KNOWN,
|
ExecutionContextLabelText.PROP_STATE_CHANGE_REASON_KNOWN,
|
||||||
ILaunchVMConstants.PROP_STATE_CHANGE_REASON,
|
ILaunchVMConstants.PROP_STATE_CHANGE_REASON,
|
||||||
ExecutionContextLabelText.PROP_STATE_CHANGE_DETAILS_KNOWN,
|
ExecutionContextLabelText.PROP_STATE_CHANGE_DETAILS_KNOWN,
|
||||||
|
@ -117,14 +120,14 @@ public class ThreadVMNode extends AbstractThreadVMNode
|
||||||
update.setProperty(ILaunchVMConstants.PROP_ID, Integer.toString(execDmc.getThreadId()));
|
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) ||
|
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))
|
||||||
{
|
{
|
||||||
//
|
IProcesses processService = getServicesTracker().getService(IProcesses.class);
|
||||||
if (processService == null || threadDmc == null) {
|
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$
|
update.setStatus(DsfUIPlugin.newErrorStatus(IDsfStatusConstants.INVALID_HANDLE, "Service or handle invalid", null)); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
processService.getExecutionData(
|
processService.getExecutionData(
|
||||||
|
@ -153,6 +156,20 @@ public class ThreadVMNode extends AbstractThreadVMNode
|
||||||
update.setProperty(PROP_NAME, data.getName());
|
update.setProperty(PROP_NAME, data.getName());
|
||||||
}
|
}
|
||||||
update.setProperty(IGdbLaunchVMConstants.PROP_OS_ID, data.getId());
|
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) {
|
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
|
* 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,
|
* which supports the new -list-thread-groups command.
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class GDBProcesses_7_0 extends AbstractDsfService
|
public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
implements IGDBProcesses, ICachingService, IEventListener {
|
implements IGDBProcesses, ICachingService, IEventListener {
|
||||||
|
@ -216,9 +213,10 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context representing a thread.
|
* Context representing a thread.
|
||||||
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
@Immutable
|
@Immutable
|
||||||
private static class MIThreadDMC extends AbstractDMContext
|
protected static class MIThreadDMC extends AbstractDMContext
|
||||||
implements IThreadDMContext
|
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
|
// 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_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 static final String GDB_7_2_VERSION = "7.1.50"; //$NON-NLS-1$
|
||||||
|
|
||||||
private final String fVersion;
|
private final String fVersion;
|
||||||
|
@ -133,6 +134,9 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IProcesses createProcessesService(DsfSession session) {
|
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) {
|
if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) {
|
||||||
return new GDBProcesses_7_0(session);
|
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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Ericsson - initial API and implementation
|
* Ericsson - initial API and implementation
|
||||||
|
* Ericsson - added support for core-awareness
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.dsf.gdb.service;
|
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;
|
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
|
||||||
|
|
||||||
public interface IGDBProcesses extends 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,
|
* 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
|
* unlike the call to getProcessesBeingDebugged(). However, some services may not be able
|
||||||
|
|
|
@ -158,9 +158,16 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
||||||
String getName();
|
String getName();
|
||||||
String getDesciption();
|
String getDesciption();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public interface IThreadGroupInfoExtension extends IThreadGroupInfo {
|
||||||
|
String[] getCores();
|
||||||
|
}
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
private static class ThreadGroupInfo implements IThreadGroupInfo {
|
private static class ThreadGroupInfo implements IThreadGroupInfoExtension {
|
||||||
final String fGroupId;
|
final String fGroupId;
|
||||||
final String fDescription;
|
final String fDescription;
|
||||||
final String fName;
|
final String fName;
|
||||||
|
@ -208,6 +215,7 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
||||||
public String getName() { return fName; }
|
public String getName() { return fName; }
|
||||||
|
|
||||||
public String getDesciption() { return fDescription; }
|
public String getDesciption() { return fDescription; }
|
||||||
|
public String[] getCores() { return fCores; }
|
||||||
|
|
||||||
// The following are not used yet, but it's good to keep
|
// The following are not used yet, but it's good to keep
|
||||||
// them as a way to document what is available from GDB.
|
// them as a way to document what is available from GDB.
|
||||||
|
@ -216,8 +224,6 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public String getUser() { return fUser; }
|
public String getUser() { return fUser; }
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public String[] getCores() { return fCores; }
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public String getExecutable() { return fExecutable; }
|
public String getExecutable() { return fExecutable; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class MIThread {
|
||||||
* Available since GDB 7.1
|
* Available since GDB 7.1
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public String getCore() { return fCore; }
|
public String getCore() { return fCore; }
|
||||||
|
|
||||||
public static MIThread parse(MITuple tuple) {
|
public static MIThread parse(MITuple tuple) {
|
||||||
MIResult[] results = tuple.getMIResults();
|
MIResult[] results = tuple.getMIResults();
|
||||||
|
|
Loading…
Add table
Reference in a new issue