| Index: visual_studio/NativeClientVSAddIn/NativeClientVSAddIn/PluginDebuggerHelper.cs
|
| diff --git a/visual_studio/NativeClientVSAddIn/NativeClientVSAddIn/PluginDebuggerHelper.cs b/visual_studio/NativeClientVSAddIn/NativeClientVSAddIn/PluginDebuggerHelper.cs
|
| index 53ad2e357c029f0369a181cd6717b5990e0af6dc..a8be9a92b96090a0d7928e8f32165cf4cf4c23f7 100644
|
| --- a/visual_studio/NativeClientVSAddIn/NativeClientVSAddIn/PluginDebuggerHelper.cs
|
| +++ b/visual_studio/NativeClientVSAddIn/NativeClientVSAddIn/PluginDebuggerHelper.cs
|
| @@ -34,6 +34,11 @@ namespace NativeClientVSAddIn
|
| private const int RelaxedPluginCheckFrequency = 5000;
|
|
|
| /// <summary>
|
| + /// The web server port to default to if the user does not specify one.
|
| + /// </summary>
|
| + private const int DefaultWebServerPort = 5103;
|
| +
|
| + /// <summary>
|
| /// The main visual studio object through which all Visual Studio functions are executed.
|
| /// </summary>
|
| private DTE2 dte_;
|
| @@ -233,47 +238,47 @@ namespace NativeClientVSAddIn
|
| }
|
|
|
| // We only support certain project types (e.g. C/C++ projects). Otherwise we fail.
|
| - // If supported, extract necessary information from specific project type.
|
| - if (Utility.IsVisualCProject(startProject))
|
| + if (!Utility.IsVisualCProject(startProject))
|
| {
|
| - VCConfiguration config = Utility.GetActiveVCConfiguration(startProject);
|
| - IVCRulePropertyStorage general = config.Rules.Item("ConfigurationGeneral");
|
| - VCLinkerTool linker = config.Tools.Item("VCLinkerTool");
|
| - VCProject vcproj = (VCProject)startProject.Object;
|
| -
|
| - sdkRootDirectory_ = general.GetEvaluatedPropertyValue("VSNaClSDKRoot");
|
| - platformToolset = general.GetEvaluatedPropertyValue("PlatformToolset");
|
| - pluginOutputDirectory_ = config.Evaluate(config.OutputDirectory);
|
| - pluginAssembly_ = config.Evaluate(linker.OutputFile);
|
| - pluginProjectDirectory_ = vcproj.ProjectDirectory; // Macros not allowed here.
|
| -
|
| - if (projectPlatformType_ == ProjectPlatformType.NaCl)
|
| - {
|
| - irtPath_ = general.GetEvaluatedPropertyValue("NaClIrtPath");
|
| - manifestPath_ = general.GetEvaluatedPropertyValue("NaClManifestPath");
|
| - }
|
| + return false;
|
| }
|
| - else
|
| +
|
| + // Extract necessary information from specific project type.
|
| + VCConfiguration config = Utility.GetActiveVCConfiguration(startProject);
|
| + IVCRulePropertyStorage general = config.Rules.Item("ConfigurationGeneral");
|
| + VCLinkerTool linker = config.Tools.Item("VCLinkerTool");
|
| + VCProject vcproj = (VCProject)startProject.Object;
|
| +
|
| + sdkRootDirectory_ = general.GetEvaluatedPropertyValue("VSNaClSDKRoot");
|
| + platformToolset = general.GetEvaluatedPropertyValue("PlatformToolset");
|
| + pluginOutputDirectory_ = config.Evaluate(config.OutputDirectory);
|
| + pluginAssembly_ = config.Evaluate(linker.OutputFile);
|
| + pluginProjectDirectory_ = vcproj.ProjectDirectory; // Macros not allowed here.
|
| +
|
| + if (projectPlatformType_ == ProjectPlatformType.NaCl)
|
| {
|
| - return false;
|
| + irtPath_ = general.GetEvaluatedPropertyValue("NaClIrtPath");
|
| + manifestPath_ = general.GetEvaluatedPropertyValue("NaClManifestPath");
|
| }
|
|
|
| if (string.IsNullOrEmpty(sdkRootDirectory_))
|
| {
|
| - MessageBox.Show(
|
| - string.Format(Strings.SDKPathNotSetFormat, Strings.SDKPathEnvironmentVariable));
|
| + MessageBox.Show(Strings.SDKPathNotSetError);
|
| return false;
|
| }
|
|
|
| sdkRootDirectory_ = sdkRootDirectory_.TrimEnd("/\\".ToArray<char>());
|
|
|
| - // TODO(tysand): Add user option to specify this.
|
| - int webServerPort = 5103;
|
| + // TODO(tysand): Move this code getting port to where the web server is started.
|
| + int webServerPort;
|
| + if (!int.TryParse(general.GetEvaluatedPropertyValue("NaClWebServerPort"), out webServerPort))
|
| + {
|
| + webServerPort = DefaultWebServerPort;
|
| + }
|
| +
|
| webServerExecutable_ = "python.exe";
|
| webServerArguments_ = string.Format(
|
| - "{0}\\examples\\httpd.py --no_dir_check {1}",
|
| - sdkRootDirectory_,
|
| - webServerPort);
|
| + "{0}\\examples\\httpd.py --no_dir_check {1}", sdkRootDirectory_, webServerPort);
|
|
|
| gdbPath_ = Path.Combine(
|
| sdkRootDirectory_, "toolchain", platformToolset, @"bin\x86_64-nacl-gdb.exe");
|
| @@ -317,35 +322,21 @@ namespace NativeClientVSAddIn
|
| }
|
| }
|
|
|
| - if (webServer_ != null)
|
| - {
|
| - webServer_.Kill();
|
| - webServer_.Dispose();
|
| - webServer_ = null;
|
| - }
|
| -
|
| - KillGDBProcess();
|
| + Utility.EnsureProcessKill(ref webServer_);
|
| + WebServerWriteLine(Strings.WebServerStopMessage);
|
| + CleanUpGDBProcess();
|
| }
|
|
|
| /// <summary>
|
| /// This function cleans up the started GDB process.
|
| /// </summary>
|
| - private void KillGDBProcess()
|
| + private void CleanUpGDBProcess()
|
| {
|
| - if (gdbProcess_ != null)
|
| + Utility.EnsureProcessKill(ref gdbProcess_);
|
| + if (!string.IsNullOrEmpty(gdbInitFileName_) && File.Exists(gdbInitFileName_))
|
| {
|
| - if (!gdbProcess_.HasExited)
|
| - {
|
| - gdbProcess_.Kill();
|
| - gdbProcess_.Dispose();
|
| - }
|
| -
|
| - if (!string.IsNullOrEmpty(gdbInitFileName_) && File.Exists(gdbInitFileName_))
|
| - {
|
| - File.Delete(gdbInitFileName_);
|
| - }
|
| -
|
| - gdbProcess_ = null;
|
| + File.Delete(gdbInitFileName_);
|
| + gdbInitFileName_ = null;
|
| }
|
| }
|
|
|
| @@ -379,6 +370,14 @@ namespace NativeClientVSAddIn
|
| uint mainChromeProcId = (uint)debuggedChromeMainProcess_.Id;
|
| List<ProcessInfo> chromeDescendants = processSearcher_.GetDescendants(mainChromeProcId);
|
|
|
| + // If we didn't start with debug flags then we should not attach.
|
| + string mainChromeFlags = chromeDescendants.Find(p => p.ID == mainChromeProcId).CommandLine;
|
| + if (projectPlatformType_ == ProjectPlatformType.NaCl &&
|
| + !mainChromeFlags.Contains(Strings.NaClDebugFlag))
|
| + {
|
| + return;
|
| + }
|
| +
|
| // From the list of descendants, find the plug-in by it's command line arguments and
|
| // process name as well as not being attached to already.
|
| List<ProcessInfo> plugins;
|
| @@ -444,7 +443,7 @@ namespace NativeClientVSAddIn
|
| private void AttachNaClGDB(object src, PluginFoundEventArgs args)
|
| {
|
| // Clean up any pre-existing GDB process (can happen if user reloads page).
|
| - KillGDBProcess();
|
| + CleanUpGDBProcess();
|
|
|
| gdbInitFileName_ = Path.GetTempFileName();
|
| string pluginAssemblyEscaped = pluginAssembly_.Replace("\\", "\\\\");
|
| @@ -469,19 +468,20 @@ namespace NativeClientVSAddIn
|
| // Insert breakpoints from Visual Studio project.
|
| foreach (Breakpoint bp in dte_.Debugger.Breakpoints)
|
| {
|
| - if (bp.Enabled &&
|
| - bp.LocationType == dbgBreakpointLocationType.dbgBreakpointLocationTypeFile)
|
| + if (!bp.Enabled)
|
| + {
|
| + continue;
|
| + }
|
| +
|
| + if (bp.LocationType == dbgBreakpointLocationType.dbgBreakpointLocationTypeFile)
|
| {
|
| - contents.AppendFormat("b {0}:{1}", Path.GetFileName(bp.File), bp.FileLine);
|
| - contents.AppendLine();
|
| + contents.AppendFormat("b {0}:{1}\n", Path.GetFileName(bp.File), bp.FileLine);
|
| }
|
| - else if (bp.Enabled &&
|
| - bp.LocationType == dbgBreakpointLocationType.dbgBreakpointLocationTypeFunction)
|
| + else if (bp.LocationType == dbgBreakpointLocationType.dbgBreakpointLocationTypeFunction)
|
| {
|
| - contents.AppendFormat("b {0}", bp.FunctionName);
|
| - contents.AppendLine();
|
| + contents.AppendFormat("b {0}\n", bp.FunctionName);
|
| }
|
| - else if (bp.Enabled)
|
| + else
|
| {
|
| WebServerWriteLine(
|
| string.Format(Strings.UnsupportedBreakpointTypeFormat, bp.LocationType.ToString()));
|
| @@ -563,7 +563,10 @@ namespace NativeClientVSAddIn
|
| /// <param name="message">Message to write.</param>
|
| private void WebServerWriteLine(string message)
|
| {
|
| - webServerOutputPane_.OutputString(message + "\n");
|
| + if (webServerOutputPane_ != null)
|
| + {
|
| + webServerOutputPane_.OutputString(message + "\n");
|
| + }
|
| }
|
|
|
| /// <summary>
|
|
|