blob: 3eb5e0f4da4d9d64a935caff8bab5d552613d104 [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 McCarthy27785dd2015-08-24 16:00:51 +000027#include "Plugins/Process/Windows/Live/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 {
Zachary Turner8d8033c2015-09-17 20:18:50 +0000307 if (m_is_shutting_down)
308 {
309 // Don't perform any blocking operations while we're shutting down. That will
310 // cause TerminateProcess -> WaitForSingleObject to time out.
311 continue_status = DBG_EXCEPTION_NOT_HANDLED;
312 break;
313 }
314
Zachary Turner610e5292015-05-07 21:39:33 +0000315 ExceptionResult status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
Zachary Turnerdcd80372014-11-11 00:00:14 +0000316
Zachary Turner610e5292015-05-07 21:39:33 +0000317 if (status == ExceptionResult::MaskException)
318 continue_status = DBG_CONTINUE;
319 else if (status == ExceptionResult::SendToApplication)
320 continue_status = DBG_EXCEPTION_NOT_HANDLED;
321 break;
322 }
323 case CREATE_THREAD_DEBUG_EVENT:
324 continue_status = HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
325 break;
326 case CREATE_PROCESS_DEBUG_EVENT:
327 continue_status = HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
328 break;
329 case EXIT_THREAD_DEBUG_EVENT:
330 continue_status = HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
331 break;
332 case EXIT_PROCESS_DEBUG_EVENT:
333 continue_status = HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000334 should_debug = false;
Zachary Turner610e5292015-05-07 21:39:33 +0000335 break;
336 case LOAD_DLL_DEBUG_EVENT:
337 continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
338 break;
339 case UNLOAD_DLL_DEBUG_EVENT:
340 continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
341 break;
342 case OUTPUT_DEBUG_STRING_EVENT:
343 continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
344 break;
345 case RIP_EVENT:
346 continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
347 if (dbe.u.RipInfo.dwType == SLE_ERROR)
348 should_debug = false;
349 break;
350 }
Zachary Turner02862bc2014-11-07 23:44:13 +0000351
Zachary Turner610e5292015-05-07 21:39:33 +0000352 WINLOGD_IFALL(WINDOWS_LOG_EVENT, "DebugLoop calling ContinueDebugEvent(%u, %u, %u) on thread %u.",
353 dbe.dwProcessId, dbe.dwThreadId, continue_status, ::GetCurrentThreadId());
354
355 ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
Adrian McCarthya59a7212015-06-19 18:26:53 +0000356
357 if (m_detached)
358 {
359 should_debug = false;
360 }
Zachary Turner610e5292015-05-07 21:39:33 +0000361 }
362 else
363 {
364 WINERR_IFALL(WINDOWS_LOG_EVENT,
365 "DebugLoop returned FALSE from WaitForDebugEvent. Error = %u",
366 ::GetCurrentThreadId(), ::GetLastError());
367
368 should_debug = false;
369 }
Zachary Turner02862bc2014-11-07 23:44:13 +0000370 }
Zachary Turnerc6a66532014-12-03 22:04:18 +0000371 FreeProcessHandles();
Zachary Turner3c1c5b92015-05-21 19:56:26 +0000372
373 WINLOG_IFALL(WINDOWS_LOG_EVENT, "WaitForDebugEvent loop completed, exiting.");
Adrian McCarthya59a7212015-06-19 18:26:53 +0000374 SetEvent(m_debugging_ended_event);
Zachary Turner02862bc2014-11-07 23:44:13 +0000375}
376
Zachary Turnerdcd80372014-11-11 00:00:14 +0000377ExceptionResult
Zachary Turner02862bc2014-11-07 23:44:13 +0000378DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id)
379{
Zachary Turnerdcd80372014-11-11 00:00:14 +0000380 bool first_chance = (info.dwFirstChance != 0);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000381
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000382 m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord, thread_id));
Zachary Turner610e5292015-05-07 21:39:33 +0000383 WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000384 "HandleExceptionEvent encountered %s chance exception 0x%x on thread 0x%x",
Zachary Turner610e5292015-05-07 21:39:33 +0000385 first_chance ? "first" : "second", info.ExceptionRecord.ExceptionCode, thread_id);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000386
Adrian McCarthya59a7212015-06-19 18:26:53 +0000387 if (m_pid_to_detach != 0 && m_active_exception->GetExceptionCode() == EXCEPTION_BREAKPOINT) {
388 WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION | WINDOWS_LOG_PROCESS,
389 "Breakpoint exception is cue to detach from process 0x%x",
390 m_pid_to_detach);
391 if (::DebugActiveProcessStop(m_pid_to_detach)) {
392 m_detached = true;
393 return ExceptionResult::MaskException;
394 } else {
395 WINLOG_IFANY(WINDOWS_LOG_PROCESS, "Failed to detach, treating as a regular breakpoint");
396 }
397 }
398
Zachary Turner610e5292015-05-07 21:39:33 +0000399 ExceptionResult result = m_debug_delegate->OnDebugException(first_chance,
400 *m_active_exception);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000401 m_exception_pred.SetValue(result, eBroadcastNever);
Zachary Turner610e5292015-05-07 21:39:33 +0000402
403 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
404 "DebuggerThread::HandleExceptionEvent waiting for ExceptionPred != BreakInDebugger");
405
Zachary Turnerc6a66532014-12-03 22:04:18 +0000406 m_exception_pred.WaitForValueNotEqualTo(ExceptionResult::BreakInDebugger, result);
407
Zachary Turner610e5292015-05-07 21:39:33 +0000408 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
409 "DebuggerThread::HandleExceptionEvent got ExceptionPred = %u",
410 m_exception_pred.GetValue());
411
Zachary Turnerc6a66532014-12-03 22:04:18 +0000412 return result;
Zachary Turner02862bc2014-11-07 23:44:13 +0000413}
414
415DWORD
416DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id)
417{
Zachary Turner610e5292015-05-07 21:39:33 +0000418 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000419 "HandleCreateThreadEvent Thread 0x%x spawned in process %I64u",
420 thread_id, m_process.GetProcessId());
421 HostThread thread(info.hThread);
422 thread.GetNativeThread().SetOwnsHandle(false);
423 m_debug_delegate->OnCreateThread(thread);
Zachary Turner02862bc2014-11-07 23:44:13 +0000424 return DBG_CONTINUE;
425}
426
427DWORD
428DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id)
429{
Zachary Turner610e5292015-05-07 21:39:33 +0000430 uint32_t process_id = ::GetProcessId(info.hProcess);
431
432 WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS, "HandleCreateProcessEvent process %u spawned", process_id);
433
Zachary Turner02862bc2014-11-07 23:44:13 +0000434 std::string thread_name;
435 llvm::raw_string_ostream name_stream(thread_name);
Zachary Turner610e5292015-05-07 21:39:33 +0000436 name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
Zachary Turner02862bc2014-11-07 23:44:13 +0000437 name_stream.flush();
438 ThisThread::SetName(thread_name.c_str());
439
440 // info.hProcess and info.hThread are closed automatically by Windows when
441 // EXIT_PROCESS_DEBUG_EVENT is received.
442 m_process = HostProcess(info.hProcess);
443 ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
444 m_main_thread = HostThread(info.hThread);
Zachary Turnerc3018992014-11-17 22:42:57 +0000445 m_main_thread.GetNativeThread().SetOwnsHandle(false);
Zachary Turner02862bc2014-11-07 23:44:13 +0000446 m_image_file = info.hFile;
447
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000448 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
449 m_debug_delegate->OnDebuggerConnected(load_addr);
Zachary Turner02862bc2014-11-07 23:44:13 +0000450
451 return DBG_CONTINUE;
452}
453
454DWORD
455DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id)
456{
Zachary Turner610e5292015-05-07 21:39:33 +0000457 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
458 "HandleExitThreadEvent Thread %u exited with code %u in process %I64u",
459 thread_id, info.dwExitCode, m_process.GetProcessId());
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000460 m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
Zachary Turner02862bc2014-11-07 23:44:13 +0000461 return DBG_CONTINUE;
462}
463
464DWORD
465DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id)
466{
Zachary Turner610e5292015-05-07 21:39:33 +0000467 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
468 "HandleExitProcessEvent process %I64u exited with code %u",
469 m_process.GetProcessId(), info.dwExitCode);
470
Oleksiy Vyalov9953f082015-05-15 02:05:10 +0000471 m_debug_delegate->OnExitProcess(info.dwExitCode);
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000472
473 FreeProcessHandles();
Zachary Turner02862bc2014-11-07 23:44:13 +0000474 return DBG_CONTINUE;
475}
476
477DWORD
478DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
479{
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000480 if (info.hFile == nullptr)
481 {
482 // Not sure what this is, so just ignore it.
Zachary Turner610e5292015-05-07 21:39:33 +0000483 WINWARN_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent has a NULL file handle, returning...",
484 m_process.GetProcessId());
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000485 return DBG_CONTINUE;
486 }
487
488 std::vector<char> buffer(1);
489 DWORD required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
490 if (required_size > 0)
491 {
492 buffer.resize(required_size + 1);
493 required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], required_size + 1, VOLUME_NAME_DOS);
494 llvm::StringRef path_str(&buffer[0]);
495 const char *path = path_str.data();
496 if (path_str.startswith("\\\\?\\"))
497 path += 4;
498
499 FileSpec file_spec(path, false);
500 ModuleSpec module_spec(file_spec);
501 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
Zachary Turner610e5292015-05-07 21:39:33 +0000502
503 WINLOG_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent DLL '%s' loaded at address 0x%p...",
504 m_process.GetProcessId(), path, info.lpBaseOfDll);
505
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000506 m_debug_delegate->OnLoadDll(module_spec, load_addr);
507 }
508 else
509 {
Zachary Turner610e5292015-05-07 21:39:33 +0000510 WINERR_IFALL(WINDOWS_LOG_EVENT,
511 "Inferior %I64u - HandleLoadDllEvent Error %u occurred calling GetFinalPathNameByHandle",
512 m_process.GetProcessId(), ::GetLastError());
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000513 }
514 // Windows does not automatically close info.hFile, so we need to do it.
Zachary Turner02862bc2014-11-07 23:44:13 +0000515 ::CloseHandle(info.hFile);
516 return DBG_CONTINUE;
517}
518
519DWORD
520DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
521{
Zachary Turner610e5292015-05-07 21:39:33 +0000522 WINLOG_IFALL(WINDOWS_LOG_EVENT,
523 "HandleUnloadDllEvent process %I64u unloading DLL at addr 0x%p.",
524 m_process.GetProcessId(), info.lpBaseOfDll);
525
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000526 m_debug_delegate->OnUnloadDll(reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
Zachary Turner02862bc2014-11-07 23:44:13 +0000527 return DBG_CONTINUE;
528}
529
530DWORD
531DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id)
532{
533 return DBG_CONTINUE;
534}
535
536DWORD
537DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id)
538{
Zachary Turner610e5292015-05-07 21:39:33 +0000539 WINERR_IFALL(WINDOWS_LOG_EVENT,
540 "HandleRipEvent encountered error %u (type=%u) in process %I64u thread %u",
541 info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
542
Zachary Turner02862bc2014-11-07 23:44:13 +0000543 Error error(info.dwError, eErrorTypeWin32);
Zachary Turnerd6a7b632014-11-12 19:31:39 +0000544 m_debug_delegate->OnDebuggerError(error, info.dwType);
Zachary Turner02862bc2014-11-07 23:44:13 +0000545
546 return DBG_CONTINUE;
547}