@@ -69,77 +69,39 @@ def break_on_all_but_main(Control, Symbols, main_offset):
69
69
# All breakpoints are currently discarded: we just sys.exit for cleanup
70
70
return
71
71
72
- def process_creator (binfile ):
73
- Kernel32 = WinDLL ("Kernel32" )
74
-
75
- # Another flavour of process creation
76
- startupinfoa = STARTUPINFOA ()
77
- startupinfoa .cb = sizeof (STARTUPINFOA )
78
- startupinfoa .lpReserved = None
79
- startupinfoa .lpDesktop = None
80
- startupinfoa .lpTitle = None
81
- startupinfoa .dwX = 0
82
- startupinfoa .dwY = 0
83
- startupinfoa .dwXSize = 0
84
- startupinfoa .dwYSize = 0
85
- startupinfoa .dwXCountChars = 0
86
- startupinfoa .dwYCountChars = 0
87
- startupinfoa .dwFillAttribute = 0
88
- startupinfoa .dwFlags = 0
89
- startupinfoa .wShowWindow = 0
90
- startupinfoa .cbReserved2 = 0
91
- startupinfoa .lpReserved2 = None
92
- startupinfoa .hStdInput = None
93
- startupinfoa .hStdOutput = None
94
- startupinfoa .hStdError = None
95
- processinformation = PROCESS_INFORMATION ()
96
-
97
- # 0x4 below specifies CREATE_SUSPENDED.
98
- ret = Kernel32 .CreateProcessA (binfile .encode ("ascii" ), None , None , None , False , 0x4 , None , None , byref (startupinfoa ), byref (processinformation ))
99
- if ret == 0 :
100
- raise Exception ('CreateProcess running {}' .format (binfile ))
101
-
102
- return processinformation .dwProcessId , processinformation .dwThreadId , processinformation .hProcess , processinformation .hThread
103
-
104
- def thread_resumer (hProcess , hThread ):
105
- Kernel32 = WinDLL ("Kernel32" )
106
-
107
- # For reasons unclear to me, other suspend-references seem to be opened on
108
- # the opened thread. Clear them all.
109
- while True :
110
- ret = Kernel32 .ResumeThread (hThread )
111
- if ret <= 0 :
112
- break
113
- if ret < 0 :
114
- Kernel32 .TerminateProcess (hProcess , 1 )
115
- raise Exception ("Couldn't resume process after startup" )
116
-
117
- return
118
-
119
72
def setup_everything (binfile ):
120
73
from . import client
121
74
from . import symbols
122
75
Client = client .Client ()
123
76
124
- created_pid , created_tid , hProcess , hThread = process_creator (binfile )
77
+ Client .Control .SetEngineOptions (0x20 ) # DEBUG_ENGOPT_INITIAL_BREAK
78
+
79
+ Client .CreateProcessAndAttach2 (binfile )
125
80
126
81
# Load lines as well as general symbols
127
82
sym_opts = Client .Symbols .GetSymbolOptions ()
128
83
sym_opts |= symbols .SymbolOptionFlags .SYMOPT_LOAD_LINES
129
84
Client .Symbols .SetSymbolOptions (sym_opts )
130
85
131
- Client .AttachProcess (created_pid )
86
+ # Need to enter the debugger engine to let it attach properly.
87
+ res = Client .Control .WaitForEvent (timeout = 1000 )
88
+ if res == S_FALSE :
89
+ # The debugee apparently didn't do anything at all. Rather than risk
90
+ # hanging, bail out at this point.
91
+ client .TerminateProcesses ()
92
+ raise Exception ("Debuggee did not start in a timely manner" )
132
93
133
- # Need to enter the debugger engine to let it attach properly
134
- Client .Control .WaitForEvent (timeout = 1 )
135
- Client .SysObjects .set_current_thread (created_pid , created_tid )
94
+ # Enable line stepping.
136
95
Client .Control .Execute ("l+t" )
96
+ # Enable C++ expression interpretation.
137
97
Client .Control .SetExpressionSyntax (cpp = True )
138
98
99
+ # We've requested to break into the process at the earliest opportunity,
100
+ # and WaitForEvent'ing means we should have reached that break state.
101
+ # Now set a breakpoint on the main symbol, and "go" until we reach it.
139
102
module_name = Client .Symbols .get_exefile_module_name ()
140
103
offset = Client .Symbols .GetOffsetByName ("{}!main" .format (module_name ))
141
104
breakpoint = Client .Control .AddBreakpoint2 (offset = offset , enabled = True )
142
- thread_resumer (hProcess , hThread )
143
105
Client .Control .SetExecutionStatus (control .DebugStatus .DEBUG_STATUS_GO )
144
106
145
107
# Problem: there is no guarantee that the client will ever reach main,
@@ -149,7 +111,7 @@ def setup_everything(binfile):
149
111
# completely hanging in the case of a environmental/programming error.
150
112
res = Client .Control .WaitForEvent (timeout = 5000 )
151
113
if res == S_FALSE :
152
- Kernel32 . TerminateProcess ( hProcess , 1 )
114
+ client . TerminateProcesses ( )
153
115
raise Exception ("Debuggee did not reach main function in a timely manner" )
154
116
155
117
break_on_all_but_main (Client .Control , Client .Symbols , offset )
@@ -160,7 +122,7 @@ def setup_everything(binfile):
160
122
for x in range (filts [0 ], filts [0 ] + filts [1 ]):
161
123
Client .Control .SetExceptionFilterSecondCommand (x , "qd" )
162
124
163
- return Client , hProcess
125
+ return Client
164
126
165
127
def step_once (client ):
166
128
client .Control .Execute ("p" )
@@ -179,7 +141,5 @@ def main_loop(client):
179
141
while res is not None :
180
142
res = step_once (client )
181
143
182
- def cleanup (client , hProcess ):
183
- res = client .DetachProcesses ()
184
- Kernel32 = WinDLL ("Kernel32" )
185
- Kernel32 .TerminateProcess (hProcess , 1 )
144
+ def cleanup (client ):
145
+ client .TerminateProcesses ()
0 commit comments