From 2d499636f4096bd08b14ba54e9da4a9266e0a2b7 Mon Sep 17 00:00:00 2001 From: Marc Khouzam Date: Fri, 30 Jul 2010 17:45:41 +0000 Subject: [PATCH] Bug 318230: Show cores and user name when listing processes to attach too. --- .../ui/actions/GdbConnectCommand.java | 30 ++++++--- .../gdb/internal/ui/actions/ProcessInfo.java | 48 ++++++++------- .../ui/launching/ProcessPrompter.java | 35 +++++++++-- .../gdb/launching/IProcessExtendedInfo.java | 47 ++++++++++++++ .../cdt/dsf/gdb/service/GDBProcesses_7_0.java | 61 ++++++++++++++----- .../cdt/dsf/gdb/service/GDBProcesses_7_1.java | 10 +-- .../cdt/dsf/gdb/service/IGDBProcesses.java | 10 ++- .../output/MIListThreadGroupsInfo.java | 26 ++++---- 8 files changed, 199 insertions(+), 68 deletions(-) create mode 100644 dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/IProcessExtendedInfo.java diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbConnectCommand.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbConnectCommand.java index 3cda1425c76..a9efcf9ad8f 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbConnectCommand.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/GdbConnectCommand.java @@ -15,7 +15,6 @@ import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.RejectedExecutionException; -import org.eclipse.cdt.core.IProcessInfo; import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; 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.gdb.actions.IConnect; 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.service.IGDBProcesses.IGdbThreadDMData; import org.eclipse.cdt.dsf.mi.service.IMIProcesses; import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.dsf.service.DsfSession; @@ -87,10 +88,10 @@ public class GdbConnectCommand implements IConnect { class PromptForPidJob extends Job { // The list of processes used in the case of an ATTACH session - IProcessInfo[] fProcessList = null; + IProcessExtendedInfo[] fProcessList = null; DataRequestMonitor fRequestMonitor; - public PromptForPidJob(String name, IProcessInfo[] procs, DataRequestMonitor rm) { + public PromptForPidJob(String name, IProcessExtendedInfo[] procs, DataRequestMonitor rm) { super(name); fProcessList = procs; fRequestMonitor = rm; @@ -157,14 +158,14 @@ public class GdbConnectCommand implements IConnect { @Override protected void handleSuccess() { - final List procInfoList = new ArrayList(); + final List procInfoList = new ArrayList(); final CountingRequestMonitor countingRm = new CountingRequestMonitor(fExecutor, rm) { @Override protected void handleSuccess() { 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(fExecutor, rm) { @Override protected void handleSuccess() { @@ -190,7 +191,13 @@ public class GdbConnectCommand implements IConnect { pid = Integer.parseInt(processData.getId()); } 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. @@ -215,12 +222,19 @@ public class GdbConnectCommand implements IConnect { new DataRequestMonitor (fExecutor, countingRm) { @Override protected void handleSuccess() { + IThreadDMData processData = getData(); int pid = 0; try { - pid = Integer.parseInt(getData().getId()); + pid = Integer.parseInt(processData.getId()); } 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(); } }); diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ProcessInfo.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ProcessInfo.java index aeb624ece79..8ec9b08b961 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ProcessInfo.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/actions/ProcessInfo.java @@ -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 * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,46 +10,52 @@ *******************************************************************************/ 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.gdb.launching.IProcessExtendedInfo; @Immutable -class ProcessInfo implements IProcessInfo, Comparable { +class ProcessInfo implements IProcessExtendedInfo, Comparable { private final int pid; private final String name; - - public ProcessInfo(String pidString, String name) { - int tmpPid = 0; - try { - tmpPid = Integer.parseInt(pidString); - } catch (NumberFormatException e) { - } - this.pid = tmpPid; - this.name = name; - } + private final String[] cores; + private final String ownerId; public ProcessInfo(int pid, String name) { - this.pid = pid; - this.name = name; + this(pid, name, null, null); + } + + /** @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() { return name; } - /** - * @see org.eclipse.cdt.core.IProcessInfo#getPid() - */ public int getPid() { 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) { int nameCompare = getName().compareTo(other.getName()); if (nameCompare != 0) return nameCompare; else return (getPid() < other.getPid()) ? -1 : 1; } + } \ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/launching/ProcessPrompter.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/launching/ProcessPrompter.java index 62ee71f7baf..81298f4c769 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/launching/ProcessPrompter.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/launching/ProcessPrompter.java @@ -11,9 +11,9 @@ *******************************************************************************/ 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.dsf.gdb.internal.ui.GdbUIPlugin; +import org.eclipse.cdt.dsf.gdb.launching.IProcessExtendedInfo; import org.eclipse.cdt.dsf.gdb.launching.LaunchMessages; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -47,7 +47,7 @@ public class ProcessPrompter implements IStatusHandler { throw new CoreException(error); } - IProcessInfo[] plist = (IProcessInfo[])processList; + IProcessExtendedInfo[] plist = (IProcessExtendedInfo[])processList; if (plist == null) { MessageDialog.openError( shell, @@ -78,9 +78,32 @@ public class ProcessPrompter implements IStatusHandler { */ @Override public String getText(Object element) { - IProcessInfo info = (IProcessInfo)element; + IProcessExtendedInfo info = (IProcessExtendedInfo)element; 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) @@ -95,7 +118,7 @@ public class ProcessPrompter implements IStatusHandler { ILabelProvider qprovider = new LabelProvider() { @Override public String getText(Object element) { - IProcessInfo info = (IProcessInfo)element; + IProcessExtendedInfo info = (IProcessExtendedInfo)element; return info.getName(); } /* @@ -116,7 +139,7 @@ public class ProcessPrompter implements IStatusHandler { dialog.setElements(plist); if (dialog.open() == Window.OK) { - IProcessInfo info = (IProcessInfo)dialog.getFirstResult(); + IProcessExtendedInfo info = (IProcessExtendedInfo)dialog.getFirstResult(); if (info != null) { return new Integer(info.getPid()); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/IProcessExtendedInfo.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/IProcessExtendedInfo.java new file mode 100644 index 00000000000..6005946ef39 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/IProcessExtendedInfo.java @@ -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(); +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java index 5d6d481e7c9..2e97089b936 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_0.java @@ -213,7 +213,7 @@ public class GDBProcesses_7_0 extends AbstractDsfService /** * Context representing a thread. - * @since 3.1 + * @since 4.0 */ @Immutable 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 - private static class MIProcessDMCAndData extends MIProcessDMC implements IThreadDMData { + protected static class MIProcessDMCAndData extends MIProcessDMC implements IGdbThreadDMData { final String fName; - - public MIProcessDMCAndData(String sessionId, ICommandControlDMContext controlDmc, String id, String name) { + // Note that cores are only available from GDB 7.1. + final String[] fCores; + final String fOwner; + + public MIProcessDMCAndData(String sessionId, ICommandControlDMContext controlDmc, + String id, String name, String[] cores, String owner) { super(sessionId, controlDmc, id); fName = name; + fCores = cores; + fOwner = owner; } public String getId() { return getProcId(); } @@ -332,17 +343,25 @@ public class GDBProcesses_7_0 extends AbstractDsfService return true; } + public String[] getCores() { return fCores; } + + public String getOwner() { return fOwner; } + @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 public boolean equals(Object 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 - 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]; for (int i=0; i(ImmediateExecutor.getInstance(), rm) { @Override protected void handleSuccess() { @@ -141,9 +143,7 @@ public class GDBProcesses_7_1 extends GDBProcesses_7_0 { if (groups != null) { for (IThreadGroupInfo group : groups) { if (group.getGroupId().equals(groupId)) { - if (group instanceof IThreadGroupInfoExtension) { - cores = ((IThreadGroupInfoExtension)group).getCores(); - } + cores = group.getCores(); break; } } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBProcesses.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBProcesses.java index c17f52b4324..22bf1c11434 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBProcesses.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBProcesses.java @@ -19,7 +19,8 @@ public interface IGDBProcesses extends IMIProcesses { /** * 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 */ @@ -32,6 +33,13 @@ public interface IGDBProcesses extends IMIProcesses { * is located. Returns null if the information is not available. */ 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(); } /** diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListThreadGroupsInfo.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListThreadGroupsInfo.java index 0fa2177c975..1385333e21f 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListThreadGroupsInfo.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/output/MIListThreadGroupsInfo.java @@ -152,20 +152,27 @@ import org.eclipse.cdt.dsf.concurrent.Immutable; 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 { String getGroupId(); String getPid(); String getName(); String getDesciption(); - } - - /** @since 4.0 */ - public interface IThreadGroupInfoExtension extends IThreadGroupInfo { + /**@since 4.0 */ + String getUser(); + /**@since 4.0 */ + String getType(); + /**@since 4.0 */ String[] getCores(); + /**@since 4.0 */ + String getExecutable(); } @Immutable - private static class ThreadGroupInfo implements IThreadGroupInfoExtension { + private static class ThreadGroupInfo implements IThreadGroupInfo { final String fGroupId; final String fDescription; final String fName; @@ -214,14 +221,9 @@ public class MIListThreadGroupsInfo extends MIInfo { public String getDesciption() { return fDescription; } 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; } - @SuppressWarnings("unused") + + public String getType() { return fType; } public String getExecutable() { return fExecutable; } }