blob: d058a412c8968e601035cab8acf99a65c5307a2e [file] [log] [blame]
Zachary Turner02862bc2014-11-07 23:44:13 +00001//===-- DebuggerThread.DebuggerThread --------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "DebuggerThread.h"
Zachary Turnerdcd80372014-11-11 00:00:14 +000011#include "ExceptionRecord.h"
Zachary Turner02862bc2014-11-07 23:44:13 +000012#include "IDebugDelegate.h"
Zachary Turner02862bc2014-11-07 23:44:13 +000013
14#include "lldb/Core/Error.h"
15#include "lldb/Core/Log.h"
Zachary Turnera32d2ce2014-11-12 19:31:56 +000016#include "lldb/Core/ModuleSpec.h"
17#include "lldb/Host/FileSpec.h"
Zachary Turner02862bc2014-11-07 23:44:13 +000018#include "lldb/Host/Predicate.h"
19#include "lldb/Host/ThisThread.h"
20#include "lldb/Host/ThreadLauncher.h"
21#include "lldb/Host/windows/HostProcessWindows.h"
22#include "lldb/Host/windows/HostThreadWindows.h"
23#include "lldb/Host/windows/ProcessLauncherWindows.h"
24#include "lldb/Target/ProcessLaunchInfo.h"
Zachary Turnerc62733b2015-05-20 18:31:17 +000025#include "lldb/Target/Process.h"
Zachary Turner02862bc2014-11-07 23:44:13 +000026
Adrian McCarthy18a9135d2015-10-28 18:21:45 +000027#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
Zachary Turner610e5292015-05-07 21:39:33 +000028
Zachary Turnera32d2ce2014-11-12 19:31:56 +000029#include "llvm/ADT/STLExtras.h"
Zachary Turner02862bc2014-11-07 23:44:13 +000030#include "llvm/Support/raw_ostream.h"
31
32using namespace lldb;
33using namespace lldb_private;
34
35namespace
36{
37struct DebugLaunchContext
38{
39 DebugLaunchContext(DebuggerThread *thread, const ProcessLaunchInfo &launch_info)
40 : m_thread(thread)
41 , m_launch_info(launch_info)
42 {
43 }
44 DebuggerThread *m_thread;
45 ProcessLaunchInfo m_launch_info;
46};
Zachary Turnerc62733b2015-05-20 18:31:17 +000047
48struct DebugAttachContext
49{
50 DebugAttachContext(DebuggerThread *thread, lldb::pid_t pid, const ProcessAttachInfo &attach_info)
51 : m_thread(thread)
52 , m_pid(pid)
53 , m_attach_info(attach_info)
54 {
55 }
56 DebuggerThread *m_thread;
57 lldb::pid_t m_pid;
58 ProcessAttachInfo m_attach_info;
59};
Zachary Turner02862bc2014-11-07 23:44:13 +000060}
61
62DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
63 : m_debug_delegate(debug_delegate)
64 , m_image_file(nullptr)
Zachary Turner3c1c5b92015-05-21 19:56:26 +000065 , m_debugging_ended_event(nullptr)
Zachary Turner8d8033c2015-09-17 20:18:50 +000066 , m_is_shutting_down(false)
Adrian McCarthya59a7212015-06-19 18:26:53 +000067 , m_pid_to_detach(0)
68 , m_detached(false)
Zachary Turner02862bc2014-11-07 23:44:13 +000069{
Zachary Turner3c1c5b92015-05-21 19:56:26 +000070 m_debugging_ended_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
Zachary Turner02862bc2014-11-07 23:44:13 +000071}
72
73DebuggerThread::~DebuggerThread()
74{
Zachary Turner3c1c5b92015-05-21 19:56:26 +000075 ::CloseHandle(m_debugging_ended_event);
Zachary Turner02862bc2014-11-07 23:44:13 +000076}
77
Zachary Turner3985f892014-11-10 22:32:18 +000078Error
Zachary Turner02862bc2014-11-07 23:44:13 +000079DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info)
80{
Zachary Turner610e5292015-05-07 21:39:33 +000081 WINLOG_IFALL(WINDOWS_LOG_PROCESS,
82 "DebuggerThread::DebugLaunch launching '%s'", launch_info.GetExecutableFile().GetPath().c_str());
Zachary Turner02862bc2014-11-07 23:44:13 +000083
Zachary Turner610e5292015-05-07 21:39:33 +000084 Error error;
Zachary Turner02862bc2014-11-07 23:44:13 +000085 DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
Zachary Turner610e5292015-05-07 21:39:33 +000086 HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]",
Zachary Turnerc62733b2015-05-20 18:31:17 +000087 DebuggerThreadLaunchRoutine, context, &error));
Zachary Turner610e5292015-05-07 21:39:33 +000088
89 if (!error.Success())
90 {
91 WINERR_IFALL(WINDOWS_LOG_PROCESS,
92 "DebugLaunch couldn't launch debugger thread. %s", error.AsCString());
93 }
Zachary Turner02862bc2014-11-07 23:44:13 +000094
Zachary Turner3985f892014-11-10 22:32:18 +000095 return error;
Zachary Turner02862bc2014-11-07 23:44:13 +000096}
97
Zachary Turnerc62733b2015-05-20 18:31:17 +000098Error
99DebuggerThread::DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
100{
101 WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread::DebugAttach attaching to '%u'", (DWORD)pid);
102
103 Error error;
104 DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
105 HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]",
106 DebuggerThreadAttachRoutine, context, &error));
107
108 if (!error.Success())
109 {
110 WINERR_IFALL(WINDOWS_LOG_PROCESS, "DebugAttach couldn't attach to process '%u'. %s", (DWORD)pid,
111 error.AsCString());
112 }
113
114 return error;
115}
116
Zachary Turner02862bc2014-11-07 23:44:13 +0000117lldb::thread_result_t
Zachary Turnerc62733b2015-05-20 18:31:17 +0000118DebuggerThread::DebuggerThreadLaunchRoutine(void *data)
Zachary Turner02862bc2014-11-07 23:44:13 +0000119{
120 DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
Zachary Turnerc62733b2015-05-20 18:31:17 +0000121 lldb::thread_result_t result = context->m_thread->DebuggerThreadLaunchRoutine(context->m_launch_info);
Zachary Turner02862bc2014-11-07 23:44:13 +0000122 delete context;
123 return result;
124}
125
126lldb::thread_result_t
Zachary Turnerc62733b2015-05-20 18:31:17 +0000127DebuggerThread::DebuggerThreadAttachRoutine(void *data)
128{
129 DebugAttachContext *context = static_cast<DebugAttachContext *>(data);
130 lldb::thread_result_t result =
131 context->m_thread->DebuggerThreadAttachRoutine(context->m_pid, context->m_attach_info);
132 delete context;
133 return result;
134}
135
136lldb::thread_result_t
137DebuggerThread::DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info)
Zachary Turner02862bc2014-11-07 23:44:13 +0000138{
139 // Grab a shared_ptr reference to this so that we know it won't get deleted until after the
140 // thread routine has exited.
141 std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
Zachary Turner02862bc2014-11-07 23:44:13 +0000142
Zachary Turnerc62733b2015-05-20 18:31:17 +0000143 WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread preparing to launch '%s' on background thread.",
144 launch_info.GetExecutableFile().GetPath().c_str());
Zachary Turner610e5292015-05-07 21:39:33 +0000145
Zachary Turner02862bc2014-11-07 23:44:13 +0000146 Error error;
147 ProcessLauncherWindows launcher;
148 HostProcess process(launcher.LaunchProcess(launch_info, error));
149 // If we couldn't create the process, notify waiters immediately. Otherwise enter the debug
150 // loop and wait until we get the create process debug notification. Note that if the process
151 // was created successfully, we can throw away the process handle we got from CreateProcess
152 // because Windows will give us another (potentially more useful?) handle when it sends us the
153 // CREATE_PROCESS_DEBUG_EVENT.
154 if (error.Success())
155 DebugLoop();
156 else
Zachary Turnerd6a7b632014-11-12 19:31:39 +0000157 m_debug_delegate->OnDebuggerError(error, 0);
Zachary Turner02862bc2014-11-07 23:44:13 +0000158
159 return 0;
160}
161
Zachary Turnerc62733b2015-05-20 18:31:17 +0000162lldb::thread_result_t
163DebuggerThread::DebuggerThreadAttachRoutine(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
164{
165 // Grab a shared_ptr reference to this so that we know it won't get deleted until after the
166 // thread routine has exited.
167 std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
168
169 WINLOG_IFALL(WINDOWS_LOG_PROCESS, "DebuggerThread preparing to attach to process '%u' on background thread.",
170 (DWORD)pid);
171
172 if (!DebugActiveProcess((DWORD)pid))
173 {
174 Error error(::GetLastError(), eErrorTypeWin32);
175 m_debug_delegate->OnDebuggerError(error, 0);
176 return 0;
177 }
178
179 // The attach was successful, enter the debug loop. From here on out, this is no different than
180 // a create process operation, so all the same comments in DebugLaunch should apply from this
181 // point out.
182 DebugLoop();
183
184 return 0;
185}
186
Zachary Turnerc6a66532014-12-03 22:04:18 +0000187Error
188DebuggerThread::StopDebugging(bool terminate)
189{
190 Error error;
191
Zachary Turner610e5292015-05-07 21:39:33 +0000192 lldb::pid_t pid = m_process.GetProcessId();
193
194 WINLOG_IFALL(WINDOWS_LOG_PROCESS,
195 "StopDebugging('%s') called (inferior=%I64u).",
196 (terminate ? "true" : "false"), pid);
197
Zachary Turner8d8033c2015-09-17 20:18:50 +0000198 // Set m_is_shutting_down to true if it was false. Return if it was already true.
199 bool expected = false;
200 if (!m_is_shutting_down.compare_exchange_strong(expected, true))
201 return error;
202
Adrian McCarthya59a7212015-06-19 18:26:53 +0000203 // Make a copy of the process, since the termination sequence will reset
204 // DebuggerThread's internal copy and it needs to remain open for the Wait operation.
205 HostProcess process_copy = m_process;
206 lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
207
Zachary Turnerc6a66532014-12-03 22:04:18 +0000208 if (terminate)
209 {
Zachary Turner610e5292015-05-07 21:39:33 +0000210 // Initiate the termination before continuing the exception, so that the next debug
211 // event we get is the exit process event, and not some other event.
Zachary Turnerc6a66532014-12-03 22:04:18 +0000212 BOOL terminate_suceeded = TerminateProcess(handle, 0);
Zachary Turner610e5292015-05-07 21:39:33 +0000213 WINLOG_IFALL(WINDOWS_LOG_PROCESS,
214 "StopDebugging called TerminateProcess(0x%p, 0) (inferior=%I64u), success='%s'",
215 handle, pid, (terminate_suceeded ? "true" : "false"));
Adrian McCarthya59a7212015-06-19 18:26:53 +0000216 }
Zachary Turner610e5292015-05-07 21:39:33 +0000217
Adrian McCarthya59a7212015-06-19 18:26:53 +0000218 // If we're stuck waiting for an exception to continue (e.g. the user is at a breakpoint
219 // messing around in the debugger), continue it now. But only AFTER calling TerminateProcess
220 // to make sure that the very next call to WaitForDebugEvent is an exit process event.
221 if (m_active_exception.get())
222 {
223 WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_EXCEPTION,
224 "StopDebugging masking active exception");
225
226 ContinueAsyncException(ExceptionResult::MaskException);
227 }
228
229 if (!terminate)
230 {
231 // Indicate that we want to detach.
232 m_pid_to_detach = GetProcess().GetProcessId();
233
234 // Force a fresh break so that the detach can happen from the debugger thread.
235 if (!::DebugBreakProcess(GetProcess().GetNativeProcess().GetSystemHandle()))
Zachary Turner610e5292015-05-07 21:39:33 +0000236 {
Adrian McCarthya59a7212015-06-19 18:26:53 +0000237 error.SetError(::GetLastError(), eErrorTypeWin32);
Zachary Turner610e5292015-05-07 21:39:33 +0000238 }
Adrian McCarthya59a7212015-06-19 18:26:53 +0000239 }
Zachary Turnerc6a66532014-12-03 22:04:18 +0000240
Adrian McCarthya59a7212015-06-19 18:26:53 +0000241 WINLOG_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging waiting for detach from process %u to complete.", pid);
Zachary Turner3c1c5b92015-05-21 19:56:26 +0000242
Adrian McCarthya59a7212015-06-19 18:26:53 +0000243 DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
244 if (wait_result != WAIT_OBJECT_0)
245 {
246 error.SetError(GetLastError(), eErrorTypeWin32);
247 WINERR_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging WaitForSingleObject(0x%p, 5000) returned %u",
248 m_debugging_ended_event, wait_result);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000249 }
250 else
251 {
Adrian McCarthya59a7212015-06-19 18:26:53 +0000252 WINLOG_IFALL(WINDOWS_LOG_PROCESS, "StopDebugging detach from process %u completed successfully.", pid);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000253 }
Zachary Turner610e5292015-05-07 21:39:33 +0000254
255 if (!error.Success())
256 {
257 WINERR_IFALL(WINDOWS_LOG_PROCESS,
Adrian McCarthya59a7212015-06-19 18:26:53 +0000258 "StopDebugging encountered an error while trying to stop process %u. %s",
Zachary Turner610e5292015-05-07 21:39:33 +0000259 pid, error.AsCString());
260 }
Zachary Turnerc6a66532014-12-03 22:04:18 +0000261 return error;
262}
263
Zachary Turner02862bc2014-11-07 23:44:13 +0000264void
Zachary Turnerdcd80372014-11-11 00:00:14 +0000265DebuggerThread::ContinueAsyncException(ExceptionResult result)
266{
Zachary Turnerc6a66532014-12-03 22:04:18 +0000267 if (!m_active_exception.get())
268 return;
269
Zachary Turner610e5292015-05-07 21:39:33 +0000270 WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_EXCEPTION,
271 "ContinueAsyncException called for inferior process %I64u, broadcasting.",
272 m_process.GetProcessId());
273
Zachary Turnerc6a66532014-12-03 22:04:18 +0000274 m_active_exception.reset();
275 m_exception_pred.SetValue(result, eBroadcastAlways);
276}
277
278void
279DebuggerThread::FreeProcessHandles()
280{
281 m_process = HostProcess();
282 m_main_thread = HostThread();
283 if (m_image_file)
284 {
285 ::CloseHandle(m_image_file);
286 m_image_file = nullptr;
287 }
Zachary Turnerdcd80372014-11-11 00:00:14 +0000288}
289
290void
Zachary Turner02862bc2014-11-07 23:44:13 +0000291DebuggerThread::DebugLoop()
292{
293 DEBUG_EVENT dbe = {0};
Zachary Turnerbe5e1e52014-12-04 22:07:02 +0000294 bool should_debug = true;
Zachary Turner610e5292015-05-07 21:39:33 +0000295 WINLOG_IFALL(WINDOWS_LOG_EVENT, "Entering WaitForDebugEvent loop");
296 while (should_debug)
Zachary Turner02862bc2014-11-07 23:44:13 +0000297 {
Zachary Turner610e5292015-05-07 21:39:33 +0000298 WINLOGD_IFALL(WINDOWS_LOG_EVENT, "Calling WaitForDebugEvent");
299 BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
300 if (wait_result)
Zachary Turner02862bc2014-11-07 23:44:13 +0000301 {
Zachary Turner610e5292015-05-07 21:39:33 +0000302 DWORD continue_status = DBG_CONTINUE;
303 switch (dbe.dwDebugEventCode)
Zachary Turnerdcd80372014-11-11 00:00:14 +0000304 {
Zachary Turner610e5292015-05-07 21:39:33 +0000305 case EXCEPTION_DEBUG_EVENT:
306 {
307 ExceptionResult status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
Zachary Turnerdcd80372014-11-11 00:00:14 +0000308
Zachary Turner610e5292015-05-07 21:39:33 +0000309 if (status == ExceptionResult::MaskException)
310 continue_status = DBG_CONTINUE;
311 else if (status == ExceptionResult::SendToApplication)
312 continue_status = DBG_EXCEPTION_NOT_HANDLED;
Zachary Turner6c3c0ed2015-10-02 22:47:04 +0000313
Zachary Turner610e5292015-05-07 21:39:33 +0000314 break;
315 }
316 case CREATE_THREAD_DEBUG_EVENT:
317 continue_status = HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
318 break;
319 case CREATE_PROCESS_DEBUG_EVENT:
320 continue_status = HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
321 break;
322 case EXIT_THREAD_DEBUG_EVENT:
323 continue_status = HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
324 break;
325 case EXIT_PROCESS_DEBUG_EVENT:
326 continue_status = HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000327 should_debug = false;
Zachary Turner610e5292015-05-07 21:39:33 +0000328 break;
329 case LOAD_DLL_DEBUG_EVENT:
330 continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
331 break;
332 case UNLOAD_DLL_DEBUG_EVENT:
333 continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
334 break;
335 case OUTPUT_DEBUG_STRING_EVENT:
336 continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
337 break;
338 case RIP_EVENT:
339 continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
340 if (dbe.u.RipInfo.dwType == SLE_ERROR)
341 should_debug = false;
342 break;
343 }
Zachary Turner02862bc2014-11-07 23:44:13 +0000344
Zachary Turner610e5292015-05-07 21:39:33 +0000345 WINLOGD_IFALL(WINDOWS_LOG_EVENT, "DebugLoop calling ContinueDebugEvent(%u, %u, %u) on thread %u.",
346 dbe.dwProcessId, dbe.dwThreadId, continue_status, ::GetCurrentThreadId());
347
348 ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
Adrian McCarthya59a7212015-06-19 18:26:53 +0000349
350 if (m_detached)
351 {
352 should_debug = false;
353 }
Zachary Turner610e5292015-05-07 21:39:33 +0000354 }
355 else
356 {
357 WINERR_IFALL(WINDOWS_LOG_EVENT,
358 "DebugLoop returned FALSE from WaitForDebugEvent. Error = %u",
359 ::GetCurrentThreadId(), ::GetLastError());
360
361 should_debug = false;
362 }
Zachary Turner02862bc2014-11-07 23:44:13 +0000363 }
Zachary Turnerc6a66532014-12-03 22:04:18 +0000364 FreeProcessHandles();
Zachary Turner3c1c5b92015-05-21 19:56:26 +0000365
366 WINLOG_IFALL(WINDOWS_LOG_EVENT, "WaitForDebugEvent loop completed, exiting.");
Adrian McCarthya59a7212015-06-19 18:26:53 +0000367 SetEvent(m_debugging_ended_event);
Zachary Turner02862bc2014-11-07 23:44:13 +0000368}
369
Zachary Turnerdcd80372014-11-11 00:00:14 +0000370ExceptionResult
Zachary Turner02862bc2014-11-07 23:44:13 +0000371DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id)
372{
Zachary Turner6c3c0ed2015-10-02 22:47:04 +0000373 if (m_is_shutting_down)
374 {
375 // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic exception that
376 // we use simply to wake up the DebuggerThread so that we can close out the debug loop.
377 if (m_pid_to_detach != 0 && info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
378 {
379 WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_PROCESS,
380 "Breakpoint exception is cue to detach from process 0x%x",
381 m_pid_to_detach);
382 ::DebugActiveProcessStop(m_pid_to_detach);
383 m_detached = true;
384 }
385
386 // Don't perform any blocking operations while we're shutting down. That will
387 // cause TerminateProcess -> WaitForSingleObject to time out.
388 return ExceptionResult::SendToApplication;
389 }
390
Zachary Turnerdcd80372014-11-11 00:00:14 +0000391 bool first_chance = (info.dwFirstChance != 0);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000392
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000393 m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord, thread_id));
Zachary Turner610e5292015-05-07 21:39:33 +0000394 WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000395 "HandleExceptionEvent encountered %s chance exception 0x%x on thread 0x%x",
Zachary Turner610e5292015-05-07 21:39:33 +0000396 first_chance ? "first" : "second", info.ExceptionRecord.ExceptionCode, thread_id);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000397
Zachary Turner610e5292015-05-07 21:39:33 +0000398 ExceptionResult result = m_debug_delegate->OnDebugException(first_chance,
399 *m_active_exception);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000400 m_exception_pred.SetValue(result, eBroadcastNever);
Zachary Turner610e5292015-05-07 21:39:33 +0000401
402 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
403 "DebuggerThread::HandleExceptionEvent waiting for ExceptionPred != BreakInDebugger");
404
Zachary Turnerc6a66532014-12-03 22:04:18 +0000405 m_exception_pred.WaitForValueNotEqualTo(ExceptionResult::BreakInDebugger, result);
406
Zachary Turner610e5292015-05-07 21:39:33 +0000407 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
408 "DebuggerThread::HandleExceptionEvent got ExceptionPred = %u",
409 m_exception_pred.GetValue());
410
Zachary Turnerc6a66532014-12-03 22:04:18 +0000411 return result;
Zachary Turner02862bc2014-11-07 23:44:13 +0000412}
413
414DWORD
415DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id)
416{
Zachary Turner610e5292015-05-07 21:39:33 +0000417 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000418 "HandleCreateThreadEvent Thread 0x%x spawned in process %I64u",
419 thread_id, m_process.GetProcessId());
420 HostThread thread(info.hThread);
421 thread.GetNativeThread().SetOwnsHandle(false);
422 m_debug_delegate->OnCreateThread(thread);
Zachary Turner02862bc2014-11-07 23:44:13 +0000423 return DBG_CONTINUE;
424}
425
426DWORD
427DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id)
428{
Zachary Turner610e5292015-05-07 21:39:33 +0000429 uint32_t process_id = ::GetProcessId(info.hProcess);
430
431 WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS, "HandleCreateProcessEvent process %u spawned", process_id);
432
Zachary Turner02862bc2014-11-07 23:44:13 +0000433 std::string thread_name;
434 llvm::raw_string_ostream name_stream(thread_name);
Zachary Turner610e5292015-05-07 21:39:33 +0000435 name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
Zachary Turner02862bc2014-11-07 23:44:13 +0000436 name_stream.flush();
437 ThisThread::SetName(thread_name.c_str());
438
439 // info.hProcess and info.hThread are closed automatically by Windows when
440 // EXIT_PROCESS_DEBUG_EVENT is received.
441 m_process = HostProcess(info.hProcess);
442 ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
443 m_main_thread = HostThread(info.hThread);
Zachary Turnerc3018992014-11-17 22:42:57 +0000444 m_main_thread.GetNativeThread().SetOwnsHandle(false);
Zachary Turner02862bc2014-11-07 23:44:13 +0000445 m_image_file = info.hFile;
446
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000447 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
448 m_debug_delegate->OnDebuggerConnected(load_addr);
Zachary Turner02862bc2014-11-07 23:44:13 +0000449
450 return DBG_CONTINUE;
451}
452
453DWORD
454DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id)
455{
Zachary Turner610e5292015-05-07 21:39:33 +0000456 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
457 "HandleExitThreadEvent Thread %u exited with code %u in process %I64u",
458 thread_id, info.dwExitCode, m_process.GetProcessId());
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000459 m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
Zachary Turner02862bc2014-11-07 23:44:13 +0000460 return DBG_CONTINUE;
461}
462
463DWORD
464DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id)
465{
Zachary Turner610e5292015-05-07 21:39:33 +0000466 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
467 "HandleExitProcessEvent process %I64u exited with code %u",
468 m_process.GetProcessId(), info.dwExitCode);
469
Oleksiy Vyalov9953f082015-05-15 02:05:10 +0000470 m_debug_delegate->OnExitProcess(info.dwExitCode);
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000471
472 FreeProcessHandles();
Zachary Turner02862bc2014-11-07 23:44:13 +0000473 return DBG_CONTINUE;
474}
475
476DWORD
477DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
478{
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000479 if (info.hFile == nullptr)
480 {
481 // Not sure what this is, so just ignore it.
Zachary Turner610e5292015-05-07 21:39:33 +0000482 WINWARN_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent has a NULL file handle, returning...",
483 m_process.GetProcessId());
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000484 return DBG_CONTINUE;
485 }
486
487 std::vector<char> buffer(1);
488 DWORD required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
489 if (required_size > 0)
490 {
491 buffer.resize(required_size + 1);
492 required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], required_size + 1, VOLUME_NAME_DOS);
493 llvm::StringRef path_str(&buffer[0]);
494 const char *path = path_str.data();
495 if (path_str.startswith("\\\\?\\"))
496 path += 4;
497
498 FileSpec file_spec(path, false);
499 ModuleSpec module_spec(file_spec);
500 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
Zachary Turner610e5292015-05-07 21:39:33 +0000501
502 WINLOG_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent DLL '%s' loaded at address 0x%p...",
503 m_process.GetProcessId(), path, info.lpBaseOfDll);
504
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000505 m_debug_delegate->OnLoadDll(module_spec, load_addr);
506 }
507 else
508 {
Zachary Turner610e5292015-05-07 21:39:33 +0000509 WINERR_IFALL(WINDOWS_LOG_EVENT,
510 "Inferior %I64u - HandleLoadDllEvent Error %u occurred calling GetFinalPathNameByHandle",
511 m_process.GetProcessId(), ::GetLastError());
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000512 }
513 // Windows does not automatically close info.hFile, so we need to do it.
Zachary Turner02862bc2014-11-07 23:44:13 +0000514 ::CloseHandle(info.hFile);
515 return DBG_CONTINUE;
516}
517
518DWORD
519DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
520{
Zachary Turner610e5292015-05-07 21:39:33 +0000521 WINLOG_IFALL(WINDOWS_LOG_EVENT,
522 "HandleUnloadDllEvent process %I64u unloading DLL at addr 0x%p.",
523 m_process.GetProcessId(), info.lpBaseOfDll);
524
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000525 m_debug_delegate->OnUnloadDll(reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
Zachary Turner02862bc2014-11-07 23:44:13 +0000526 return DBG_CONTINUE;
527}
528
529DWORD
530DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id)
531{
532 return DBG_CONTINUE;
533}
534
535DWORD
536DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id)
537{
Zachary Turner610e5292015-05-07 21:39:33 +0000538 WINERR_IFALL(WINDOWS_LOG_EVENT,
539 "HandleRipEvent encountered error %u (type=%u) in process %I64u thread %u",
540 info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
541
Zachary Turner02862bc2014-11-07 23:44:13 +0000542 Error error(info.dwError, eErrorTypeWin32);
Zachary Turnerd6a7b632014-11-12 19:31:39 +0000543 m_debug_delegate->OnDebuggerError(error, info.dwType);
Zachary Turner02862bc2014-11-07 23:44:13 +0000544
545 return DBG_CONTINUE;
546}