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

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

Issue 10831030: NaCl settings and completed install scripts. (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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 namespace NativeClientVSAddIn 5 namespace NativeClientVSAddIn
6 { 6 {
7 using System; 7 using System;
8 using System.Collections.Generic; 8 using System.Collections.Generic;
9 using System.IO; 9 using System.IO;
10 using System.Linq; 10 using System.Linq;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 private string gdbInitFileName_; 84 private string gdbInitFileName_;
85 85
86 /// <summary> 86 /// <summary>
87 /// The platform that the start-up project is currently configured with (NaC l or PPAPI). 87 /// The platform that the start-up project is currently configured with (NaC l or PPAPI).
88 /// </summary> 88 /// </summary>
89 private ProjectPlatformType projectPlatformType_; 89 private ProjectPlatformType projectPlatformType_;
90 90
91 /// <summary> 91 /// <summary>
92 /// When debugging is started this is the web server process object. 92 /// When debugging is started this is the web server process object.
93 /// </summary> 93 /// </summary>
94 private System.Diagnostics.Process webServer_ = null; 94 private System.Diagnostics.Process webServer_;
95 95
96 /// <summary> 96 /// <summary>
97 /// Visual Studio output window pane that captures output from the web serve r. 97 /// Visual Studio output window pane that captures output from the web serve r.
98 /// </summary> 98 /// </summary>
99 private OutputWindowPane webServerOutputPane_ = null; 99 private OutputWindowPane webServerOutputPane_;
100 100
101 /// <summary> 101 /// <summary>
102 /// Path to the web server executable. 102 /// Path to the web server executable.
103 /// </summary> 103 /// </summary>
104 private string webServerExecutable_; 104 private string webServerExecutable_;
105 105
106 /// <summary> 106 /// <summary>
107 /// Arguments to be passed to the web server executable to start it. 107 /// Arguments to be passed to the web server executable to start it.
108 /// </summary> 108 /// </summary>
109 private string webServerArguments_; 109 private string webServerArguments_;
110 110
111 /// <summary> 111 /// <summary>
112 /// Timer object that periodically calls a function to look for the plug-in process to debug. 112 /// Timer object that periodically calls a function to look for the plug-in process to debug.
113 /// </summary> 113 /// </summary>
114 private Timer pluginFinderTimer_; 114 private Timer pluginFinderTimer_;
115 115
116 /// <summary> 116 /// <summary>
117 /// List of process IDs which we should not attempt to attach the debugger t o. Mainly this 117 /// List of process IDs which we should not attempt to attach the debugger t o. Mainly this
118 /// list contains process IDs of processes we have already attached to. 118 /// list contains process IDs of processes we have already attached to.
119 /// </summary> 119 /// </summary>
120 private List<uint> pluginFinderForbiddenPids_; 120 private List<uint> pluginFinderForbiddenPids_;
121 121
122 /// <summary> 122 /// <summary>
123 /// Process searcher class which allows us to query the system for running p rocesses. 123 /// Process searcher class which allows us to query the system for running p rocesses.
124 /// </summary> 124 /// </summary>
125 private ProcessSearcher processSearcher_; 125 private ProcessSearcher processSearcher_;
126 126
127 /// <summary> 127 /// <summary>
128 /// The main process of chrome that was started by Visual Studio during debu gging.
129 /// </summary>
130 private System.Diagnostics.Process debuggedChromeMainProcess_;
131
132 /// <summary>
128 /// Constructs the PluginDebuggerHelper. 133 /// Constructs the PluginDebuggerHelper.
129 /// Object is not usable until LoadProjectSettings() is called. 134 /// Object is not usable until LoadProjectSettings() is called.
130 /// </summary> 135 /// </summary>
131 /// <param name="dte">Automation object from Visual Studio.</param> 136 /// <param name="dte">Automation object from Visual Studio.</param>
132 public PluginDebuggerHelper(DTE2 dte) 137 public PluginDebuggerHelper(DTE2 dte)
133 { 138 {
134 if (dte == null) 139 if (dte == null)
135 { 140 {
136 throw new ArgumentNullException("dte"); 141 throw new ArgumentNullException("dte");
137 } 142 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 { 223 {
219 projectPlatformType_ = ProjectPlatformType.Other; 224 projectPlatformType_ = ProjectPlatformType.Other;
220 return false; 225 return false;
221 } 226 }
222 227
223 // We only support certain project types (e.g. C/C++ projects). Otherwise we fail. 228 // We only support certain project types (e.g. C/C++ projects). Otherwise we fail.
224 // If supported, extract necessary information from specific project type. 229 // If supported, extract necessary information from specific project type.
225 if (Utility.IsVisualCProject(startProject)) 230 if (Utility.IsVisualCProject(startProject))
226 { 231 {
227 VCConfiguration config = Utility.GetActiveVCConfiguration(startProject); 232 VCConfiguration config = Utility.GetActiveVCConfiguration(startProject);
233 IVCRulePropertyStorage general = config.Rules.Item("ConfigurationGeneral ");
234 VCLinkerTool linker = config.Tools.Item("VCLinkerTool");
228 VCProject vcproj = (VCProject)startProject.Object; 235 VCProject vcproj = (VCProject)startProject.Object;
229 VCLinkerTool linker = config.Tools.Item("VCLinkerTool"); 236 sdkRootDirectory_ = general.GetEvaluatedPropertyValue("VSNaClSDKRoot");
237 pluginOutputDirectory_ = config.Evaluate(config.OutputDirectory);
238 pluginAssembly_ = config.Evaluate(linker.OutputFile);
230 pluginProjectDirectory_ = vcproj.ProjectDirectory; // Macros not allowe d here. 239 pluginProjectDirectory_ = vcproj.ProjectDirectory; // Macros not allowe d here.
231 pluginAssembly_ = config.Evaluate(linker.OutputFile);
232 pluginOutputDirectory_ = config.Evaluate(config.OutputDirectory);
233 } 240 }
234 else 241 else
235 { 242 {
236 return false; 243 return false;
237 } 244 }
238 245
239 // TODO(tysand): Add user option to specify this. 246 if (string.IsNullOrEmpty(sdkRootDirectory_))
240 int webServerPort = 5103;
241 sdkRootDirectory_ = Environment.GetEnvironmentVariable(Strings.SDKPathEnvi ronmentVariable);
242 if (sdkRootDirectory_ == null)
243 { 247 {
244 MessageBox.Show( 248 MessageBox.Show(
245 string.Format(Strings.SDKPathNotSetFormat, Strings.SDKPathEnvironmen tVariable)); 249 string.Format(Strings.SDKPathNotSetFormat, Strings.SDKPathEnvironmen tVariable));
246 return false; 250 return false;
247 } 251 }
248 252
249 sdkRootDirectory_ = sdkRootDirectory_.TrimEnd("/\\".ToArray<char>()); 253 sdkRootDirectory_ = sdkRootDirectory_.TrimEnd("/\\".ToArray<char>());
250 254
255 // TODO(tysand): Add user option to specify this.
256 int webServerPort = 5103;
251 webServerExecutable_ = "python.exe"; 257 webServerExecutable_ = "python.exe";
252 webServerArguments_ = string.Format( 258 webServerArguments_ = string.Format(
253 "{0}\\examples\\httpd.py --no_dir_check {1}", 259 "{0}\\examples\\httpd.py --no_dir_check {1}",
254 sdkRootDirectory_, 260 sdkRootDirectory_,
255 webServerPort); 261 webServerPort);
256 262
257 // TODO(tysand): Update this to nacl-gdb when it is ready. Should be able to remove irtPath_. 263 // TODO(tysand): Update this to nacl-gdb when it is ready. Should be able to remove irtPath_.
258 gdbPath_ = sdkRootDirectory_ + @"\customGDB\gdb.exe"; 264 gdbPath_ = sdkRootDirectory_ + @"\gdb-remote-x86-64\gdb.exe";
259 irtPath_ = sdkRootDirectory_ + @"\tools\irt_x86_64.nexe"; 265 irtPath_ = sdkRootDirectory_ + @"\tools\irt_x86_64.nexe";
260 266
267 debuggedChromeMainProcess_ = null;
268
261 isProperlyInitialized_ = true; 269 isProperlyInitialized_ = true;
262 return true; 270 return true;
263 } 271 }
264 272
265 /// <summary> 273 /// <summary>
266 /// This function should be called to start the PluginDebuggerHelper functio nality. 274 /// This function should be called to start the PluginDebuggerHelper functio nality.
267 /// </summary> 275 /// </summary>
268 public void StartDebugging() 276 public void StartDebugging()
269 { 277 {
270 if (!isProperlyInitialized_) 278 if (!isProperlyInitialized_)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 { 330 {
323 File.Delete(gdbInitFileName_); 331 File.Delete(gdbInitFileName_);
324 } 332 }
325 333
326 gdbProcess_ = null; 334 gdbProcess_ = null;
327 } 335 }
328 } 336 }
329 337
330 /// <summary> 338 /// <summary>
331 /// This is called periodically by the Visual Studio UI thread to look for o ur plug-in process 339 /// This is called periodically by the Visual Studio UI thread to look for o ur plug-in process
332 /// and attach the debugger to it. The call is triggered by the pluginFinde rTimer_ object 340 /// and attach the debugger to it. The call is triggered by the pluginFinde rTimer_ object.
333 /// </summary> 341 /// </summary>
334 /// <param name="unused">The parameter is not used.</param> 342 /// <param name="unused">The parameter is not used.</param>
335 /// <param name="unused1">The parameter is not used.</param> 343 /// <param name="unused1">The parameter is not used.</param>
336 private void FindAndAttachToPlugin(object unused, EventArgs unused1) 344 private void FindAndAttachToPlugin(object unused, EventArgs unused1)
337 { 345 {
338 string processNameTarget; 346 StringComparison ignoreCase = StringComparison.InvariantCultureIgnoreCase;
339 string typeFlagTarget; 347
340 string identifierFlagTarget; 348 // Set the main chrome process that was started by visual studio. If it's not chrome
349 // or not found then we have no business attaching to any plug-ins so retu rn.
350 if (debuggedChromeMainProcess_ == null)
351 {
352 foreach (Process proc in dte_.Debugger.DebuggedProcesses)
353 {
354 if (proc.Name.EndsWith(Strings.ChromeProcessName, ignoreCase))
355 {
356 debuggedChromeMainProcess_ = System.Diagnostics.Process.GetProcessBy Id(proc.ProcessID);
357 break;
358 }
359 }
360
361 return;
362 }
363
364 // Get the list of all descendants of the main chrome process.
365 uint mainChromeProcId = (uint)debuggedChromeMainProcess_.Id;
366 List<ProcessInfo> chromeDescendants = processSearcher_.GetDescendants(main ChromeProcId);
367
368 // From the list of descendants, find the plug-in by it's command line arg uments and
369 // process name as well as not being attached to already.
370 List<ProcessInfo> plugins;
341 switch (projectPlatformType_) 371 switch (projectPlatformType_)
342 { 372 {
343 case ProjectPlatformType.Pepper: 373 case ProjectPlatformType.Pepper:
344 processNameTarget = Strings.PepperProcessName; 374 string identifierFlagTarget =
345 typeFlagTarget = Strings.PepperProcessTypeFlag;
346 identifierFlagTarget =
347 string.Format(Strings.PepperProcessPluginFlagFormat, pluginAssembl y_); 375 string.Format(Strings.PepperProcessPluginFlagFormat, pluginAssembl y_);
376 plugins = chromeDescendants.FindAll(p =>
377 p.Name.Equals(Strings.ChromeProcessName, ignoreCase) &&
378 p.CommandLine.Contains(Strings.ChromeRendererFlag, ignoreCase) &&
379 p.CommandLine.Contains(identifierFlagTarget, ignoreCase) &&
380 !pluginFinderForbiddenPids_.Contains(p.ID));
348 break; 381 break;
349 case ProjectPlatformType.NaCl: 382 case ProjectPlatformType.NaCl:
350 processNameTarget = Strings.NaClProcessName; 383 plugins = chromeDescendants.FindAll(p =>
351 typeFlagTarget = Strings.NaClProcessTypeFlag; 384 p.Name.Equals(Strings.NaClProcessName, ignoreCase) &&
352 identifierFlagTarget = Strings.NaClDebugFlag; 385 p.CommandLine.Contains(Strings.NaClLoaderFlag, ignoreCase) &&
386 !pluginFinderForbiddenPids_.Contains(p.ID));
353 break; 387 break;
354 default: 388 default:
355 return; 389 return;
356 } 390 }
357 391
358 // To identify our target plug-in we look for: its process name (e.g. chro me.exe), 392 // Attach to all plug-ins that we found.
359 // identifying command line arguments (e.g. --type=renderer), not already attached 393 foreach (ProcessInfo process in plugins)
360 // to by us, and must be a descendant process of this instance of Visual S tudio.
361 List<ProcessInfo> results = processSearcher_.GetResultsByName(processNameT arget);
362 uint currentProcessId = (uint)System.Diagnostics.Process.GetCurrentProcess ().Id;
363 StringComparison ignoreCase = StringComparison.InvariantCultureIgnoreCase;
364 foreach (ProcessInfo process in results)
365 { 394 {
366 if (!pluginFinderForbiddenPids_.Contains(process.ID) && 395 // If we are attaching to a plug-in, add it to the forbidden list to ens ure we
367 !string.IsNullOrEmpty(process.CommandLine) && 396 // don't try to attach again later.
368 process.CommandLine.Contains(typeFlagTarget, ignoreCase) && 397 pluginFinderForbiddenPids_.Add(process.ID);
369 process.CommandLine.Contains(identifierFlagTarget, ignoreCase) && 398 PluginFoundEvent.Invoke(this, new PluginFoundEventArgs(process.ID));
370 Utility.IsDescendantOfProcess(processSearcher_, process.ID, currentP rocessId))
371 {
372 // If we are attaching to a plug-in, add it to the forbidden list to e nsure we
373 // don't try to attach again later.
374 pluginFinderForbiddenPids_.Add(process.ID);
375 PluginFoundEvent.Invoke(this, new PluginFoundEventArgs(process.ID));
376 399
377 // Slow down the frequency of checks for new plugins. 400 // Slow down the frequency of checks for new plugins.
378 pluginFinderTimer_.Interval = RelaxedPluginCheckFrequency; 401 pluginFinderTimer_.Interval = RelaxedPluginCheckFrequency;
379 }
380 } 402 }
381 } 403 }
382 404
383 /// <summary> 405 /// <summary>
384 /// Attaches the visual studio debugger to a given process ID. 406 /// Attaches the visual studio debugger to a given process ID.
385 /// </summary> 407 /// </summary>
386 /// <param name="src">The parameter is not used.</param> 408 /// <param name="src">The parameter is not used.</param>
387 /// <param name="args">Contains the process ID to attach to.</param> 409 /// <param name="args">Contains the process ID to attach to.</param>
388 private void AttachVSDebugger(object src, PluginFoundEventArgs args) 410 private void AttachVSDebugger(object src, PluginFoundEventArgs args)
389 { 411 {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 contents.AppendFormat("target remote localhost:{0}", 4014); 447 contents.AppendFormat("target remote localhost:{0}", 4014);
426 contents.AppendLine(); 448 contents.AppendLine();
427 449
428 // TODO(tysand): Nacl-gdb should detect this automatically making this cal l unnecessary. 450 // TODO(tysand): Nacl-gdb should detect this automatically making this cal l unnecessary.
429 contents.Append("set architecture i386:x86-64"); 451 contents.Append("set architecture i386:x86-64");
430 contents.AppendLine(); 452 contents.AppendLine();
431 contents.AppendFormat("cd {0}", projectDir); 453 contents.AppendFormat("cd {0}", projectDir);
432 contents.AppendLine(); 454 contents.AppendLine();
433 455
434 // TODO(tysand): Nacl-gdb should handle the offset automatically. Remove 0 xC00020080. 456 // TODO(tysand): Nacl-gdb should handle the offset automatically. Remove 0 xC00020080.
435 contents.AppendFormat("add-symbol-file {0} 0xC00020080", pluginAssemblyEsc aped); 457 contents.AppendFormat("add-symbol-file \"{0}\" 0xC00020080", pluginAssembl yEscaped);
436 contents.AppendLine(); 458 contents.AppendLine();
437 459
438 // TODO(tysand): Nacl-gdb should handle loading the irt automatically. Rem ove this line. 460 // TODO(tysand): Nacl-gdb should handle loading the irt automatically. Rem ove this line.
439 contents.AppendFormat("add-symbol-file {0} 0xC0fc00080", irtPathEscaped); 461 contents.AppendFormat("add-symbol-file \"{0}\" 0xC0fc00080", irtPathEscape d);
440 contents.AppendLine(); 462 contents.AppendLine();
441 463
442 // Insert breakpoints from Visual Studio project. 464 // Insert breakpoints from Visual Studio project.
443 foreach (Breakpoint bp in dte_.Debugger.Breakpoints) 465 foreach (Breakpoint bp in dte_.Debugger.Breakpoints)
444 { 466 {
445 if (bp.Enabled && 467 if (bp.Enabled &&
446 bp.LocationType == dbgBreakpointLocationType.dbgBreakpointLocationTy peFile) 468 bp.LocationType == dbgBreakpointLocationType.dbgBreakpointLocationTy peFile)
447 { 469 {
448 contents.AppendFormat("b {0}:{1}", Path.GetFileName(bp.File), bp.FileL ine); 470 contents.AppendFormat("b {0}:{1}", Path.GetFileName(bp.File), bp.FileL ine);
449 contents.AppendLine(); 471 contents.AppendLine();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 WebServerWriteLine(e.Data); 552 WebServerWriteLine(e.Data);
531 } 553 }
532 554
533 /// <summary> 555 /// <summary>
534 /// Helper function to write data to the Web Server Output Pane. 556 /// Helper function to write data to the Web Server Output Pane.
535 /// </summary> 557 /// </summary>
536 /// <param name="message">Message to write.</param> 558 /// <param name="message">Message to write.</param>
537 private void WebServerWriteLine(string message) 559 private void WebServerWriteLine(string message)
538 { 560 {
539 webServerOutputPane_.OutputString(message + "\n"); 561 webServerOutputPane_.OutputString(message + "\n");
540 webServerOutputPane_.Activate();
541 } 562 }
542 563
543 /// <summary> 564 /// <summary>
544 /// The event arguments when a plug-in is found. 565 /// The event arguments when a plug-in is found.
545 /// </summary> 566 /// </summary>
546 public class PluginFoundEventArgs : EventArgs 567 public class PluginFoundEventArgs : EventArgs
547 { 568 {
548 /// <summary> 569 /// <summary>
549 /// Construct the PluginFoundEventArgs. 570 /// Construct the PluginFoundEventArgs.
550 /// </summary> 571 /// </summary>
551 /// <param name="pid">Process ID of the found plug-in.</param> 572 /// <param name="pid">Process ID of the found plug-in.</param>
552 public PluginFoundEventArgs(uint pid) 573 public PluginFoundEventArgs(uint pid)
553 { 574 {
554 this.ProcessID = pid; 575 this.ProcessID = pid;
555 } 576 }
556 577
557 /// <summary> 578 /// <summary>
558 /// Gets or sets process ID of the found plug-in. 579 /// Gets or sets process ID of the found plug-in.
559 /// </summary> 580 /// </summary>
560 public uint ProcessID { get; set; } 581 public uint ProcessID { get; set; }
561 } 582 }
562 } 583 }
563 } 584 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698