mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 374024: In case /proc/cpuinfo cannot be fetched, rely on -list-thread-groups --available
This commit is contained in:
parent
675760dec8
commit
b36fe67745
3 changed files with 105 additions and 23 deletions
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,26 +24,6 @@ import org.eclipse.cdt.internal.core.ICoreInfo;
|
||||||
*/
|
*/
|
||||||
public class CoreList {
|
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 ICoreInfo[] fCoreList;
|
||||||
private String fCoreFileName;
|
private String fCoreFileName;
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,11 @@
|
||||||
package org.eclipse.cdt.dsf.gdb.service;
|
package org.eclipse.cdt.dsf.gdb.service;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Vector;
|
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.ICommandResult;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandToken;
|
import org.eclipse.cdt.dsf.debug.service.command.ICommandToken;
|
||||||
import org.eclipse.cdt.dsf.debug.service.command.IEventListener;
|
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.CoreList;
|
||||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||||
import org.eclipse.cdt.dsf.gdb.internal.service.command.commands.MIMetaGetCPUInfo;
|
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.IMICommandControl;
|
||||||
import org.eclipse.cdt.dsf.mi.service.command.CommandFactory;
|
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.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.AbstractDsfService;
|
||||||
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
|
||||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||||
|
@ -378,6 +384,7 @@ public class GDBHardware extends AbstractDsfService implements IGDBHardware, ICa
|
||||||
* information we need.
|
* information we need.
|
||||||
*/
|
*/
|
||||||
private class CPUInfoManager implements ICommandControl {
|
private class CPUInfoManager implements ICommandControl {
|
||||||
|
private final List<ICommandListener> fCommandProcessors = new ArrayList<ICommandListener>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <V extends ICommandResult> ICommandToken queueCommand(final ICommand<V> command, DataRequestMonitor<V> rm) {
|
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) {
|
if (command instanceof MIMetaGetCPUInfo) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final DataRequestMonitor<MIMetaGetCPUInfoInfo> drm = (DataRequestMonitor<MIMetaGetCPUInfoInfo>)rm;
|
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
|
// Now that we processed the file, remove it to avoid polluting the file system
|
||||||
new File(localFile).delete();
|
new File(localFile).delete();
|
||||||
drm.done(new MIMetaGetCPUInfoInfo(info));
|
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 {
|
} else {
|
||||||
// For a local session, parse /proc/cpuinfo directly.
|
// For a local session, parse /proc/cpuinfo directly.
|
||||||
ICoreInfo[] info = new CoreList("/proc/cpuinfo").getCoreList(); //$NON-NLS-1$
|
ICoreInfo[] info = new CoreList("/proc/cpuinfo").getCoreList(); //$NON-NLS-1$
|
||||||
drm.done(new MIMetaGetCPUInfoInfo(info));
|
drm.done(new MIMetaGetCPUInfoInfo(info));
|
||||||
|
processCommandDone(token, drm.getData());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR,
|
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;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Need to support these as they are used by the commandCache
|
||||||
@Override
|
@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
|
@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$
|
public void addEventListener(IEventListener processor) { assert false : "Not supported"; } //$NON-NLS-1$
|
||||||
@Override
|
@Override
|
||||||
public void removeEventListener(IEventListener processor) { assert false : "Not supported"; } //$NON-NLS-1$
|
public void removeEventListener(IEventListener processor) { assert false : "Not supported"; } //$NON-NLS-1$
|
||||||
|
|
Loading…
Add table
Reference in a new issue