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

Side by Side Diff: visual_studio/NativeClientVSAddIn/NativeClientVSAddIn/PluginDebuggerBase.cs

Issue 10836143: Refactored the VS add-in (Closed) Base URL: https://nativeclient-sdk.googlecode.com/svn/trunk/src
Patch Set: Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 namespace NativeClientVSAddIn
6 {
7 using System;
8 using System.Collections.Generic;
9 using System.Windows.Forms;
10
11 using EnvDTE;
12 using EnvDTE80;
13
14 /// <summary>
15 /// This is a base class for encapsulating functionality related to attaching a debugger
16 /// to a nacl/pepper plug-in. This base class mostly contains functionality r elated to finding
17 /// the plug-in.
18 /// </summary>
19 public class PluginDebuggerBase : IDisposable
20 {
21 /// <summary>
22 /// This is the initial number of milliseconds to wait between
23 /// checking for plug-in processes to attach the debugger to.
24 /// </summary>
25 private const int InitialPluginCheckFrequency = 1000;
26
27 /// <summary>
28 /// After a plug-in has been found, we slow the frequency of checking
29 /// for new ones. This value is in milliseconds.
30 /// </summary>
31 private const int RelaxedPluginCheckFrequency = 5000;
32
33 /// <summary>
34 /// Timer object that periodically calls a function to look for the plug-in process to debug.
35 /// </summary>
36 private Timer pluginFinderTimer_;
37
38 /// <summary>
39 /// List of process IDs which we should not attempt to attach the debugger t o. Mainly this
40 /// list contains process IDs of processes we have already attached to.
41 /// </summary>
42 private List<uint> pluginFinderForbiddenPids_;
43
44 /// <summary>
45 /// Process searcher class which allows us to query the system for running p rocesses.
46 /// </summary>
47 private ProcessSearcher processSearcher_;
48
49 /// <summary>
50 /// The main process of chrome that was started by Visual Studio during debu gging.
51 /// </summary>
52 private System.Diagnostics.Process debuggedChromeMainProcess_;
53
54 /// <summary>
55 /// Constructs the PluginDebuggerHelper.
56 /// </summary>
57 /// <param name="dte">Automation object from Visual Studio.</param>
58 /// <param name="properties">PropertyManager set to a valid project/platform .</param>
59 protected PluginDebuggerBase(DTE2 dte, PropertyManager properties)
60 {
61 if (dte == null)
62 {
63 throw new ArgumentNullException("dte");
64 }
65
66 if (properties == null)
67 {
68 throw new ArgumentNullException("properties");
69 }
70
71 Dte = dte;
72
73 // Every second, check for a new instance of the plug-in to attach to.
74 // Note that although the timer itself runs on a separate thread, the even t
75 // is fired from the main UI thread during message processing, thus we do not
76 // need to worry about threading issues.
77 pluginFinderTimer_ = new Timer();
78 pluginFinderTimer_.Tick += new EventHandler(FindAndAttachToPlugin);
79 pluginFinderForbiddenPids_ = new List<uint>();
80 processSearcher_ = new ProcessSearcher();
81
82 pluginFinderTimer_.Interval = InitialPluginCheckFrequency;
83 pluginFinderTimer_.Start();
84 }
85
86 /// <summary>
87 /// Finalizer. Should clean up unmanaged resources. Should not be overriden in derived classes.
88 /// </summary>
89 ~PluginDebuggerBase()
90 {
91 Dispose(false);
92 }
93
94 /// <summary>
95 /// An event indicating a target plug-in was found on the system.
96 /// </summary>
97 public event EventHandler<PluginFoundEventArgs> PluginFoundEvent;
98
99 /// <summary>
100 /// Gets or sets a value indicating whether this object has been disposed of already.
101 /// </summary>
102 protected bool Disposed { get; set; }
103
104 /// <summary>
105 /// Gets or sets the main visual studio object.
106 /// </summary>
107 protected DTE2 Dte { get; set; }
108
109 /// <summary>
110 /// Disposes the object when called by user code (not directly by garbage co llector).
111 /// </summary>
112 public void Dispose()
113 {
114 Dispose(true);
115 GC.SuppressFinalize(this);
116 }
117
118 /// <summary>
119 /// This is called periodically by the Visual Studio UI thread to look for o ur plug-in process
120 /// and attach the debugger to it. The call is triggered by the pluginFinde rTimer_ object.
121 /// </summary>
122 /// <param name="unused">The parameter is not used.</param>
123 /// <param name="unused1">The parameter is not used.</param>
124 public void FindAndAttachToPlugin(object unused, EventArgs unused1)
125 {
126 // This function is called by the main Visual Studio event loop and we may have put the event
127 // on the queue just before disposing it meaning this could be called afte r we've disposed.
128 if (Disposed)
129 {
130 return;
131 }
132
133 StringComparison ignoreCase = StringComparison.InvariantCultureIgnoreCase;
134
135 // Set the main chrome process that was started by visual studio. If it's not chrome
136 // or not found then we have no business attaching to any plug-ins so retu rn.
137 if (debuggedChromeMainProcess_ == null)
138 {
139 foreach (Process proc in Dte.Debugger.DebuggedProcesses)
140 {
141 if (proc.Name.EndsWith(Strings.ChromeProcessName, ignoreCase))
142 {
143 debuggedChromeMainProcess_ = System.Diagnostics.Process.GetProcessBy Id(proc.ProcessID);
144 break;
145 }
146 }
147
148 return;
149 }
150
151 // Get the list of all descendants of the main chrome process.
152 uint mainChromeProcId = (uint)debuggedChromeMainProcess_.Id;
153 List<ProcessInfo> chromeDescendants = processSearcher_.GetDescendants(main ChromeProcId);
154 string mainChromeFlags = chromeDescendants.Find(p => p.ID == mainChromePro cId).CommandLine;
155
156 // From the list of descendants, find the plug-in by it's command line arg uments and
157 // process name as well as not being attached to already.
158 List<ProcessInfo> plugins = chromeDescendants.FindAll(p =>
159 IsPluginProcess(p, mainChromeFlags) && !pluginFinderForbiddenPids_.Con tains(p.ID));
160
161 // Attach to all plug-ins that we found.
162 foreach (ProcessInfo process in plugins)
163 {
164 // If we are attaching to a plug-in, add it to the forbidden list to ens ure we
165 // don't try to attach again later.
166 pluginFinderForbiddenPids_.Add(process.ID);
167 PluginFoundEvent.Invoke(this, new PluginFoundEventArgs(process.ID));
168
169 // Slow down the frequency of checks for new plugins.
170 pluginFinderTimer_.Interval = RelaxedPluginCheckFrequency;
171 }
172 }
173
174 /// <summary>
175 /// Disposes the object. If disposing is false then this has been called by garbage collection,
176 /// and we shouldn't reference managed objects.
177 /// </summary>
178 /// <param name="disposing">True if user call to Dispose, false if garbase c ollection.</param>
179 protected virtual void Dispose(bool disposing)
180 {
181 if (!Disposed && disposing)
182 {
183 pluginFinderTimer_.Stop();
184 }
185
186 Disposed = true;
187 }
188
189 /// <summary>
190 /// Called to check if a process is a valid plugin to attach to.
191 /// </summary>
192 /// <param name="proc">Contains information about the process in question.</ param>
193 /// <param name="mainChromeFlags">Flags on the main Chrome process.</param>
194 /// <returns>True if we should attach to the process.</returns>
195 protected virtual bool IsPluginProcess(ProcessInfo proc, string mainChromeFl ags)
196 {
197 throw new InvalidOperationException();
198 }
199
200 /// <summary>
201 /// The event arguments when a plug-in is found.
202 /// </summary>
203 public class PluginFoundEventArgs : EventArgs
204 {
205 /// <summary>
206 /// Construct the PluginFoundEventArgs.
207 /// </summary>
208 /// <param name="pid">Process ID of the found plug-in.</param>
209 public PluginFoundEventArgs(uint pid)
210 {
211 this.ProcessID = pid;
212 }
213
214 /// <summary>
215 /// Gets or sets process ID of the found plug-in.
216 /// </summary>
217 public uint ProcessID { get; set; }
218 }
219 }
220 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698