Skip to content

Commit 1dbef7b

Browse files
committed
Add JIT event signalling and --break arg for attach
1 parent 6b7d3c5 commit 1dbef7b

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

Extensions/dnSpy.Debugger/dnSpy.Debugger/Attach/AppCommandLineArgsHandler.cs

+45-5
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,72 @@ You should have received a copy of the GNU General Public License
2020
using System;
2121
using System.ComponentModel.Composition;
2222
using System.Linq;
23+
using System.Runtime.InteropServices;
2324
using System.Threading;
25+
using System.Threading.Tasks;
2426
using dnSpy.Contracts.App;
27+
using dnSpy.Contracts.Debugger;
2528
using dnSpy.Contracts.Debugger.Attach;
2629

2730
namespace dnSpy.Debugger.Attach {
2831
[Export(typeof(IAppCommandLineArgsHandler))]
2932
sealed class AppCommandLineArgsHandler : IAppCommandLineArgsHandler {
3033
readonly Lazy<AttachableProcessesService> attachableProcessesService;
34+
readonly Lazy<DbgManager> dbgManager;
3135

3236
[ImportingConstructor]
33-
AppCommandLineArgsHandler(Lazy<AttachableProcessesService> attachableProcessesService) =>
37+
AppCommandLineArgsHandler(Lazy<AttachableProcessesService> attachableProcessesService, Lazy<DbgManager> dbgManager) {
3438
this.attachableProcessesService = attachableProcessesService;
39+
this.dbgManager = dbgManager;
40+
}
3541

3642
public double Order => 0;
3743

44+
[DllImport("kernel32.dll")]
45+
private static extern bool SetEvent(IntPtr hEvent);
46+
[DllImport("kernel32.dll")]
47+
private static extern bool CloseHandle(IntPtr hObject);
48+
private async Task BreakOnAttach(AttachableProcess process) {
49+
TaskCompletionSource<bool> isDebuggingChangedSrc = new();
50+
TaskCompletionSource<bool> isRunningChangedSrc = new();
51+
52+
EventHandler? IsDebuggingHandler=null;
53+
EventHandler? IsRunningHandler = null;
54+
var mgr = dbgManager.Value;
55+
56+
57+
IsDebuggingHandler = ( _, _) => { if (mgr.IsDebugging == true) isDebuggingChangedSrc.SetResult(true); };
58+
IsRunningHandler = ( _, _) => { if (mgr.IsRunning == true) isRunningChangedSrc.SetResult(true); };
59+
mgr.IsDebuggingChanged += IsDebuggingHandler;
60+
mgr.IsRunningChanged += IsRunningHandler;
61+
process.Attach();
62+
if (mgr.IsRunning != true || mgr.IsDebugging != true)
63+
await Task.WhenAny(Task.WhenAll(isDebuggingChangedSrc.Task, isRunningChangedSrc.Task), Task.Delay(TimeSpan.FromSeconds(10)));
64+
mgr.IsDebuggingChanged -= IsDebuggingHandler;
65+
mgr.IsRunningChanged -= IsRunningHandler;
66+
if (mgr.IsRunning == true && mgr.IsDebugging == true)
67+
mgr.BreakAll();
68+
}
3869
public async void OnNewArgs(IAppCommandLineArgs args) {
70+
AttachableProcess? process=null;
3971
if (args.DebugAttachPid is int pid && pid != 0) {
4072
var processes = await attachableProcessesService.Value.GetAttachableProcessesAsync(null, new[] { pid }, null, CancellationToken.None).ConfigureAwait(false);
41-
var process = processes.FirstOrDefault(p => p.ProcessId == pid);
42-
process?.Attach();
73+
process = processes.FirstOrDefault(p => p.ProcessId == pid);
74+
if (args.DebugEvent != 0) {
75+
var evt = new IntPtr(args.DebugEvent);
76+
SetEvent(evt);
77+
CloseHandle(evt);
78+
}
4379
}
4480
else if (args.DebugAttachProcess is string processName && !string.IsNullOrEmpty(processName)) {
4581
var processes = await attachableProcessesService.Value.GetAttachableProcessesAsync(processName, CancellationToken.None).ConfigureAwait(false);
46-
var process = processes.FirstOrDefault();
47-
process?.Attach();
82+
process = processes.FirstOrDefault();
4883
}
84+
if (args.DebugBreakOnAttach && process != null)
85+
await BreakOnAttach(process);
86+
else
87+
process?.Attach();
4988
}
89+
5090
}
5191
}

dnSpy/dnSpy.Contracts.DnSpy/App/IAppCommandLineArgs.cs

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ public interface IAppCommandLineArgs {
8181
/// <summary>Attach to this process, unless it's 0</summary>
8282
int DebugAttachPid { get; }
8383

84+
/// <summary>If attaching on startup break right away</summary>
85+
bool DebugBreakOnAttach { get; }
86+
8487
/// <summary>Event handle duplicated into the postmortem debugger process</summary>
8588
uint DebugEvent { get; }
8689

dnSpy/dnSpy/MainApp/AppCommandLineArgs.cs

+6
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ sealed class AppCommandLineArgs : IAppCommandLineArgs {
4646
public string HideToolWindow { get; }
4747
public bool ShowStartupTime { get; }
4848
public int DebugAttachPid { get; }
49+
public bool DebugBreakOnAttach { get; }
4950
public uint DebugEvent { get; }
5051
public ulong JitDebugInfo { get; }
5152
public string DebugAttachProcess { get; }
@@ -76,6 +77,7 @@ public AppCommandLineArgs(string[] args) {
7677
HideToolWindow = string.Empty;
7778
ShowStartupTime = false;
7879
DebugAttachPid = 0;
80+
DebugBreakOnAttach = false;
7981
DebugAttachProcess = string.Empty;
8082
ExtraExtensionDirectory = string.Empty;
8183

@@ -178,6 +180,10 @@ public AppCommandLineArgs(string[] args) {
178180
i++;
179181
break;
180182

183+
case "--break":
184+
DebugBreakOnAttach = true;
185+
break;
186+
181187
case "-e":
182188
if (TryParseUInt32(next, out uint debugEvent))
183189
DebugEvent = debugEvent;

0 commit comments

Comments
 (0)