Skip to content

Commit

Permalink
Save per-thread forking state, interrupt over the pipe rat6her than u…
Browse files Browse the repository at this point in the history
…sing the mi
  • Loading branch information
paulmaybee committed May 17, 2016
1 parent 17d1f39 commit 12632f3
Show file tree
Hide file tree
Showing 11 changed files with 415 additions and 177 deletions.
4 changes: 2 additions & 2 deletions src/DebugEngineHost.Stub/DebugEngineHost.ref.cs
Original file line number Diff line number Diff line change
Expand Up @@ -317,9 +317,9 @@ public static void FindNatvisInSolution(NatvisLoader loader)
public static class HostDebugger
{
/// <summary>
/// Attach to a process using the provided options
/// Ask the host to async spin up a new instance of the debug engine and go through the launch sequence using the specified options
/// </summary>
public static void Attach(string filePath, string options, Guid engineId)
public static void StartDebugChildProcess(string filePath, string options, Guid engineId)
{
throw new NotImplementedException();
}
Expand Down
9 changes: 6 additions & 3 deletions src/DebugEngineHost/HostDebugger.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio;
Expand All @@ -15,9 +18,9 @@ namespace Microsoft.DebugEngineHost
public static class HostDebugger
{
/// <summary>
/// Attach to a process using the provided options
/// Ask the host to async spin up a new instance of the debug engine and go through the launch sequence using the specified options
/// </summary>
public static void Attach(string filePath, string options, Guid engineId)
public static void StartDebugChildProcess(string filePath, string options, Guid engineId)
{
try
{
Expand Down
48 changes: 38 additions & 10 deletions src/MICore/Debugger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class Debugger : ITransportCallback
public event EventHandler BreakCreatedEvent; // a breakpoint was created
public event EventHandler ThreadCreatedEvent;
public event EventHandler ThreadExitedEvent;
public event EventHandler ThreadGroupExitedEvent;
public event EventHandler<ResultEventArgs> MessageEvent;
public event EventHandler<ResultEventArgs> TelemetryEvent;
private int _exiting;
Expand Down Expand Up @@ -543,12 +544,21 @@ public async Task<Results> CmdDetach()

public Task CmdBreakInternal()
{
<<<<<<< 17d1f39a11034234966c6bc4ddf9dc41d6c51d85
this.VerifyNotDebuggingCoreDump();

// TODO May need to fix attach on windows.
// Note that interrupt doesn't work when attached on OS X with gdb:
// https://sourceware.org/bugzilla/show_bug.cgi?id=20035
if (IsLocalGdb() && (PlatformUtilities.IsLinux() || PlatformUtilities.IsOSX()))
=======
if (ProcessState != ProcessState.Running)
{
return Task.CompletedTask;
}
//TODO May need to fix attach on windows and osx.
if (IsLocalGdbAttach() && RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
>>>>>>> Save per-thread forking state, interrupt over the pipe rat6her than using the mi
{
// for local linux debugging, send a signal to one of the debuggee processes rather than
// using -exec-interrupt. -exec-interrupt does not work with attach and, in some instances, launch.
Expand All @@ -570,6 +580,13 @@ public Task CmdBreakInternal()
return CmdUnixBreak(debuggeePid, ResultClass.done);
}
}
else if (_transport is PipeTransport)
{
if (((PipeTransport)_transport).Interrupt(PidByInferior("i1")))
{
return Task.FromResult<Results>(new Results(ResultClass.done));
}
}

var res = CmdAsync("-exec-interrupt", ResultClass.done);
return res.ContinueWith((t) =>
Expand Down Expand Up @@ -1140,6 +1157,7 @@ private void OnNotificationOutput(string cmd)
{
results = _miResults.ParseResultList(cmd.Substring("thread-group-exited,".Length));
HandleThreadGroupExited(results);
ThreadGroupExitedEvent(this, new ResultEventArgs(results, 0));
}
else if (cmd.StartsWith("thread-created,", StringComparison.Ordinal))
{
Expand Down Expand Up @@ -1230,21 +1248,31 @@ public uint InferiorByPid(int pid)
{
if ( grp.Value == pid)
{
// Inferior names are of the form "iX" where X in the inferior number
string name = grp.Key;
if (name[0] == 'i')
{
uint id;
if (UInt32.TryParse(name.Substring(1), out id))
{
return id;
}
}
return InferiorNumber(grp.Key);
}
}
return 0;
}

public int PidByInferior(string inf)
{
return _debuggeePids[inf];
}

public uint InferiorNumber(string groupId)
{
// Inferior names are of the form "iX" where X in the inferior number
if (groupId.Length >= 2 && groupId[0] == 'i')
{
uint id;
if (UInt32.TryParse(groupId.Substring(1), out id))
{
return id;
}
}
return 1; // default to the first inferior if group-id not understood
}

private void HandleThreadGroupExited(Results results)
{
string threadGroupId = results.TryFindString("id");
Expand Down
94 changes: 60 additions & 34 deletions src/MICore/LaunchOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,19 @@ public enum LaunchCompleteCommand
/// </summary>
public sealed class PipeLaunchOptions : LaunchOptions
{
public PipeLaunchOptions(string PipePath, string PipeArguments)
public PipeLaunchOptions(string PipePath, string PipeArguments, string PipeCommandArguments)
{
if (string.IsNullOrEmpty(PipePath))
throw new ArgumentNullException("PipePath");

this.PipePath = PipePath;
this.PipeArguments = PipeArguments;
this.PipeCommandArguments = PipeCommandArguments;
}

static internal PipeLaunchOptions CreateFromXml(Xml.LaunchOptions.PipeLaunchOptions source)
{
var options = new PipeLaunchOptions(RequireAttribute(source.PipePath, "PipePath"), source.PipeArguments);
var options = new PipeLaunchOptions(RequireAttribute(source.PipePath, "PipePath"), source.PipeArguments, source.PipeCommandArguments);
options.InitializeCommonOptions(source);

return options;
Expand All @@ -88,7 +89,13 @@ static internal PipeLaunchOptions CreateFromXml(Xml.LaunchOptions.PipeLaunchOpti
/// <summary>
/// [Optional] Arguments to pass to the pipe executable.
/// </summary>
///
public string PipeArguments { get; private set; }

/// <summary>
/// [Optional] Arguments to pass to the PipePath program that include a format specifier ('{0}') for a custom command.
/// </summary>
public string PipeCommandArguments { get; private set; }
}

public sealed class TcpLaunchOptions : LaunchOptions
Expand Down Expand Up @@ -282,24 +289,6 @@ private static string ResolveFromPath(string command)
/// </summary>
public string MIDebuggerServerAddress { get; private set; }

/// <summary>
/// [Required] Path to the executable file. This path must exist on the Visual Studio computer.
/// </summary>
public override string ExePath
{
get
{
return base.ExePath;
}
set
{
if (String.IsNullOrEmpty(value) || !LocalLaunchOptions.CheckPath(value))
throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, MICoreResources.Error_InvalidLocalExePath, value));

base.ExePath = value;
}
}

/// <summary>
/// [Optional] List of environment variables to add to the launched process
/// </summary>
Expand Down Expand Up @@ -397,12 +386,24 @@ public abstract class LaunchOptions

public MIMode DebuggerMIMode { get; set; }

private string _exePath;

private Xml.LaunchOptions.BaseLaunchOptions _baseOptions;
/// <summary>
/// Hold on to options in serializable form to support child process debugging
/// </summary>
public Xml.LaunchOptions.BaseLaunchOptions BaseOptions { get; set; }
public Xml.LaunchOptions.BaseLaunchOptions BaseOptions
{
get { return _baseOptions; }
protected set
{
if (value == null)
throw new ArgumentNullException("BaseOptions");
VerifyCanModifyProperty("BaseOptions");

_baseOptions = value;
}
}

private string _exePath;

/// <summary>
/// [Required] Path to the executable file. This could be a path on the remote machine (for Pipe transport)
Expand Down Expand Up @@ -435,10 +436,20 @@ public string ExeArguments
}
}

private int _processId;

/// <summary>
/// [Optional] If supplied, the debugger will attach to the process rather than launching a new one. Note that some operating systems will require admin rights to do this.
/// </summary>
public int ProcessId { get; set; }
public int ProcessId
{
get { return _processId; }
protected set
{
VerifyCanModifyProperty("ProcessId");
_processId = value;
}
}

private string _coreDumpPath;
/// <summary>
Expand All @@ -450,8 +461,10 @@ public string CoreDumpPath
{
return _coreDumpPath;
}
set
protected set
{
VerifyCanModifyProperty("CoreDumpPath");

// CoreDumpPath is allowed to be null/empty
_coreDumpPath = value;
}
Expand Down Expand Up @@ -615,30 +628,40 @@ public LaunchCompleteCommand LaunchCompleteCommand
}
}

public bool DebugChildProcesses { get; set; }
private bool _debugChildProcesses;

public bool DebugChildProcesses
{
get { return _debugChildProcesses; }
protected set
{
VerifyCanModifyProperty("DebugChildProcesses");
_debugChildProcesses = value;
}
}

public static string GetOptionsString(object o)
public string GetOptionsString()
{
try
{
var strWriter = new StringWriter(CultureInfo.InvariantCulture);
XmlSerializer serializer;
using (XmlWriter writer = XmlWriter.Create(strWriter))
{
if (o is Xml.LaunchOptions.LocalLaunchOptions)
if (BaseOptions is Xml.LaunchOptions.LocalLaunchOptions)
{
serializer = new XmlSerializer(typeof(Xml.LaunchOptions.LocalLaunchOptions));
Serialize(serializer, writer, o);
Serialize(serializer, writer, BaseOptions);
}
else if (o is Xml.LaunchOptions.PipeLaunchOptions)
else if (BaseOptions is Xml.LaunchOptions.PipeLaunchOptions)
{
serializer = new XmlSerializer(typeof(Xml.LaunchOptions.PipeLaunchOptions));
Serialize(serializer, writer, o);
Serialize(serializer, writer, BaseOptions);
}
else if (o is Xml.LaunchOptions.TcpLaunchOptions)
else if (BaseOptions is Xml.LaunchOptions.TcpLaunchOptions)
{
serializer = new XmlSerializer(typeof(Xml.LaunchOptions.TcpLaunchOptions));
Serialize(serializer, writer, o);
Serialize(serializer, writer, BaseOptions);
}
else
{
Expand Down Expand Up @@ -835,7 +858,7 @@ public static object Deserialize(XmlSerializer serializer, XmlReader reader)
}
}

public static void Serialize(XmlSerializer serializer, XmlWriter writer, object o)
private static void Serialize(XmlSerializer serializer, XmlWriter writer, object o)
{
try
{
Expand Down Expand Up @@ -950,8 +973,11 @@ protected void InitializeCommonOptions(Xml.LaunchOptions.BaseLaunchOptions sourc
else
this.AdditionalSOLibSearchPath = string.Concat(this.AdditionalSOLibSearchPath, ";", additionalSOLibSearchPath);
}
<<<<<<< 17d1f39a11034234966c6bc4ddf9dc41d6c51d85
if (string.IsNullOrEmpty(this.AbsolutePrefixSOLibSearchPath))
this.AbsolutePrefixSOLibSearchPath = source.AbsolutePrefixSOLibSearchPath;
=======
>>>>>>> Save per-thread forking state, interrupt over the pipe rat6her than using the mi

this.ProcessId = source.ProcessId;
this.CoreDumpPath = source.CoreDumpPath;
Expand Down
8 changes: 7 additions & 1 deletion src/MICore/LaunchOptions.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,11 @@
<xs:documentation>Any arguments to pass to this program.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="PipeCommandArguments" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Arguments to pass to the PipePath program that include a format specifier ('{0}') for a custom command.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Expand Down Expand Up @@ -320,7 +325,8 @@
</xs:complexContent>
</xs:complexType>
</xs:element>
<!--base type for LocalLaunchOptions, PipeLaunchOptions, and TcpLaunchOptions -->

<!--base type for LocalLaunchOptions, PipeLaunchOptions, and TcpLaunchOptions -->
<xs:complexType name="BaseLaunchOptions">
<xs:sequence>
<xs:element name="SetupCommands" minOccurs="0" maxOccurs="1" type="CommandList">
Expand Down
4 changes: 4 additions & 0 deletions src/MICore/LaunchOptions.xsd.types.designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 12632f3

Please sign in to comment.