mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 17:26:01 +02:00
[274135] Changes to support GDB HEAD, to lead to the proper support of GDB 7.0
This commit is contained in:
parent
f9f6f4d46a
commit
2d2e01d6f4
4 changed files with 154 additions and 96 deletions
|
@ -11,6 +11,7 @@
|
||||||
package org.eclipse.cdt.dsf.gdb.service;
|
package org.eclipse.cdt.dsf.gdb.service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -341,12 +342,21 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
private Map<String, String> fThreadToGroupMap = new HashMap<String, String>();
|
private Map<String, String> fThreadToGroupMap = new HashMap<String, String>();
|
||||||
|
|
||||||
private IGDBControl fCommandControl;
|
private IGDBControl fCommandControl;
|
||||||
|
private IGDBBackend fBackend;
|
||||||
|
|
||||||
// A cache for commands about the threadGroups
|
// A cache for commands about the threadGroups
|
||||||
private CommandCache fContainerCommandCache;
|
private CommandCache fContainerCommandCache;
|
||||||
|
|
||||||
//A cache for commands about the threads
|
//A cache for commands about the threads
|
||||||
private CommandCache fThreadCommandCache;
|
private CommandCache fThreadCommandCache;
|
||||||
|
|
||||||
|
// A temporary cache to avoid using -list-thread-groups --available more than once at the same time.
|
||||||
|
// We cannot cache this command because it lists all available processes, which can
|
||||||
|
// change at any time. However, it is inefficient to send more than one of this command at
|
||||||
|
// the same time. This cache will help us avoid that. The idea is that we cache the command,
|
||||||
|
// but as soon as it returns, we clear the cache. So the cache will only trigger for those
|
||||||
|
// overlapping situations.
|
||||||
|
private CommandCache fListThreadGroupsAvailableCache;
|
||||||
|
|
||||||
// A map of process id to process names. It is filled when we get all the processes that are running
|
// A map of process id to process names. It is filled when we get all the processes that are running
|
||||||
private Map<String, String> fProcessNames = new HashMap<String, String>();
|
private Map<String, String> fProcessNames = new HashMap<String, String>();
|
||||||
|
@ -384,10 +394,15 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
private void doInitialize(RequestMonitor requestMonitor) {
|
private void doInitialize(RequestMonitor requestMonitor) {
|
||||||
|
|
||||||
fCommandControl = getServicesTracker().getService(IGDBControl.class);
|
fCommandControl = getServicesTracker().getService(IGDBControl.class);
|
||||||
|
fBackend = getServicesTracker().getService(IGDBBackend.class);
|
||||||
|
|
||||||
fContainerCommandCache = new CommandCache(getSession(), fCommandControl);
|
fContainerCommandCache = new CommandCache(getSession(), fCommandControl);
|
||||||
fContainerCommandCache.setContextAvailable(fCommandControl.getContext(), true);
|
fContainerCommandCache.setContextAvailable(fCommandControl.getContext(), true);
|
||||||
fThreadCommandCache = new CommandCache(getSession(), fCommandControl);
|
fThreadCommandCache = new CommandCache(getSession(), fCommandControl);
|
||||||
fThreadCommandCache.setContextAvailable(fCommandControl.getContext(), true);
|
fThreadCommandCache.setContextAvailable(fCommandControl.getContext(), true);
|
||||||
|
|
||||||
|
fListThreadGroupsAvailableCache = new CommandCache(getSession(), fCommandControl);
|
||||||
|
fListThreadGroupsAvailableCache.setContextAvailable(fCommandControl.getContext(), true);
|
||||||
|
|
||||||
getSession().addServiceEventListener(this, null);
|
getSession().addServiceEventListener(this, null);
|
||||||
fCommandControl.addEventListener(this);
|
fCommandControl.addEventListener(this);
|
||||||
|
@ -447,6 +462,21 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
|
|
||||||
public IMIContainerDMContext createContainerContextFromThreadId(ICommandControlDMContext controlDmc, String threadId) {
|
public IMIContainerDMContext createContainerContextFromThreadId(ICommandControlDMContext controlDmc, String threadId) {
|
||||||
String groupId = fThreadToGroupMap.get(threadId);
|
String groupId = fThreadToGroupMap.get(threadId);
|
||||||
|
if (groupId == null) {
|
||||||
|
// this can happen if the threadId was 'all'
|
||||||
|
// In such a case, we choose the first process we find
|
||||||
|
// This works when we run a single process
|
||||||
|
// but will break for multi-process!!!
|
||||||
|
if (fThreadToGroupMap.isEmpty()) {
|
||||||
|
groupId = MIProcesses.UNIQUE_GROUP_ID;
|
||||||
|
} else {
|
||||||
|
Collection<String> values = fThreadToGroupMap.values();
|
||||||
|
for (String value : values) {
|
||||||
|
groupId = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
IProcessDMContext processDmc = createProcessContext(controlDmc, groupId);
|
IProcessDMContext processDmc = createProcessContext(controlDmc, groupId);
|
||||||
return createContainerContext(processDmc, groupId);
|
return createContainerContext(processDmc, groupId);
|
||||||
}
|
}
|
||||||
|
@ -471,42 +501,58 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
|
|
||||||
public void getExecutionData(IThreadDMContext dmc, final DataRequestMonitor<IThreadDMData> rm) {
|
public void getExecutionData(IThreadDMContext dmc, final DataRequestMonitor<IThreadDMData> rm) {
|
||||||
if (dmc instanceof IMIProcessDMContext) {
|
if (dmc instanceof IMIProcessDMContext) {
|
||||||
final String id = ((IMIProcessDMContext)dmc).getProcId();
|
if (fBackend.getSessionType() == SessionType.CORE) {
|
||||||
String name = fProcessNames.get(id);
|
// For the Core session, the process is no longer running.
|
||||||
if (name == null) {
|
// Therefore, we cannot get its name with the -list-thread-groups command
|
||||||
// We don't have the name yet. Maybe we didn't fetch names yet,
|
// Instead, we take it from the binary we are using.
|
||||||
// or maybe this is a new process
|
String name = fBackend.getProgramPath().lastSegment();
|
||||||
// This is not very efficient, but GDB does not provide a way to get the name
|
// Also, the pid we get from GDB is 1, which is not correct.
|
||||||
// of a single process.
|
// I haven't found a good way to get the pid yet, so let's not show it.
|
||||||
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
|
rm.setData(new MIThreadDMData(name, null));
|
||||||
fCommandControl.queueCommand(
|
rm.done();
|
||||||
new MIListThreadGroups(controlDmc, true),
|
} else {
|
||||||
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
final String id = ((IMIProcessDMContext)dmc).getProcId();
|
||||||
@Override
|
String name = fProcessNames.get(id);
|
||||||
protected void handleCompleted() {
|
if (name == null) {
|
||||||
String name = null;
|
// We don't have the name yet. Maybe we didn't fetch names yet,
|
||||||
if (isSuccess()) {
|
// or maybe this is a new process
|
||||||
for (IThreadGroupInfo groupInfo : getData().getGroupList()) {
|
// This is not very efficient, but GDB does not provide a way to get the name
|
||||||
fProcessNames.put(groupInfo.getPid(), groupInfo.getName());
|
// of a single process.
|
||||||
if (groupInfo.getPid().equals(id)) {
|
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
|
||||||
name = groupInfo.getName();
|
fListThreadGroupsAvailableCache.execute(
|
||||||
|
new MIListThreadGroups(controlDmc, true),
|
||||||
|
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
||||||
|
@Override
|
||||||
|
protected void handleCompleted() {
|
||||||
|
// We cannot actually cache this command since the process
|
||||||
|
// list may change. But this cache allows to avoid overlapping
|
||||||
|
// sending of this command.
|
||||||
|
fListThreadGroupsAvailableCache.reset();
|
||||||
|
|
||||||
|
String name = null;
|
||||||
|
if (isSuccess()) {
|
||||||
|
for (IThreadGroupInfo groupInfo : getData().getGroupList()) {
|
||||||
|
fProcessNames.put(groupInfo.getPid(), groupInfo.getName());
|
||||||
|
if (groupInfo.getPid().equals(id)) {
|
||||||
|
name = groupInfo.getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (name == null) {
|
|
||||||
// We still don't have the name... weird.
|
|
||||||
// Don't go into an infinite loop by trying again, just give up
|
|
||||||
name = "Unknown name"; //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
rm.setData(new MIThreadDMData(name, id));
|
|
||||||
rm.done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
if (name == null) {
|
||||||
rm.setData(new MIThreadDMData(name, id));
|
// We still don't have the name... weird.
|
||||||
rm.done();
|
// Don't go into an infinite loop by trying again, just give up
|
||||||
|
name = "Unknown name"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
rm.setData(new MIThreadDMData(name, id));
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
rm.setData(new MIThreadDMData(name, id));
|
||||||
|
rm.done();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (dmc instanceof MIThreadDMC) {
|
} else if (dmc instanceof MIThreadDMC) {
|
||||||
final MIThreadDMC threadDmc = (MIThreadDMC)dmc;
|
final MIThreadDMC threadDmc = (MIThreadDMC)dmc;
|
||||||
|
@ -554,15 +600,28 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
private boolean doIsDebuggerAttachSupported() {
|
||||||
IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
|
IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
|
||||||
rm.setData(backend.getIsAttachSession());
|
if (backend != null) {
|
||||||
|
return backend.getIsAttachSession();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isDebuggerAttachSupported(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
||||||
|
rm.setData(doIsDebuggerAttachSupported());
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void attachDebuggerToProcess(final IProcessDMContext procCtx, final DataRequestMonitor<IDMContext> rm) {
|
public void attachDebuggerToProcess(final IProcessDMContext procCtx, final DataRequestMonitor<IDMContext> rm) {
|
||||||
if (procCtx instanceof IMIProcessDMContext) {
|
if (procCtx instanceof IMIProcessDMContext) {
|
||||||
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(procCtx, ICommandControlDMContext.class);
|
if (!doIsDebuggerAttachSupported()) {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Attach not supported.", null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(procCtx, ICommandControlDMContext.class);
|
||||||
fCommandControl.queueCommand(
|
fCommandControl.queueCommand(
|
||||||
new MITargetAttach(controlDmc, ((IMIProcessDMContext)procCtx).getProcId()),
|
new MITargetAttach(controlDmc, ((IMIProcessDMContext)procCtx).getProcId()),
|
||||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
|
new DataRequestMonitor<MIInfo>(getExecutor(), rm) {
|
||||||
|
@ -580,19 +639,33 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void canDetachDebuggerFromProcess(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
private boolean doCanDetachDebuggerFromProcess() {
|
||||||
IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
|
IGDBBackend backend = getServicesTracker().getService(IGDBBackend.class);
|
||||||
rm.setData(backend.getIsAttachSession() && fCommandControl.isConnected());
|
if (backend != null) {
|
||||||
|
return backend.getIsAttachSession() && fCommandControl.isConnected();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void canDetachDebuggerFromProcess(IDMContext dmc, DataRequestMonitor<Boolean> rm) {
|
||||||
|
rm.setData(doCanDetachDebuggerFromProcess());
|
||||||
rm.done();
|
rm.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void detachDebuggerFromProcess(final IDMContext dmc, final RequestMonitor rm) {
|
public void detachDebuggerFromProcess(final IDMContext dmc, final RequestMonitor rm) {
|
||||||
|
|
||||||
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
|
ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
|
||||||
IMIProcessDMContext procDmc = DMContexts.getAncestorOfType(dmc, IMIProcessDMContext.class);
|
IMIProcessDMContext procDmc = DMContexts.getAncestorOfType(dmc, IMIProcessDMContext.class);
|
||||||
|
|
||||||
if (controlDmc != null && procDmc != null) {
|
if (controlDmc != null && procDmc != null) {
|
||||||
fCommandControl.queueCommand(
|
if (!doCanDetachDebuggerFromProcess()) {
|
||||||
|
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Detach not supported.", null)); //$NON-NLS-1$
|
||||||
|
rm.done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fCommandControl.queueCommand(
|
||||||
new MITargetDetach(controlDmc, procDmc.getProcId()),
|
new MITargetDetach(controlDmc, procDmc.getProcId()),
|
||||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
|
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
|
||||||
} else {
|
} else {
|
||||||
|
@ -619,38 +692,29 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getProcessesBeingDebugged(final IDMContext dmc, final DataRequestMonitor<IDMContext[]> rm) {
|
public void getProcessesBeingDebugged(final IDMContext dmc, final DataRequestMonitor<IDMContext[]> rm) {
|
||||||
// MIInferiorProcess inferiorProcess = fCommandControl.getInferiorProcess();
|
final ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
|
||||||
// if (fCommandControl.isConnected() &&
|
final IMIContainerDMContext containerDmc = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
|
||||||
// inferiorProcess != null &&
|
if (containerDmc != null) {
|
||||||
// inferiorProcess.getState() != MIInferiorProcess.State.TERMINATED) {
|
fThreadCommandCache.execute(
|
||||||
|
new MIListThreadGroups(controlDmc, containerDmc.getGroupId()),
|
||||||
final ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
|
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
||||||
final IMIContainerDMContext containerDmc = DMContexts.getAncestorOfType(dmc, IMIContainerDMContext.class);
|
@Override
|
||||||
if (containerDmc != null) {
|
protected void handleSuccess() {
|
||||||
fThreadCommandCache.execute(
|
rm.setData(makeExecutionDMCs(containerDmc, getData().getThreadInfo().getThreadList()));
|
||||||
new MIListThreadGroups(controlDmc, containerDmc.getGroupId()),
|
rm.done();
|
||||||
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
}
|
||||||
@Override
|
});
|
||||||
protected void handleSuccess() {
|
} else {
|
||||||
rm.setData(makeExecutionDMCs(containerDmc, getData().getThreadInfo().getThreadList()));
|
fContainerCommandCache.execute(
|
||||||
rm.done();
|
new MIListThreadGroups(controlDmc),
|
||||||
}
|
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
||||||
});
|
@Override
|
||||||
} else {
|
protected void handleSuccess() {
|
||||||
fContainerCommandCache.execute(
|
rm.setData(makeContainerDMCs(controlDmc, getData().getGroupList()));
|
||||||
new MIListThreadGroups(controlDmc),
|
rm.done();
|
||||||
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
}
|
||||||
@Override
|
});
|
||||||
protected void handleSuccess() {
|
}
|
||||||
rm.setData(makeContainerDMCs(controlDmc, getData().getGroupList()));
|
|
||||||
rm.done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// } else {
|
|
||||||
// rm.setData(new IDMContext[0]);
|
|
||||||
// rm.done();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IExecutionDMContext[] makeExecutionDMCs(IContainerDMContext containerDmc, MIThread[] threadInfos) {
|
private IExecutionDMContext[] makeExecutionDMCs(IContainerDMContext containerDmc, MIThread[] threadInfos) {
|
||||||
|
@ -693,11 +757,16 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
|
|
||||||
if (controlDmc != null) {
|
if (controlDmc != null) {
|
||||||
// Don't cache this command since the list can change at any time.
|
// Don't cache this command since the list can change at any time.
|
||||||
fCommandControl.queueCommand(
|
fListThreadGroupsAvailableCache.execute(
|
||||||
new MIListThreadGroups(controlDmc, true),
|
new MIListThreadGroups(controlDmc, true),
|
||||||
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
new DataRequestMonitor<MIListThreadGroupsInfo>(getExecutor(), rm) {
|
||||||
@Override
|
@Override
|
||||||
protected void handleCompleted() {
|
protected void handleCompleted() {
|
||||||
|
// We cannot actually cache this command since the process
|
||||||
|
// list may change. But this cache allows to avoid overlapping
|
||||||
|
// sending of this command.
|
||||||
|
fListThreadGroupsAvailableCache.reset();
|
||||||
|
|
||||||
if (isSuccess()) {
|
if (isSuccess()) {
|
||||||
for (IThreadGroupInfo groupInfo : getData().getGroupList()) {
|
for (IThreadGroupInfo groupInfo : getData().getGroupList()) {
|
||||||
fProcessNames.put(groupInfo.getPid(), groupInfo.getName());
|
fProcessNames.put(groupInfo.getPid(), groupInfo.getName());
|
||||||
|
@ -737,12 +806,7 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
}
|
}
|
||||||
|
|
||||||
public void terminate(IThreadDMContext thread, RequestMonitor rm) {
|
public void terminate(IThreadDMContext thread, RequestMonitor rm) {
|
||||||
if (thread instanceof IMIProcessDMContext) {
|
fCommandControl.terminate(rm);
|
||||||
fCommandControl.terminate(rm);
|
|
||||||
} else {
|
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid process context.", null)); //$NON-NLS-1$
|
|
||||||
rm.done();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DsfServiceEventHandler
|
@DsfServiceEventHandler
|
||||||
|
@ -757,7 +821,6 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
IProcessDMContext procDmc = e.getDMContext();
|
IProcessDMContext procDmc = e.getDMContext();
|
||||||
IMIContainerDMContext containerDmc = e.getGroupId() != null ? createContainerContext(procDmc, e.getGroupId()) : null;
|
IMIContainerDMContext containerDmc = e.getGroupId() != null ? createContainerContext(procDmc, e.getGroupId()) : null;
|
||||||
getSession().dispatchEvent(new ContainerExitedDMEvent(containerDmc), getProperties());
|
getSession().dispatchEvent(new ContainerExitedDMEvent(containerDmc), getProperties());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DsfServiceEventHandler
|
@DsfServiceEventHandler
|
||||||
|
@ -777,8 +840,8 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
public void eventDispatched(ISuspendedDMEvent e) {
|
public void eventDispatched(ISuspendedDMEvent e) {
|
||||||
if (e instanceof IContainerSuspendedDMEvent) {
|
if (e instanceof IContainerSuspendedDMEvent) {
|
||||||
// This will happen in all-stop mode
|
// This will happen in all-stop mode
|
||||||
fContainerCommandCache.setContextAvailable(e.getDMContext(), true);
|
fContainerCommandCache.setContextAvailable(fCommandControl.getContext(), true);
|
||||||
fThreadCommandCache.setContextAvailable(e.getDMContext(), true);
|
fThreadCommandCache.setContextAvailable(fCommandControl.getContext(), true);
|
||||||
} else {
|
} else {
|
||||||
// This will happen in non-stop mode
|
// This will happen in non-stop mode
|
||||||
}
|
}
|
||||||
|
@ -843,13 +906,6 @@ public class GDBProcesses_7_0 extends AbstractDsfService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Until GDB is officially supporting multi-process, we may not get
|
|
||||||
// a groupId. In this case, we are running single process and we'll
|
|
||||||
// need its groupId
|
|
||||||
if (groupId == null) {
|
|
||||||
groupId = MIProcesses.UNIQUE_GROUP_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("thread-created".equals(miEvent)) { //$NON-NLS-1$
|
if ("thread-created".equals(miEvent)) { //$NON-NLS-1$
|
||||||
// Update the thread to groupId map with the new groupId
|
// Update the thread to groupId map with the new groupId
|
||||||
fThreadToGroupMap.put(threadId, groupId);
|
fThreadToGroupMap.put(threadId, groupId);
|
||||||
|
|
|
@ -42,7 +42,7 @@ import org.eclipse.debug.core.ILaunchConfiguration;
|
||||||
public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
|
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.20081118"; //$NON-NLS-1$
|
private static final String GDB_7_0_VERSION = "6.8.50.20090218"; //$NON-NLS-1$
|
||||||
|
|
||||||
private final String fVersion;
|
private final String fVersion;
|
||||||
|
|
||||||
|
@ -123,10 +123,7 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IProcesses createProcessesService(DsfSession session) {
|
protected IProcesses createProcessesService(DsfSession session) {
|
||||||
// Multi-process is not part of GDB HEAD yet,
|
if (GDB_7_0_VERSION.compareTo(fVersion) <= 0) {
|
||||||
// but is part of this very specific build.
|
|
||||||
// We'll need to change this when 7.0 is ready
|
|
||||||
if (fVersion.startsWith("6.8.50.20090218")) { //$NON-NLS-1$
|
|
||||||
return new GDBProcesses_7_0(session);
|
return new GDBProcesses_7_0(session);
|
||||||
}
|
}
|
||||||
return new GDBProcesses(session);
|
return new GDBProcesses(session);
|
||||||
|
|
|
@ -289,7 +289,7 @@ public class MIRunControlEventProcessor_7_0
|
||||||
}
|
}
|
||||||
|
|
||||||
IExecutionDMContext execDmc = containerDmc;
|
IExecutionDMContext execDmc = containerDmc;
|
||||||
if (threadId != null) {
|
if (threadId != null && !threadId.equals("all")) { //$NON-NLS-1$
|
||||||
IThreadDMContext threadDmc = procService.createThreadContext(procDmc, threadId);
|
IThreadDMContext threadDmc = procService.createThreadContext(procDmc, threadId);
|
||||||
execDmc = procService.createExecutionContext(containerDmc, threadDmc, threadId);
|
execDmc = procService.createExecutionContext(containerDmc, threadDmc, threadId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,8 @@ import org.eclipse.cdt.dsf.concurrent.Immutable;
|
||||||
* {id="162",type="process",description="name: JIM_TcpSetupHandlerProcess, type 555505, locked: N, system: N, state: Idle"},
|
* {id="162",type="process",description="name: JIM_TcpSetupHandlerProcess, type 555505, locked: N, system: N, state: Idle"},
|
||||||
* {id="165",type="process",description="name: JUnitProcess2_PT, type 1094608, locked: N, system: N, state: Idle"},
|
* {id="165",type="process",description="name: JUnitProcess2_PT, type 1094608, locked: N, system: N, state: Idle"},
|
||||||
* {id="166",type="process",description="name: JUnitProcess_PT, type 1094605, locked: N, system: N, state: Idle"}]
|
* {id="166",type="process",description="name: JUnitProcess_PT, type 1094605, locked: N, system: N, state: Idle"}]
|
||||||
*
|
*
|
||||||
|
* {id="3602",type="process",description="/usr/sbin/dhcdbd --system",user="root"}
|
||||||
* -list-thread-groups:
|
* -list-thread-groups:
|
||||||
* ^done,groups=[{id="162",type="process",pid="162"}]
|
* ^done,groups=[{id="162",type="process",pid="162"}]
|
||||||
*
|
*
|
||||||
|
@ -66,6 +67,10 @@ public class MIListThreadGroupsInfo extends MIInfo {
|
||||||
Matcher matcher = pattern.matcher(desc);
|
Matcher matcher = pattern.matcher(desc);
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
name = matcher.group(1);
|
name = matcher.group(1);
|
||||||
|
} else {
|
||||||
|
// If we didn't get the form "name: " then we expect to have the form
|
||||||
|
// "/usr/sbin/dhcdbd --system"
|
||||||
|
name = desc.split("\\s", 2)[0]; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
|
|
Loading…
Add table
Reference in a new issue