Skip to content

Commit

Permalink
Add JIT event signalling and --break arg for attach
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchcapper committed Mar 7, 2024
1 parent 6b7d3c5 commit 1dbef7b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,72 @@ You should have received a copy of the GNU General Public License
using System;
using System.ComponentModel.Composition;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using dnSpy.Contracts.App;
using dnSpy.Contracts.Debugger;
using dnSpy.Contracts.Debugger.Attach;

namespace dnSpy.Debugger.Attach {
[Export(typeof(IAppCommandLineArgsHandler))]
sealed class AppCommandLineArgsHandler : IAppCommandLineArgsHandler {
readonly Lazy<AttachableProcessesService> attachableProcessesService;
readonly Lazy<DbgManager> dbgManager;

[ImportingConstructor]
AppCommandLineArgsHandler(Lazy<AttachableProcessesService> attachableProcessesService) =>
AppCommandLineArgsHandler(Lazy<AttachableProcessesService> attachableProcessesService, Lazy<DbgManager> dbgManager) {
this.attachableProcessesService = attachableProcessesService;
this.dbgManager = dbgManager;
}

public double Order => 0;

[DllImport("kernel32.dll")]
private static extern bool SetEvent(IntPtr hEvent);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hObject);
private async Task BreakOnAttach(AttachableProcess process) {
TaskCompletionSource<bool> isDebuggingChangedSrc = new();
TaskCompletionSource<bool> isRunningChangedSrc = new();

EventHandler? IsDebuggingHandler=null;
EventHandler? IsRunningHandler = null;
var mgr = dbgManager.Value;


IsDebuggingHandler = ( _, _) => { if (mgr.IsDebugging == true) isDebuggingChangedSrc.SetResult(true); };
IsRunningHandler = ( _, _) => { if (mgr.IsRunning == true) isRunningChangedSrc.SetResult(true); };
mgr.IsDebuggingChanged += IsDebuggingHandler;
mgr.IsRunningChanged += IsRunningHandler;
process.Attach();
if (mgr.IsRunning != true || mgr.IsDebugging != true)
await Task.WhenAny(Task.WhenAll(isDebuggingChangedSrc.Task, isRunningChangedSrc.Task), Task.Delay(TimeSpan.FromSeconds(10)));
mgr.IsDebuggingChanged -= IsDebuggingHandler;
mgr.IsRunningChanged -= IsRunningHandler;
if (mgr.IsRunning == true && mgr.IsDebugging == true)
mgr.BreakAll();
}
public async void OnNewArgs(IAppCommandLineArgs args) {
AttachableProcess? process=null;
if (args.DebugAttachPid is int pid && pid != 0) {
var processes = await attachableProcessesService.Value.GetAttachableProcessesAsync(null, new[] { pid }, null, CancellationToken.None).ConfigureAwait(false);
var process = processes.FirstOrDefault(p => p.ProcessId == pid);
process?.Attach();
process = processes.FirstOrDefault(p => p.ProcessId == pid);
if (args.DebugEvent != 0) {
var evt = new IntPtr(args.DebugEvent);
SetEvent(evt);
CloseHandle(evt);
}
}
else if (args.DebugAttachProcess is string processName && !string.IsNullOrEmpty(processName)) {
var processes = await attachableProcessesService.Value.GetAttachableProcessesAsync(processName, CancellationToken.None).ConfigureAwait(false);
var process = processes.FirstOrDefault();
process?.Attach();
process = processes.FirstOrDefault();
}
if (args.DebugBreakOnAttach && process != null)
await BreakOnAttach(process);
else
process?.Attach();
}

}
}
3 changes: 3 additions & 0 deletions dnSpy/dnSpy.Contracts.DnSpy/App/IAppCommandLineArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ public interface IAppCommandLineArgs {
/// <summary>Attach to this process, unless it's 0</summary>
int DebugAttachPid { get; }

/// <summary>If attaching on startup break right away</summary>
bool DebugBreakOnAttach { get; }

/// <summary>Event handle duplicated into the postmortem debugger process</summary>
uint DebugEvent { get; }

Expand Down
6 changes: 6 additions & 0 deletions dnSpy/dnSpy/MainApp/AppCommandLineArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ sealed class AppCommandLineArgs : IAppCommandLineArgs {
public string HideToolWindow { get; }
public bool ShowStartupTime { get; }
public int DebugAttachPid { get; }
public bool DebugBreakOnAttach { get; }
public uint DebugEvent { get; }
public ulong JitDebugInfo { get; }
public string DebugAttachProcess { get; }
Expand Down Expand Up @@ -76,6 +77,7 @@ public AppCommandLineArgs(string[] args) {
HideToolWindow = string.Empty;
ShowStartupTime = false;
DebugAttachPid = 0;
DebugBreakOnAttach = false;
DebugAttachProcess = string.Empty;
ExtraExtensionDirectory = string.Empty;

Expand Down Expand Up @@ -178,6 +180,10 @@ public AppCommandLineArgs(string[] args) {
i++;
break;

case "--break":
DebugBreakOnAttach = true;
break;

case "-e":
if (TryParseUInt32(next, out uint debugEvent))
DebugEvent = debugEvent;
Expand Down

0 comments on commit 1dbef7b

Please sign in to comment.