Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Khouzam2012-03-16 14:47:44 -0400
committerMarc Khouzam2012-03-16 15:21:03 -0400
commitb36fe677457c4960c4f094a595228c136aa0feeb (patch)
tree812bd46efdf2c1d8915666b1071617367545a23a /dsf-gdb
parent675760dec8528b63d238e79547ae5a91820fc238 (diff)
downloadorg.eclipse.cdt-b36fe677457c4960c4f094a595228c136aa0feeb.tar.gz
org.eclipse.cdt-b36fe677457c4960c4f094a595228c136aa0feeb.tar.xz
org.eclipse.cdt-b36fe677457c4960c4f094a595228c136aa0feeb.zip
Bug 374024: In case /proc/cpuinfo cannot be fetched, rely on -list-thread-groups --available
Diffstat (limited to 'dsf-gdb')
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreInfo.java33
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java20
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardware.java75
3 files changed, 105 insertions, 23 deletions
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreInfo.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreInfo.java
new file mode 100644
index 0000000000..726a6fd47e
--- /dev/null
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreInfo.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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:
+ * Marc Khouzam (Ericsson) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.dsf.gdb.internal;
+
+import org.eclipse.cdt.internal.core.ICoreInfo;
+
+public class CoreInfo implements ICoreInfo {
+ private String fId;
+ private String fPhysicalId;
+
+ public CoreInfo(String id, String pId) {
+ fId = id;
+ fPhysicalId = pId;
+ }
+
+ @Override
+ public String getId() {
+ return fId;
+ }
+
+ @Override
+ public String getPhysicalId() {
+ return fPhysicalId;
+ }
+} \ No newline at end of file
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java
index 45e57f2ed4..55007d29bb 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/internal/CoreList.java
@@ -24,26 +24,6 @@ import org.eclipse.cdt.internal.core.ICoreInfo;
*/
public class CoreList {
- private class CoreInfo implements ICoreInfo {
- private String fId;
- private String fPhysicalId;
-
- public CoreInfo(String id, String pId) {
- fId = id;
- fPhysicalId = pId;
- }
-
- @Override
- public String getId() {
- return fId;
- }
-
- @Override
- public String getPhysicalId() {
- return fPhysicalId;
- }
- }
-
private ICoreInfo[] fCoreList;
private String fCoreFileName;
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardware.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardware.java
index c4c9323166..48d0a69d9c 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardware.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBHardware.java
@@ -12,8 +12,11 @@
package org.eclipse.cdt.dsf.gdb.service;
import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.Hashtable;
+import java.util.List;
import java.util.Set;
import java.util.Vector;
@@ -36,6 +39,7 @@ import org.eclipse.cdt.dsf.debug.service.command.ICommandListener;
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult;
import org.eclipse.cdt.dsf.debug.service.command.ICommandToken;
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
+import org.eclipse.cdt.dsf.gdb.internal.CoreInfo;
import org.eclipse.cdt.dsf.gdb.internal.CoreList;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.internal.service.command.commands.MIMetaGetCPUInfo;
@@ -44,6 +48,8 @@ import org.eclipse.cdt.dsf.gdb.service.command.IGDBControl;
import org.eclipse.cdt.dsf.mi.service.IMICommandControl;
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
+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.service.AbstractDsfService;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfSession;
@@ -378,6 +384,7 @@ public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICa
* information we need.
*/
private class CPUInfoManager implements ICommandControl {
+ private final List<ICommandListener> fCommandProcessors = new ArrayList<ICommandListener>();
@Override
public <V extends ICommandResult> ICommandToken queueCommand(final ICommand<V> command, DataRequestMonitor<V> rm) {
@@ -389,6 +396,11 @@ public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICa
}
};
+ // The class does not buffer commands itself, but sends them directly to the real
+ // MICommandControl service. Therefore, we must immediately tell our calling cache that the command
+ // has been sent, since we can never cancel it.
+ processCommandSent(token);
+
if (command instanceof MIMetaGetCPUInfo) {
@SuppressWarnings("unchecked")
final DataRequestMonitor<MIMetaGetCPUInfoInfo> drm = (DataRequestMonitor<MIMetaGetCPUInfoInfo>)rm;
@@ -407,12 +419,54 @@ public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICa
// Now that we processed the file, remove it to avoid polluting the file system
new File(localFile).delete();
drm.done(new MIMetaGetCPUInfoInfo(info));
+ processCommandDone(token, drm.getData());
+ }
+ @Override
+ protected void handleError() {
+ // On some older linux versions, gdbserver is not able to read from /proc
+ // because it is a pseudo filesystem.
+ // We need to find some other method of getting the info we need.
+
+ // For a remote session, we can use GDB's -list-thread-groups --available
+ // command, which shows on which cores a process is running. This does
+ // not necessarily give the exhaustive list of cores, but that is the best
+ // we have in this case.
+ //
+ // In this case, we don't have knowledge about CPUs, so we lump all cores
+ // into a single CPU.
+
+ fCommandControl.queueCommand(
+ fCommandFactory.createMIListThreadGroups(dmc, true),
+ new ImmediateDataRequestMonitor<MIListThreadGroupsInfo>(drm) {
+ @Override
+ protected void handleSuccess() {
+ // First extract the string id for every core GDB reports
+ Set<String> coreIds = new HashSet<String>();
+ IThreadGroupInfo[] groups = getData().getGroupList();
+ for (IThreadGroupInfo group : groups) {
+ coreIds.addAll(Arrays.asList(group.getCores()));
+ }
+
+ // Now create the context for each distinct core
+ //
+ // We don't have CPU info in this case so let's put them all under a single CPU
+ final String defaultCPUId = "0"; //$NON-NLS-1$
+ ICoreInfo[] info = new ICoreInfo[coreIds.size()];
+ int i = 0;
+ for (String id : coreIds) {
+ info[i++] = new CoreInfo(id, defaultCPUId);
+ }
+ drm.done(new MIMetaGetCPUInfoInfo(info));
+ processCommandDone(token, drm.getData());
+ }
+ });
}
});
} else {
// For a local session, parse /proc/cpuinfo directly.
ICoreInfo[] info = new CoreList("/proc/cpuinfo").getCoreList(); //$NON-NLS-1$
drm.done(new MIMetaGetCPUInfoInfo(info));
+ processCommandDone(token, drm.getData());
}
} else {
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
@@ -422,11 +476,26 @@ public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICa
return token;
}
+ // Need to support these as they are used by the commandCache
@Override
- public void addCommandListener(ICommandListener processor) { assert false : "Not supported"; } //$NON-NLS-1$
+ public void addCommandListener(ICommandListener processor) { fCommandProcessors.add(processor); }
+ @Override
+ public void removeCommandListener(ICommandListener processor) { fCommandProcessors.remove(processor); }
+
+
+ private void processCommandSent(ICommandToken token) {
+ for (ICommandListener processor : fCommandProcessors) {
+ processor.commandSent(token);
+ }
+ }
+
+ private void processCommandDone(ICommandToken token, ICommandResult result) {
+ for (ICommandListener processor : fCommandProcessors) {
+ processor.commandDone(token, result);
+ }
+ }
+
@Override
- public void removeCommandListener(ICommandListener processor) { assert false : "Not supported"; } //$NON-NLS-1$
- @Override
public void addEventListener(IEventListener processor) { assert false : "Not supported"; } //$NON-NLS-1$
@Override
public void removeEventListener(IEventListener processor) { assert false : "Not supported"; } //$NON-NLS-1$

Back to the top