1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 02:06:01 +02:00

Bug 318230: Show cores and user name when listing processes to attach too.

This commit is contained in:
Marc Khouzam 2010-07-30 17:45:41 +00:00
parent 04f6ef5c84
commit 2d499636f4
8 changed files with 199 additions and 68 deletions

View file

@ -15,7 +15,6 @@ import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import org.eclipse.cdt.core.IProcessInfo;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DsfExecutor; import org.eclipse.cdt.dsf.concurrent.DsfExecutor;
@ -30,7 +29,9 @@ import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.gdb.actions.IConnect; import org.eclipse.cdt.dsf.gdb.actions.IConnect;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.gdb.launching.IProcessExtendedInfo;
import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages; import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages;
import org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.IGdbThreadDMData;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses; import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.dsf.service.DsfSession;
@ -87,10 +88,10 @@ public class GdbConnectCommand implements IConnect {
class PromptForPidJob extends Job { class PromptForPidJob extends Job {
// The list of processes used in the case of an ATTACH session // The list of processes used in the case of an ATTACH session
IProcessInfo[] fProcessList = null; IProcessExtendedInfo[] fProcessList = null;
DataRequestMonitor<Integer> fRequestMonitor; DataRequestMonitor<Integer> fRequestMonitor;
public PromptForPidJob(String name, IProcessInfo[] procs, DataRequestMonitor<Integer> rm) { public PromptForPidJob(String name, IProcessExtendedInfo[] procs, DataRequestMonitor<Integer> rm) {
super(name); super(name);
fProcessList = procs; fProcessList = procs;
fRequestMonitor = rm; fRequestMonitor = rm;
@ -157,14 +158,14 @@ public class GdbConnectCommand implements IConnect {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
final List<IProcessInfo> procInfoList = new ArrayList<IProcessInfo>(); final List<IProcessExtendedInfo> procInfoList = new ArrayList<IProcessExtendedInfo>();
final CountingRequestMonitor countingRm = final CountingRequestMonitor countingRm =
new CountingRequestMonitor(fExecutor, rm) { new CountingRequestMonitor(fExecutor, rm) {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
new PromptForPidJob( new PromptForPidJob(
"Prompt for Process", procInfoList.toArray(new IProcessInfo[0]), //$NON-NLS-1$ "Prompt for Process", procInfoList.toArray(new IProcessExtendedInfo[0]), //$NON-NLS-1$
new DataRequestMonitor<Integer>(fExecutor, rm) { new DataRequestMonitor<Integer>(fExecutor, rm) {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
@ -190,7 +191,13 @@ public class GdbConnectCommand implements IConnect {
pid = Integer.parseInt(processData.getId()); pid = Integer.parseInt(processData.getId());
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
} }
procInfoList.add(new ProcessInfo(pid, processData.getName())); String[] cores = null;
String owner = null;
if (processData instanceof IGdbThreadDMData) {
cores = ((IGdbThreadDMData)processData).getCores();
owner = ((IGdbThreadDMData)processData).getOwner();
}
procInfoList.add(new ProcessInfo(pid, processData.getName(), cores, owner));
} }
// Re-use the counting monitor and trigger it right away. // Re-use the counting monitor and trigger it right away.
@ -215,12 +222,19 @@ public class GdbConnectCommand implements IConnect {
new DataRequestMonitor<IThreadDMData> (fExecutor, countingRm) { new DataRequestMonitor<IThreadDMData> (fExecutor, countingRm) {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
IThreadDMData processData = getData();
int pid = 0; int pid = 0;
try { try {
pid = Integer.parseInt(getData().getId()); pid = Integer.parseInt(processData.getId());
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
} }
procInfoList.add(new ProcessInfo(pid, getData().getName())); String[] cores = null;
String owner = null;
if (processData instanceof IGdbThreadDMData) {
cores = ((IGdbThreadDMData)processData).getCores();
owner = ((IGdbThreadDMData)processData).getOwner();
}
procInfoList.add(new ProcessInfo(pid, processData.getName(), cores, owner));
countingRm.done(); countingRm.done();
} }
}); });

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 * 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
@ -10,46 +10,52 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.actions; package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
import org.eclipse.cdt.core.IProcessInfo;
import org.eclipse.cdt.dsf.concurrent.Immutable; import org.eclipse.cdt.dsf.concurrent.Immutable;
import org.eclipse.cdt.dsf.gdb.launching.IProcessExtendedInfo;
@Immutable @Immutable
class ProcessInfo implements IProcessInfo, Comparable<ProcessInfo> { class ProcessInfo implements IProcessExtendedInfo, Comparable<ProcessInfo> {
private final int pid; private final int pid;
private final String name; private final String name;
private final String[] cores;
public ProcessInfo(String pidString, String name) { private final String ownerId;
int tmpPid = 0;
try {
tmpPid = Integer.parseInt(pidString);
} catch (NumberFormatException e) {
}
this.pid = tmpPid;
this.name = name;
}
public ProcessInfo(int pid, String name) { public ProcessInfo(int pid, String name) {
this.pid = pid; this(pid, name, null, null);
this.name = name; }
/** @since 2.2 */
public ProcessInfo(int pid, String name, String[] cores, String owner) {
this.pid = pid;
this.name = name;
this.cores = cores;
this.ownerId = owner;
} }
/**
* @see org.eclipse.cdt.core.IProcessInfo#getName()
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* @see org.eclipse.cdt.core.IProcessInfo#getPid()
*/
public int getPid() { public int getPid() {
return pid; return pid;
} }
public String[] getCores() {
return cores;
}
public String getOwner() {
return ownerId;
}
/**
* Sort by name, then by pid.
* No need to sort any further since pids are unique.
*/
public int compareTo(ProcessInfo other) { public int compareTo(ProcessInfo other) {
int nameCompare = getName().compareTo(other.getName()); int nameCompare = getName().compareTo(other.getName());
if (nameCompare != 0) return nameCompare; if (nameCompare != 0) return nameCompare;
else return (getPid() < other.getPid()) ? -1 : 1; else return (getPid() < other.getPid()) ? -1 : 1;
} }
} }

View file

@ -11,9 +11,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui.launching; package org.eclipse.cdt.dsf.gdb.internal.ui.launching;
import org.eclipse.cdt.core.IProcessInfo;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin; import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
import org.eclipse.cdt.dsf.gdb.launching.IProcessExtendedInfo;
import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages; import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
@ -47,7 +47,7 @@ public class ProcessPrompter implements IStatusHandler {
throw new CoreException(error); throw new CoreException(error);
} }
IProcessInfo[] plist = (IProcessInfo[])processList; IProcessExtendedInfo[] plist = (IProcessExtendedInfo[])processList;
if (plist == null) { if (plist == null) {
MessageDialog.openError( MessageDialog.openError(
shell, shell,
@ -78,9 +78,32 @@ public class ProcessPrompter implements IStatusHandler {
*/ */
@Override @Override
public String getText(Object element) { public String getText(Object element) {
IProcessInfo info = (IProcessInfo)element; IProcessExtendedInfo info = (IProcessExtendedInfo)element;
IPath path = new Path(info.getName()); IPath path = new Path(info.getName());
return path.lastSegment() + " - " + info.getPid(); //$NON-NLS-1$ StringBuffer text = new StringBuffer(path.lastSegment());
String owner = info.getOwner();
if (owner != null) {
text.append(" (" + owner + ")"); //$NON-NLS-1$//$NON-NLS-2$
}
text.append(" - " + info.getPid()); //$NON-NLS-1$
String[] cores = info.getCores();
if (cores != null && cores.length > 0) {
if (cores.length == 1) {
text.append(" [core: ");
} else {
text.append(" [cores: ");
}
for (String core : cores) {
text.append(core + ", "); //$NON-NLS-1$
}
// Remove the last comma and space
text.replace(text.length()-2, text.length(), "]"); //$NON-NLS-1$
}
return text.toString();
} }
/* /*
* (non-Javadoc) * (non-Javadoc)
@ -95,7 +118,7 @@ public class ProcessPrompter implements IStatusHandler {
ILabelProvider qprovider = new LabelProvider() { ILabelProvider qprovider = new LabelProvider() {
@Override @Override
public String getText(Object element) { public String getText(Object element) {
IProcessInfo info = (IProcessInfo)element; IProcessExtendedInfo info = (IProcessExtendedInfo)element;
return info.getName(); return info.getName();
} }
/* /*
@ -116,7 +139,7 @@ public class ProcessPrompter implements IStatusHandler {
dialog.setElements(plist); dialog.setElements(plist);
if (dialog.open() == Window.OK) { if (dialog.open() == Window.OK) {
IProcessInfo info = (IProcessInfo)dialog.getFirstResult(); IProcessExtendedInfo info = (IProcessExtendedInfo)dialog.getFirstResult();
if (info != null) { if (info != null) {
return new Integer(info.getPid()); return new Integer(info.getPid());
} }

View file

@ -0,0 +1,47 @@
/*******************************************************************************
* 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.launching;
/**
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*
* @since 4.0
*/
public interface IProcessExtendedInfo {
/**
* Returns the pid of the process, as assigned by the OS.
*/
public int getPid();
/**
* Returns the name of the process, as assigned by the OS.
* Returns null if that information is not available.
*/
public String getName();
/**
* Returns a list of cores on which the process is located.
* This list is all cores on which at least one thread of the
* process is located.
* Returns null if that information is not available.
*/
public String[] getCores();
/**
* Returns the owner of the process. Usually the userId
* that started the process. Returns null if that
* information is not available.
*/
public String getOwner();
}

View file

@ -213,7 +213,7 @@ public class GDBProcesses_7_0 extends AbstractDsfService
/** /**
* Context representing a thread. * Context representing a thread.
* @since 3.1 * @since 4.0
*/ */
@Immutable @Immutable
protected static class MIThreadDMC extends AbstractDMContext protected static class MIThreadDMC extends AbstractDMContext
@ -317,13 +317,24 @@ public class GDBProcesses_7_0 extends AbstractDsfService
} }
} }
/**
* This class provides an implementation of both a process context and process data.
* It is used to be able to return a list of processes including their data all at once.
* @since 4.0
*/
@Immutable @Immutable
private static class MIProcessDMCAndData extends MIProcessDMC implements IThreadDMData { protected static class MIProcessDMCAndData extends MIProcessDMC implements IGdbThreadDMData {
final String fName; final String fName;
// Note that cores are only available from GDB 7.1.
public MIProcessDMCAndData(String sessionId, ICommandControlDMContext controlDmc, String id, String name) { final String[] fCores;
final String fOwner;
public MIProcessDMCAndData(String sessionId, ICommandControlDMContext controlDmc,
String id, String name, String[] cores, String owner) {
super(sessionId, controlDmc, id); super(sessionId, controlDmc, id);
fName = name; fName = name;
fCores = cores;
fOwner = owner;
} }
public String getId() { return getProcId(); } public String getId() { return getProcId(); }
@ -332,17 +343,25 @@ public class GDBProcesses_7_0 extends AbstractDsfService
return true; return true;
} }
public String[] getCores() { return fCores; }
public String getOwner() { return fOwner; }
@Override @Override
public String toString() { return baseToString() + ".proc[" + getId() + "," + getName() + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ public String toString() { return baseToString() +
".proc[" + getId() + "," + getName() + "," + getOwner() + "]"; } //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
return super.equals(obj) && return super.equals(obj) &&
(((MIProcessDMCAndData)obj).fName == null ? fName == null : ((MIProcessDMCAndData)obj).fName.equals(fName)); (((MIProcessDMCAndData)obj).fName == null ? fName == null : ((MIProcessDMCAndData)obj).fName.equals(fName)) &&
(((MIProcessDMCAndData)obj).fOwner == null ? fOwner == null : ((MIProcessDMCAndData)obj).fOwner.equals(fOwner));
} }
@Override @Override
public int hashCode() { return super.hashCode() ^ (fName == null ? 0 : fName.hashCode()); } public int hashCode() { return super.hashCode() ^
(fName == null ? 0 : fName.hashCode()) ^
(fOwner == null ? 0 : fOwner.hashCode()) ; }
} }
/** /**
@ -866,24 +885,36 @@ public class GDBProcesses_7_0 extends AbstractDsfService
} }
private MIProcessDMCAndData[] makeProcessDMCAndData(ICommandControlDMContext controlDmc, IProcessInfo[] processes) { /**
* Create the joint process DMC and data based on IProcessInfo, which is a local listing.
* @since 4.0
*/
protected MIProcessDMCAndData[] makeProcessDMCAndData(ICommandControlDMContext controlDmc, IProcessInfo[] processes) {
MIProcessDMCAndData[] procDmcs = new MIProcessDMCAndData[processes.length]; MIProcessDMCAndData[] procDmcs = new MIProcessDMCAndData[processes.length];
for (int i=0; i<procDmcs.length; i++) { for (int i=0; i<procDmcs.length; i++) {
procDmcs[i] = new MIProcessDMCAndData(controlDmc.getSessionId(), procDmcs[i] = new MIProcessDMCAndData(controlDmc.getSessionId(),
controlDmc, controlDmc,
Integer.toString(processes[i].getPid()), Integer.toString(processes[i].getPid()),
processes[i].getName()); processes[i].getName(),
null, null);
} }
return procDmcs; return procDmcs;
} }
private MIProcessDMCAndData[] makeProcessDMCAndData(ICommandControlDMContext controlDmc, IThreadGroupInfo[] processes) { /**
* Create the joint process DMC and data based on IThreadGroupInfo, which is obtained from GDB.
* @since 4.0
*/
protected MIProcessDMCAndData[] makeProcessDMCAndData(ICommandControlDMContext controlDmc, IThreadGroupInfo[] processes) {
MIProcessDMCAndData[] procDmcs = new MIProcessDMCAndData[processes.length]; MIProcessDMCAndData[] procDmcs = new MIProcessDMCAndData[processes.length];
for (int i=0; i<procDmcs.length; i++) { int i=0;
procDmcs[i] = new MIProcessDMCAndData(controlDmc.getSessionId(), for (IThreadGroupInfo process : processes) {
controlDmc, procDmcs[i++] = new MIProcessDMCAndData(controlDmc.getSessionId(),
processes[i].getGroupId(), controlDmc,
processes[i].getName()); process.getGroupId(),
process.getName(),
process.getCores(),
process.getUser());
} }
return procDmcs; return procDmcs;
} }

View file

@ -32,7 +32,6 @@ 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.CommandFactory;
import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo; 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.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.MIThread;
import org.eclipse.cdt.dsf.mi.service.command.output.MIThreadInfoInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIThreadInfoInfo;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler; import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
@ -44,7 +43,7 @@ import org.eclipse.core.runtime.Status;
* This class implements the IProcesses interface for GDB 7.1 * This class implements the IProcesses interface for GDB 7.1
* which provides new information about cores for threads and processes. * which provides new information about cores for threads and processes.
* *
* @since 3.1 * @since 4.0
*/ */
public class GDBProcesses_7_1 extends GDBProcesses_7_0 { public class GDBProcesses_7_1 extends GDBProcesses_7_0 {
@ -58,6 +57,8 @@ public class GDBProcesses_7_1 extends GDBProcesses_7_0 {
} }
public String[] getCores() { return fCores; } public String[] getCores() { return fCores; }
public String getOwner() { return null; }
} }
private CommandFactory fCommandFactory; private CommandFactory fCommandFactory;
@ -123,6 +124,7 @@ public class GDBProcesses_7_1 extends GDBProcesses_7_0 {
// Starting with GDB 7.1, we can obtain the list of cores a process is currently // 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). // running on (each core that has a thread of that process).
// We have to use -list-thread-groups to obtain that information // We have to use -list-thread-groups to obtain that information
// Note that -list-thread-groups does not show the 'user' field
super.getExecutionData(dmc, new DataRequestMonitor<IThreadDMData>(ImmediateExecutor.getInstance(), rm) { super.getExecutionData(dmc, new DataRequestMonitor<IThreadDMData>(ImmediateExecutor.getInstance(), rm) {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
@ -141,9 +143,7 @@ public class GDBProcesses_7_1 extends GDBProcesses_7_0 {
if (groups != null) { if (groups != null) {
for (IThreadGroupInfo group : groups) { for (IThreadGroupInfo group : groups) {
if (group.getGroupId().equals(groupId)) { if (group.getGroupId().equals(groupId)) {
if (group instanceof IThreadGroupInfoExtension) { cores = group.getCores();
cores = ((IThreadGroupInfoExtension)group).getCores();
}
break; break;
} }
} }

View file

@ -19,7 +19,8 @@ public interface IGDBProcesses extends IMIProcesses {
/** /**
* This interface extends the DSF ThreadDMData to provide * This interface extends the DSF ThreadDMData to provide
* the cores on which a process or a thread is located. * the cores on which a process or a thread is located as well
* as the owner of the process.
* *
* @since 4.0 * @since 4.0
*/ */
@ -32,6 +33,13 @@ public interface IGDBProcesses extends IMIProcesses {
* is located. Returns null if the information is not available. * is located. Returns null if the information is not available.
*/ */
String[] getCores(); String[] getCores();
/**
* @return The owner of the process, usually a user ID. Returns null if the
* information is not available. For threads, this method can return
* null or the owner of the parent process, if available.
*/
String getOwner();
} }
/** /**

View file

@ -152,20 +152,27 @@ import org.eclipse.cdt.dsf.concurrent.Immutable;
public class MIListThreadGroupsInfo extends MIInfo { public class MIListThreadGroupsInfo extends MIInfo {
/**
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface IThreadGroupInfo { public interface IThreadGroupInfo {
String getGroupId(); String getGroupId();
String getPid(); String getPid();
String getName(); String getName();
String getDesciption(); String getDesciption();
} /**@since 4.0 */
String getUser();
/** @since 4.0 */ /**@since 4.0 */
public interface IThreadGroupInfoExtension extends IThreadGroupInfo { String getType();
/**@since 4.0 */
String[] getCores(); String[] getCores();
/**@since 4.0 */
String getExecutable();
} }
@Immutable @Immutable
private static class ThreadGroupInfo implements IThreadGroupInfoExtension { private static class ThreadGroupInfo implements IThreadGroupInfo {
final String fGroupId; final String fGroupId;
final String fDescription; final String fDescription;
final String fName; final String fName;
@ -214,14 +221,9 @@ public class MIListThreadGroupsInfo extends MIInfo {
public String getDesciption() { return fDescription; } public String getDesciption() { return fDescription; }
public String[] getCores() { return fCores; } 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.
@SuppressWarnings("unused")
public String getType() { return fType; }
@SuppressWarnings("unused")
public String getUser() { return fUser; } public String getUser() { return fUser; }
@SuppressWarnings("unused")
public String getType() { return fType; }
public String getExecutable() { return fExecutable; } public String getExecutable() { return fExecutable; }
} }