Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Unified Diff: tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs

Issue 23526064: Resubmit of ChromeDebug extension with fixed license headers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/win/ChromeDebug/ChromeDebug.sln ('k') | tools/win/ChromeDebug/ChromeDebug/AttachDialog.resx » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs
diff --git a/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs
new file mode 100644
index 0000000000000000000000000000000000000000..0476a54d31c60a87a5385b88d1f0f4fbe9565111
--- /dev/null
+++ b/tools/win/ChromeDebug/ChromeDebug/AttachDialog.cs
@@ -0,0 +1,254 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Management;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+using ChromeDebug.LowLevel;
+
+namespace ChromeDebug {
+ // The form that is displayed to allow the user to select processes to attach to. Note that we
+ // cannot interact with the DTE object from here (I assume this is because the dialog is running
+ // on a different thread, although I don't fully understand), so any access to the DTE object
+ // will have to be done through events that get posted back to the main package thread.
+ public partial class AttachDialog : Form {
+ private class ProcessViewItem : ListViewItem {
+ public ProcessViewItem() {
+ Category = ProcessCategory.Other;
+ MachineType = LowLevelTypes.MachineType.UNKNOWN;
+ }
+
+ public string Exe;
+ public int ProcessId;
+ public int SessionId;
+ public string Title;
+ public string DisplayCmdLine;
+ public string[] CmdLineArgs;
+ public ProcessCategory Category;
+ public LowLevelTypes.MachineType MachineType;
+
+ public ProcessDetail Detail;
+ }
+
+ private Dictionary<ProcessCategory, List<ProcessViewItem>> loadedProcessTable = null;
+ private Dictionary<ProcessCategory, ListViewGroup> processGroups = null;
+ private List<int> selectedProcesses = null;
+
+ public AttachDialog() {
+ InitializeComponent();
+
+ loadedProcessTable = new Dictionary<ProcessCategory, List<ProcessViewItem>>();
+ processGroups = new Dictionary<ProcessCategory, ListViewGroup>();
+ selectedProcesses = new List<int>();
+
+ // Create and initialize the groups and process lists only once. On a reset
+ // we don't clear the groups manually, clearing the list view should clear the
+ // groups. And we don't clear the entire processes_ dictionary, only the
+ // individual buckets inside the dictionary.
+ foreach (object value in Enum.GetValues(typeof(ProcessCategory))) {
+ ProcessCategory category = (ProcessCategory)value;
+
+ ListViewGroup group = new ListViewGroup(category.ToGroupTitle());
+ processGroups[category] = group;
+ listViewProcesses.Groups.Add(group);
+
+ loadedProcessTable[category] = new List<ProcessViewItem>();
+ }
+ }
+
+ // Provides an iterator that evaluates to the process ids of the entries that are selected
+ // in the list view.
+ public IEnumerable<int> SelectedItems {
+ get {
+ foreach (ProcessViewItem item in listViewProcesses.SelectedItems)
+ yield return item.ProcessId;
+ }
+ }
+
+ private void AttachDialog_Load(object sender, EventArgs e) {
+ RepopulateListView();
+ }
+
+ // Remove command line arguments that we aren't interested in displaying as part of the command
+ // line of the process.
+ private string[] FilterCommandLine(string[] args) {
+ Func<string, int, bool> AllowArgument = delegate(string arg, int index) {
+ if (index == 0)
+ return false;
+ return !arg.StartsWith("--force-fieldtrials", StringComparison.CurrentCultureIgnoreCase);
+ };
+
+ // The force-fieldtrials command line option makes the command line view useless, so remove
+ // it. Also remove args[0] since that is the process name.
+ args = args.Where(AllowArgument).ToArray();
+ return args;
+ }
+
+ private void ReloadNativeProcessInfo() {
+ foreach (List<ProcessViewItem> list in loadedProcessTable.Values) {
+ list.Clear();
+ }
+
+ Process[] processes = Process.GetProcesses();
+ foreach (Process p in processes) {
+ ProcessViewItem item = new ProcessViewItem();
+ try {
+ item.Detail = new ProcessDetail(p.Id);
+ if (item.Detail.CanReadPeb && item.Detail.CommandLine != null) {
+ item.CmdLineArgs = Utility.SplitArgs(item.Detail.CommandLine);
+ item.DisplayCmdLine = GetFilteredCommandLineString(item.CmdLineArgs);
+ }
+ item.MachineType = item.Detail.MachineType;
+ }
+ catch (Exception) {
+ // Generally speaking, an exception here means the process is privileged and we cannot
+ // get any information about the process. For those processes, we will just display the
+ // information that the Framework gave us in the Process structure.
+ }
+
+ // If we don't have the machine type, its privilege level is high enough that we won't be
+ // able to attach a debugger to it anyway, so skip it.
+ if (item.MachineType == LowLevelTypes.MachineType.UNKNOWN)
+ continue;
+
+ item.ProcessId = p.Id;
+ item.SessionId = p.SessionId;
+ item.Title = p.MainWindowTitle;
+ item.Exe = p.ProcessName;
+ if (item.CmdLineArgs != null)
+ item.Category = DetermineProcessCategory(item.CmdLineArgs);
+
+ List<ProcessViewItem> items = loadedProcessTable[item.Category];
+ item.Group = processGroups[item.Category];
+ items.Add(item);
+ }
+ }
+
+ // Filter the command line arguments to remove extraneous arguments that we don't wish to
+ // display.
+ private string GetFilteredCommandLineString(string[] args) {
+ if (args == null || args.Length == 0)
+ return string.Empty;
+
+ args = FilterCommandLine(args);
+ return string.Join(" ", args, 0, args.Length);
+ }
+
+ // Using a heuristic based on the command line, tries to determine what type of process this
+ // is.
+ private ProcessCategory DetermineProcessCategory(string[] cmdline) {
+ if (cmdline == null || cmdline.Length == 0)
+ return ProcessCategory.Other;
+
+ string file = Path.GetFileName(cmdline[0]);
+ if (file.Equals("delegate_execute.exe", StringComparison.CurrentCultureIgnoreCase))
+ return ProcessCategory.DelegateExecute;
+ else if (file.Equals("chrome.exe", StringComparison.CurrentCultureIgnoreCase)) {
+ if (cmdline.Contains("--type=renderer"))
+ return ProcessCategory.Renderer;
+ else if (cmdline.Contains("--type=plugin") || cmdline.Contains("--type=ppapi"))
+ return ProcessCategory.Plugin;
+ else if (cmdline.Contains("--type=gpu-process"))
+ return ProcessCategory.Gpu;
+ else if (cmdline.Contains("--type=service"))
+ return ProcessCategory.Service;
+ else if (cmdline.Any(arg => arg.StartsWith("-ServerName")))
+ return ProcessCategory.MetroViewer;
+ else
+ return ProcessCategory.Browser;
+ } else
+ return ProcessCategory.Other;
+ }
+
+ private void InsertCategoryItems(ProcessCategory category) {
+ foreach (ProcessViewItem item in loadedProcessTable[category]) {
+ item.SubItems.Add(item.Exe);
+ item.SubItems.Add(item.ProcessId.ToString());
+ item.SubItems.Add(item.Title);
+ item.SubItems.Add(item.MachineType.ToString());
+ item.SubItems.Add(item.SessionId.ToString());
+ item.SubItems.Add(item.DisplayCmdLine);
+ listViewProcesses.Items.Add(item);
+ }
+ }
+
+ private void AutoResizeColumns() {
+ // First adjust to the width of the headers, since it's fast.
+ listViewProcesses.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
+
+ // Save the widths so we can use them again later.
+ List<int> widths = new List<int>();
+ foreach (ColumnHeader header in listViewProcesses.Columns)
+ widths.Add(header.Width);
+
+ // Now let Windows do the slow adjustment based on the content.
+ listViewProcesses.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
+
+ // Finally, iterate over each column, and resize those columns that just got smaller.
+ listViewProcesses.Columns[0].Width = 0;
+ int total = 0;
+ for (int i = 1; i < listViewProcesses.Columns.Count; ++i) {
+ // Resize to the largest of the two, but don't let it go over a pre-defined maximum.
+ int max = Math.Max(listViewProcesses.Columns[i].Width, widths[i]);
+ int capped = Math.Min(max, 300);
+
+ // We do still want to fill up the available space in the list view however, so if we're
+ // under then we can fill.
+ int globalMinWidth = listViewProcesses.Width - SystemInformation.VerticalScrollBarWidth;
+ if (i == listViewProcesses.Columns.Count - 1 && (total + capped) < (globalMinWidth - 4))
+ capped = globalMinWidth - total - 4;
+
+ total += capped;
+ listViewProcesses.Columns[i].Width = capped;
+ }
+ }
+
+ private void RepopulateListView() {
+ listViewProcesses.Items.Clear();
+
+ ReloadNativeProcessInfo();
+
+ InsertCategoryItems(ProcessCategory.Browser);
+ InsertCategoryItems(ProcessCategory.Renderer);
+ InsertCategoryItems(ProcessCategory.Gpu);
+ InsertCategoryItems(ProcessCategory.Plugin);
+ InsertCategoryItems(ProcessCategory.MetroViewer);
+ InsertCategoryItems(ProcessCategory.Service);
+ InsertCategoryItems(ProcessCategory.DelegateExecute);
+ if (!checkBoxOnlyChrome.Checked)
+ InsertCategoryItems(ProcessCategory.Other);
+
+ AutoResizeColumns();
+ }
+
+ private void buttonRefresh_Click(object sender, EventArgs e) {
+ RepopulateListView();
+ }
+
+ private void buttonAttach_Click(object sender, EventArgs e) {
+ System.Diagnostics.Debug.WriteLine("Closing dialog.");
+ this.Close();
+ }
+
+ private void checkBoxOnlyChrome_CheckedChanged(object sender, EventArgs e) {
+ if (!checkBoxOnlyChrome.Checked)
+ InsertCategoryItems(ProcessCategory.Other);
+ else {
+ foreach (ProcessViewItem item in loadedProcessTable[ProcessCategory.Other]) {
+ listViewProcesses.Items.Remove(item);
+ }
+ }
+ }
+ }
+}
« no previous file with comments | « tools/win/ChromeDebug/ChromeDebug.sln ('k') | tools/win/ChromeDebug/ChromeDebug/AttachDialog.resx » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698