@@ -20,32 +20,72 @@ You should have received a copy of the GNU General Public License
20
20
using System ;
21
21
using System . ComponentModel . Composition ;
22
22
using System . Linq ;
23
+ using System . Runtime . InteropServices ;
23
24
using System . Threading ;
25
+ using System . Threading . Tasks ;
24
26
using dnSpy . Contracts . App ;
27
+ using dnSpy . Contracts . Debugger ;
25
28
using dnSpy . Contracts . Debugger . Attach ;
26
29
27
30
namespace dnSpy . Debugger . Attach {
28
31
[ Export ( typeof ( IAppCommandLineArgsHandler ) ) ]
29
32
sealed class AppCommandLineArgsHandler : IAppCommandLineArgsHandler {
30
33
readonly Lazy < AttachableProcessesService > attachableProcessesService ;
34
+ readonly Lazy < DbgManager > dbgManager ;
31
35
32
36
[ ImportingConstructor ]
33
- AppCommandLineArgsHandler ( Lazy < AttachableProcessesService > attachableProcessesService ) =>
37
+ AppCommandLineArgsHandler ( Lazy < AttachableProcessesService > attachableProcessesService , Lazy < DbgManager > dbgManager ) {
34
38
this . attachableProcessesService = attachableProcessesService ;
39
+ this . dbgManager = dbgManager ;
40
+ }
35
41
36
42
public double Order => 0 ;
37
43
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
+ }
38
69
public async void OnNewArgs ( IAppCommandLineArgs args ) {
70
+ AttachableProcess ? process = null ;
39
71
if ( args . DebugAttachPid is int pid && pid != 0 ) {
40
72
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
+ }
43
79
}
44
80
else if ( args . DebugAttachProcess is string processName && ! string . IsNullOrEmpty ( processName ) ) {
45
81
var processes = await attachableProcessesService . Value . GetAttachableProcessesAsync ( processName , CancellationToken . None ) . ConfigureAwait ( false ) ;
46
- var process = processes . FirstOrDefault ( ) ;
47
- process ? . Attach ( ) ;
82
+ process = processes . FirstOrDefault ( ) ;
48
83
}
84
+ if ( args . DebugBreakOnAttach && process != null )
85
+ await BreakOnAttach ( process ) ;
86
+ else
87
+ process ? . Attach ( ) ;
49
88
}
89
+
50
90
}
51
91
}
0 commit comments