blob: ad7feaa2d370373c5b193bf57c435de0d289920d [file] [log] [blame]
Alexander Shaposhnikov696bd632016-11-26 05:23:44 +00001//===-- DebuggerThread.cpp --------------------------------------*- C++ -*-===//
Zachary Turner02862bc2014-11-07 23:44:13 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Zachary Turner02862bc2014-11-07 23:44:13 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "DebuggerThread.h"
Zachary Turnerdcd80372014-11-11 00:00:14 +000010#include "ExceptionRecord.h"
Zachary Turner02862bc2014-11-07 23:44:13 +000011#include "IDebugDelegate.h"
Zachary Turner02862bc2014-11-07 23:44:13 +000012
Zachary Turnera32d2ce2014-11-12 19:31:56 +000013#include "lldb/Core/ModuleSpec.h"
Pavel Labathe7404d92019-02-04 15:03:06 +000014#include "lldb/Host/ProcessLaunchInfo.h"
Zachary Turner02862bc2014-11-07 23:44:13 +000015#include "lldb/Host/ThreadLauncher.h"
16#include "lldb/Host/windows/HostProcessWindows.h"
17#include "lldb/Host/windows/HostThreadWindows.h"
18#include "lldb/Host/windows/ProcessLauncherWindows.h"
Zachary Turnerc62733b2015-05-20 18:31:17 +000019#include "lldb/Target/Process.h"
Zachary Turner5713a052017-03-22 18:40:07 +000020#include "lldb/Utility/FileSpec.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000021#include "lldb/Utility/Log.h"
Raphael Isemann7fae4932018-08-30 17:51:10 +000022#include "lldb/Utility/Predicate.h"
Zachary Turner97206d52017-05-12 04:51:55 +000023#include "lldb/Utility/Status.h"
Zachary Turner02862bc2014-11-07 23:44:13 +000024
Adrian McCarthy18a9135d2015-10-28 18:21:45 +000025#include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
Zachary Turner610e5292015-05-07 21:39:33 +000026
Zachary Turnera32d2ce2014-11-12 19:31:56 +000027#include "llvm/ADT/STLExtras.h"
Zachary Turner190fadc2016-03-22 17:58:09 +000028#include "llvm/Support/ConvertUTF.h"
Zachary Turnered96be92017-03-04 01:31:06 +000029#include "llvm/Support/Threading.h"
Zachary Turner02862bc2014-11-07 23:44:13 +000030#include "llvm/Support/raw_ostream.h"
31
32using namespace lldb;
33using namespace lldb_private;
34
Kate Stoneb9c1b512016-09-06 20:57:50 +000035namespace {
36struct DebugLaunchContext {
37 DebugLaunchContext(DebuggerThread *thread,
38 const ProcessLaunchInfo &launch_info)
39 : m_thread(thread), m_launch_info(launch_info) {}
40 DebuggerThread *m_thread;
41 ProcessLaunchInfo m_launch_info;
Zachary Turner02862bc2014-11-07 23:44:13 +000042};
Zachary Turnerc62733b2015-05-20 18:31:17 +000043
Kate Stoneb9c1b512016-09-06 20:57:50 +000044struct DebugAttachContext {
45 DebugAttachContext(DebuggerThread *thread, lldb::pid_t pid,
46 const ProcessAttachInfo &attach_info)
47 : m_thread(thread), m_pid(pid), m_attach_info(attach_info) {}
48 DebuggerThread *m_thread;
49 lldb::pid_t m_pid;
50 ProcessAttachInfo m_attach_info;
Zachary Turnerc62733b2015-05-20 18:31:17 +000051};
Aaron Smithe3037902018-10-10 18:30:32 +000052} // namespace
Zachary Turner02862bc2014-11-07 23:44:13 +000053
54DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
Zachary Turner5a8ad4592016-10-05 17:07:34 +000055 : m_debug_delegate(debug_delegate), m_pid_to_detach(0),
56 m_is_shutting_down(false) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000057 m_debugging_ended_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
Zachary Turner02862bc2014-11-07 23:44:13 +000058}
59
Kate Stoneb9c1b512016-09-06 20:57:50 +000060DebuggerThread::~DebuggerThread() { ::CloseHandle(m_debugging_ended_event); }
61
Zachary Turner97206d52017-05-12 04:51:55 +000062Status DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) {
Pavel Labatha385d2c2017-02-22 10:38:02 +000063 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
64 LLDB_LOG(log, "launching '{0}'", launch_info.GetExecutableFile().GetPath());
Kate Stoneb9c1b512016-09-06 20:57:50 +000065
Zachary Turner97206d52017-05-12 04:51:55 +000066 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
68 HostThread slave_thread(ThreadLauncher::LaunchThread(
69 "lldb.plugin.process-windows.slave[?]", DebuggerThreadLaunchRoutine,
70 context, &error));
71
Pavel Labatha385d2c2017-02-22 10:38:02 +000072 if (!error.Success())
73 LLDB_LOG(log, "couldn't launch debugger thread. {0}", error);
Kate Stoneb9c1b512016-09-06 20:57:50 +000074
75 return error;
Zachary Turner02862bc2014-11-07 23:44:13 +000076}
77
Zachary Turner97206d52017-05-12 04:51:55 +000078Status DebuggerThread::DebugAttach(lldb::pid_t pid,
79 const ProcessAttachInfo &attach_info) {
Pavel Labatha385d2c2017-02-22 10:38:02 +000080 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
81 LLDB_LOG(log, "attaching to '{0}'", pid);
Zachary Turner02862bc2014-11-07 23:44:13 +000082
Zachary Turner97206d52017-05-12 04:51:55 +000083 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +000084 DebugAttachContext *context = new DebugAttachContext(this, pid, attach_info);
85 HostThread slave_thread(ThreadLauncher::LaunchThread(
86 "lldb.plugin.process-windows.slave[?]", DebuggerThreadAttachRoutine,
87 context, &error));
Zachary Turner610e5292015-05-07 21:39:33 +000088
Pavel Labatha385d2c2017-02-22 10:38:02 +000089 if (!error.Success())
90 LLDB_LOG(log, "couldn't attach to process '{0}'. {1}", pid, error);
Zachary Turner02862bc2014-11-07 23:44:13 +000091
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 return error;
Zachary Turner02862bc2014-11-07 23:44:13 +000093}
94
Kate Stoneb9c1b512016-09-06 20:57:50 +000095lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(void *data) {
96 DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
97 lldb::thread_result_t result =
98 context->m_thread->DebuggerThreadLaunchRoutine(context->m_launch_info);
99 delete context;
100 return result;
Zachary Turnerc62733b2015-05-20 18:31:17 +0000101}
102
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(void *data) {
104 DebugAttachContext *context = static_cast<DebugAttachContext *>(data);
105 lldb::thread_result_t result = context->m_thread->DebuggerThreadAttachRoutine(
106 context->m_pid, context->m_attach_info);
107 delete context;
108 return result;
Zachary Turner02862bc2014-11-07 23:44:13 +0000109}
110
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(
112 const ProcessLaunchInfo &launch_info) {
113 // Grab a shared_ptr reference to this so that we know it won't get deleted
Adrian Prantl05097242018-04-30 16:49:04 +0000114 // until after the thread routine has exited.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
Zachary Turnerc62733b2015-05-20 18:31:17 +0000116
Pavel Labatha385d2c2017-02-22 10:38:02 +0000117 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
118 LLDB_LOG(log, "preparing to launch '{0}' on background thread.",
119 launch_info.GetExecutableFile().GetPath());
Zachary Turner02862bc2014-11-07 23:44:13 +0000120
Zachary Turner97206d52017-05-12 04:51:55 +0000121 Status error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000122 ProcessLauncherWindows launcher;
123 HostProcess process(launcher.LaunchProcess(launch_info, error));
124 // If we couldn't create the process, notify waiters immediately. Otherwise
Adrian Prantl05097242018-04-30 16:49:04 +0000125 // enter the debug loop and wait until we get the create process debug
126 // notification. Note that if the process was created successfully, we can
127 // throw away the process handle we got from CreateProcess because Windows
128 // will give us another (potentially more useful?) handle when it sends us
129 // the CREATE_PROCESS_DEBUG_EVENT.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130 if (error.Success())
Zachary Turnerc62733b2015-05-20 18:31:17 +0000131 DebugLoop();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132 else
133 m_debug_delegate->OnDebuggerError(error, 0);
Zachary Turnerc62733b2015-05-20 18:31:17 +0000134
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135 return 0;
136}
137
138lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(
139 lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
140 // Grab a shared_ptr reference to this so that we know it won't get deleted
Adrian Prantl05097242018-04-30 16:49:04 +0000141 // until after the thread routine has exited.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142 std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
143
Pavel Labatha385d2c2017-02-22 10:38:02 +0000144 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
145 LLDB_LOG(log, "preparing to attach to process '{0}' on background thread.",
146 pid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147
148 if (!DebugActiveProcess((DWORD)pid)) {
Zachary Turner97206d52017-05-12 04:51:55 +0000149 Status error(::GetLastError(), eErrorTypeWin32);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000150 m_debug_delegate->OnDebuggerError(error, 0);
Zachary Turnerc62733b2015-05-20 18:31:17 +0000151 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152 }
153
Adrian Prantl05097242018-04-30 16:49:04 +0000154 // The attach was successful, enter the debug loop. From here on out, this
155 // is no different than a create process operation, so all the same comments
156 // in DebugLaunch should apply from this point out.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000157 DebugLoop();
158
159 return 0;
Zachary Turnerc62733b2015-05-20 18:31:17 +0000160}
161
Zachary Turner97206d52017-05-12 04:51:55 +0000162Status DebuggerThread::StopDebugging(bool terminate) {
163 Status error;
Zachary Turnerc6a66532014-12-03 22:04:18 +0000164
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165 lldb::pid_t pid = m_process.GetProcessId();
Zachary Turner610e5292015-05-07 21:39:33 +0000166
Pavel Labatha385d2c2017-02-22 10:38:02 +0000167 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
168 LLDB_LOG(log, "terminate = {0}, inferior={1}.", terminate, pid);
Zachary Turner610e5292015-05-07 21:39:33 +0000169
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170 // Set m_is_shutting_down to true if it was false. Return if it was already
171 // true.
172 bool expected = false;
173 if (!m_is_shutting_down.compare_exchange_strong(expected, true))
Zachary Turnerc6a66532014-12-03 22:04:18 +0000174 return error;
Zachary Turnerc6a66532014-12-03 22:04:18 +0000175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 // Make a copy of the process, since the termination sequence will reset
177 // DebuggerThread's internal copy and it needs to remain open for the Wait
178 // operation.
179 HostProcess process_copy = m_process;
180 lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
Zachary Turnerc6a66532014-12-03 22:04:18 +0000181
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182 if (terminate) {
Stella Stamenova9d6fabf2018-06-13 19:02:44 +0000183 if (handle != nullptr && handle != LLDB_INVALID_PROCESS) {
184 // Initiate the termination before continuing the exception, so that the
185 // next debug event we get is the exit process event, and not some other
186 // event.
187 BOOL terminate_suceeded = TerminateProcess(handle, 0);
188 LLDB_LOG(log,
189 "calling TerminateProcess({0}, 0) (inferior={1}), success={2}",
190 handle, pid, terminate_suceeded);
191 } else {
192 LLDB_LOG(log,
Aaron Smithe3037902018-10-10 18:30:32 +0000193 "NOT calling TerminateProcess because the inferior is not valid "
194 "({0}, 0) (inferior={1})",
Stella Stamenova9d6fabf2018-06-13 19:02:44 +0000195 handle, pid);
196 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 }
Zachary Turner610e5292015-05-07 21:39:33 +0000198
Kate Stoneb9c1b512016-09-06 20:57:50 +0000199 // If we're stuck waiting for an exception to continue (e.g. the user is at a
Adrian Prantl05097242018-04-30 16:49:04 +0000200 // breakpoint messing around in the debugger), continue it now. But only
201 // AFTER calling TerminateProcess to make sure that the very next call to
202 // WaitForDebugEvent is an exit process event.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000203 if (m_active_exception.get()) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000204 LLDB_LOG(log, "masking active exception");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205 ContinueAsyncException(ExceptionResult::MaskException);
206 }
207
208 if (!terminate) {
209 // Indicate that we want to detach.
210 m_pid_to_detach = GetProcess().GetProcessId();
211
212 // Force a fresh break so that the detach can happen from the debugger
213 // thread.
214 if (!::DebugBreakProcess(
215 GetProcess().GetNativeProcess().GetSystemHandle())) {
216 error.SetError(::GetLastError(), eErrorTypeWin32);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000217 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000218 }
219
Pavel Labatha385d2c2017-02-22 10:38:02 +0000220 LLDB_LOG(log, "waiting for detach from process {0} to complete.", pid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000221
222 DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
223 if (wait_result != WAIT_OBJECT_0) {
224 error.SetError(GetLastError(), eErrorTypeWin32);
Pavel Labatha385d2c2017-02-22 10:38:02 +0000225 LLDB_LOG(log, "error: WaitForSingleObject({0}, 5000) returned {1}",
226 m_debugging_ended_event, wait_result);
227 } else
228 LLDB_LOG(log, "detach from process {0} completed successfully.", pid);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000229
230 if (!error.Success()) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000231 LLDB_LOG(log, "encountered an error while trying to stop process {0}. {1}",
232 pid, error);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233 }
234 return error;
Zachary Turnerdcd80372014-11-11 00:00:14 +0000235}
236
Kate Stoneb9c1b512016-09-06 20:57:50 +0000237void DebuggerThread::ContinueAsyncException(ExceptionResult result) {
238 if (!m_active_exception.get())
239 return;
Zachary Turnerdcd80372014-11-11 00:00:14 +0000240
Pavel Labatha385d2c2017-02-22 10:38:02 +0000241 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS |
242 WINDOWS_LOG_EXCEPTION);
243 LLDB_LOG(log, "broadcasting for inferior process {0}.",
244 m_process.GetProcessId());
Zachary Turner6c3c0ed2015-10-02 22:47:04 +0000245
Kate Stoneb9c1b512016-09-06 20:57:50 +0000246 m_active_exception.reset();
247 m_exception_pred.SetValue(result, eBroadcastAlways);
248}
Zachary Turner02862bc2014-11-07 23:44:13 +0000249
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250void DebuggerThread::FreeProcessHandles() {
251 m_process = HostProcess();
252 m_main_thread = HostThread();
253 if (m_image_file) {
254 ::CloseHandle(m_image_file);
255 m_image_file = nullptr;
256 }
257}
Zachary Turner610e5292015-05-07 21:39:33 +0000258
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259void DebuggerThread::DebugLoop() {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000260 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
Zachary Turner5a8ad4592016-10-05 17:07:34 +0000261 DEBUG_EVENT dbe = {};
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262 bool should_debug = true;
Pavel Labatha385d2c2017-02-22 10:38:02 +0000263 LLDB_LOGV(log, "Entering WaitForDebugEvent loop");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000264 while (should_debug) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000265 LLDB_LOGV(log, "Calling WaitForDebugEvent");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000266 BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
267 if (wait_result) {
268 DWORD continue_status = DBG_CONTINUE;
269 switch (dbe.dwDebugEventCode) {
Aaron Smithe3037902018-10-10 18:30:32 +0000270 default:
271 llvm_unreachable("Unhandle debug event code!");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000272 case EXCEPTION_DEBUG_EVENT: {
273 ExceptionResult status =
274 HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
Adrian McCarthya59a7212015-06-19 18:26:53 +0000275
Kate Stoneb9c1b512016-09-06 20:57:50 +0000276 if (status == ExceptionResult::MaskException)
277 continue_status = DBG_CONTINUE;
278 else if (status == ExceptionResult::SendToApplication)
279 continue_status = DBG_EXCEPTION_NOT_HANDLED;
Zachary Turner610e5292015-05-07 21:39:33 +0000280
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281 break;
282 }
283 case CREATE_THREAD_DEBUG_EVENT:
284 continue_status =
285 HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
286 break;
287 case CREATE_PROCESS_DEBUG_EVENT:
288 continue_status =
289 HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
290 break;
291 case EXIT_THREAD_DEBUG_EVENT:
292 continue_status =
293 HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
294 break;
295 case EXIT_PROCESS_DEBUG_EVENT:
296 continue_status =
297 HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
298 should_debug = false;
299 break;
300 case LOAD_DLL_DEBUG_EVENT:
301 continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
302 break;
303 case UNLOAD_DLL_DEBUG_EVENT:
304 continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
305 break;
306 case OUTPUT_DEBUG_STRING_EVENT:
307 continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
308 break;
309 case RIP_EVENT:
310 continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
311 if (dbe.u.RipInfo.dwType == SLE_ERROR)
312 should_debug = false;
313 break;
314 }
315
Pavel Labatha385d2c2017-02-22 10:38:02 +0000316 LLDB_LOGV(log, "calling ContinueDebugEvent({0}, {1}, {2}) on thread {3}.",
317 dbe.dwProcessId, dbe.dwThreadId, continue_status,
318 ::GetCurrentThreadId());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000319
320 ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
321
322 if (m_detached) {
323 should_debug = false;
324 }
325 } else {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000326 LLDB_LOG(log, "returned FALSE from WaitForDebugEvent. Error = {0}",
327 ::GetLastError());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000328
329 should_debug = false;
Zachary Turner02862bc2014-11-07 23:44:13 +0000330 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000331 }
332 FreeProcessHandles();
Zachary Turner3c1c5b92015-05-21 19:56:26 +0000333
Pavel Labatha385d2c2017-02-22 10:38:02 +0000334 LLDB_LOG(log, "WaitForDebugEvent loop completed, exiting.");
Aaron Smithe3037902018-10-10 18:30:32 +0000335 ::SetEvent(m_debugging_ended_event);
Zachary Turner02862bc2014-11-07 23:44:13 +0000336}
337
Zachary Turnerdcd80372014-11-11 00:00:14 +0000338ExceptionResult
Kate Stoneb9c1b512016-09-06 20:57:50 +0000339DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
340 DWORD thread_id) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000341 Log *log =
342 ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000343 if (m_is_shutting_down) {
344 // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic
345 // exception that
346 // we use simply to wake up the DebuggerThread so that we can close out the
347 // debug loop.
348 if (m_pid_to_detach != 0 &&
349 info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000350 LLDB_LOG(log, "Breakpoint exception is cue to detach from process {0:x}",
351 m_pid_to_detach.load());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000352 ::DebugActiveProcessStop(m_pid_to_detach);
353 m_detached = true;
Zachary Turner6c3c0ed2015-10-02 22:47:04 +0000354 }
355
Kate Stoneb9c1b512016-09-06 20:57:50 +0000356 // Don't perform any blocking operations while we're shutting down. That
Adrian Prantl05097242018-04-30 16:49:04 +0000357 // will cause TerminateProcess -> WaitForSingleObject to time out.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000358 return ExceptionResult::SendToApplication;
359 }
Zachary Turnerc6a66532014-12-03 22:04:18 +0000360
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361 bool first_chance = (info.dwFirstChance != 0);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000362
Kate Stoneb9c1b512016-09-06 20:57:50 +0000363 m_active_exception.reset(
364 new ExceptionRecord(info.ExceptionRecord, thread_id));
Pavel Labatha385d2c2017-02-22 10:38:02 +0000365 LLDB_LOG(log, "encountered {0} chance exception {1:x} on thread {2:x}",
366 first_chance ? "first" : "second",
367 info.ExceptionRecord.ExceptionCode, thread_id);
Zachary Turner610e5292015-05-07 21:39:33 +0000368
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369 ExceptionResult result =
370 m_debug_delegate->OnDebugException(first_chance, *m_active_exception);
371 m_exception_pred.SetValue(result, eBroadcastNever);
Zachary Turner610e5292015-05-07 21:39:33 +0000372
Pavel Labatha385d2c2017-02-22 10:38:02 +0000373 LLDB_LOG(log, "waiting for ExceptionPred != BreakInDebugger");
Pavel Labath4b130332018-05-09 14:49:43 +0000374 result = *m_exception_pred.WaitForValueNotEqualTo(
375 ExceptionResult::BreakInDebugger);
Zachary Turner610e5292015-05-07 21:39:33 +0000376
Pavel Labatha385d2c2017-02-22 10:38:02 +0000377 LLDB_LOG(log, "got ExceptionPred = {0}", (int)m_exception_pred.GetValue());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000378 return result;
Zachary Turner02862bc2014-11-07 23:44:13 +0000379}
380
381DWORD
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
383 DWORD thread_id) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000384 Log *log =
385 ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD);
Aaron Smithe3037902018-10-10 18:30:32 +0000386 LLDB_LOG(log, "Thread {0} spawned in process {1}", thread_id,
Pavel Labatha385d2c2017-02-22 10:38:02 +0000387 m_process.GetProcessId());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000388 HostThread thread(info.hThread);
389 thread.GetNativeThread().SetOwnsHandle(false);
390 m_debug_delegate->OnCreateThread(thread);
391 return DBG_CONTINUE;
Zachary Turner02862bc2014-11-07 23:44:13 +0000392}
393
394DWORD
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
396 DWORD thread_id) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000397 Log *log =
398 ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000399 uint32_t process_id = ::GetProcessId(info.hProcess);
Zachary Turner610e5292015-05-07 21:39:33 +0000400
Pavel Labatha385d2c2017-02-22 10:38:02 +0000401 LLDB_LOG(log, "process {0} spawned", process_id);
Zachary Turner610e5292015-05-07 21:39:33 +0000402
Kate Stoneb9c1b512016-09-06 20:57:50 +0000403 std::string thread_name;
404 llvm::raw_string_ostream name_stream(thread_name);
405 name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
406 name_stream.flush();
Zachary Turnered96be92017-03-04 01:31:06 +0000407 llvm::set_thread_name(thread_name);
Zachary Turner02862bc2014-11-07 23:44:13 +0000408
Kate Stoneb9c1b512016-09-06 20:57:50 +0000409 // info.hProcess and info.hThread are closed automatically by Windows when
410 // EXIT_PROCESS_DEBUG_EVENT is received.
411 m_process = HostProcess(info.hProcess);
412 ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
413 m_main_thread = HostThread(info.hThread);
414 m_main_thread.GetNativeThread().SetOwnsHandle(false);
415 m_image_file = info.hFile;
Zachary Turner02862bc2014-11-07 23:44:13 +0000416
Kate Stoneb9c1b512016-09-06 20:57:50 +0000417 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
418 m_debug_delegate->OnDebuggerConnected(load_addr);
Zachary Turner02862bc2014-11-07 23:44:13 +0000419
Kate Stoneb9c1b512016-09-06 20:57:50 +0000420 return DBG_CONTINUE;
Zachary Turner02862bc2014-11-07 23:44:13 +0000421}
422
423DWORD
Kate Stoneb9c1b512016-09-06 20:57:50 +0000424DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
425 DWORD thread_id) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000426 Log *log =
427 ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD);
428 LLDB_LOG(log, "Thread {0} exited with code {1} in process {2}", thread_id,
429 info.dwExitCode, m_process.GetProcessId());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000430 m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
431 return DBG_CONTINUE;
Zachary Turner02862bc2014-11-07 23:44:13 +0000432}
433
434DWORD
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
436 DWORD thread_id) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000437 Log *log =
438 ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT | WINDOWS_LOG_THREAD);
439 LLDB_LOG(log, "process {0} exited with code {1}", m_process.GetProcessId(),
440 info.dwExitCode);
Zachary Turner610e5292015-05-07 21:39:33 +0000441
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442 m_debug_delegate->OnExitProcess(info.dwExitCode);
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000443
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444 return DBG_CONTINUE;
Zachary Turner02862bc2014-11-07 23:44:13 +0000445}
446
447DWORD
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info,
449 DWORD thread_id) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000450 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451 if (info.hFile == nullptr) {
452 // Not sure what this is, so just ignore it.
Pavel Labatha385d2c2017-02-22 10:38:02 +0000453 LLDB_LOG(log, "Warning: Inferior {0} has a NULL file handle, returning...",
454 m_process.GetProcessId());
Zachary Turner02862bc2014-11-07 23:44:13 +0000455 return DBG_CONTINUE;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000456 }
457
458 std::vector<wchar_t> buffer(1);
459 DWORD required_size =
460 GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
461 if (required_size > 0) {
462 buffer.resize(required_size + 1);
463 required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0],
464 required_size, VOLUME_NAME_DOS);
465 std::string path_str_utf8;
466 llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
467 llvm::StringRef path_str = path_str_utf8;
468 const char *path = path_str.data();
469 if (path_str.startswith("\\\\?\\"))
470 path += 4;
471
Aleksandr Urakov54bb3162018-11-02 08:47:33 +0000472 FileSpec file_spec(path);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000473 ModuleSpec module_spec(file_spec);
474 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
475
Pavel Labatha385d2c2017-02-22 10:38:02 +0000476 LLDB_LOG(log, "Inferior {0} - DLL '{1}' loaded at address {2:x}...",
477 m_process.GetProcessId(), path, info.lpBaseOfDll);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000478
479 m_debug_delegate->OnLoadDll(module_spec, load_addr);
480 } else {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000481 LLDB_LOG(
482 log,
483 "Inferior {0} - Error {1} occurred calling GetFinalPathNameByHandle",
484 m_process.GetProcessId(), ::GetLastError());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000485 }
486 // Windows does not automatically close info.hFile, so we need to do it.
487 ::CloseHandle(info.hFile);
488 return DBG_CONTINUE;
Zachary Turner02862bc2014-11-07 23:44:13 +0000489}
490
491DWORD
Kate Stoneb9c1b512016-09-06 20:57:50 +0000492DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
493 DWORD thread_id) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000494 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
495 LLDB_LOG(log, "process {0} unloading DLL at addr {1:x}.",
496 m_process.GetProcessId(), info.lpBaseOfDll);
Zachary Turner610e5292015-05-07 21:39:33 +0000497
Kate Stoneb9c1b512016-09-06 20:57:50 +0000498 m_debug_delegate->OnUnloadDll(
499 reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
500 return DBG_CONTINUE;
Zachary Turner02862bc2014-11-07 23:44:13 +0000501}
502
503DWORD
Kate Stoneb9c1b512016-09-06 20:57:50 +0000504DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info,
505 DWORD thread_id) {
506 return DBG_CONTINUE;
Zachary Turner02862bc2014-11-07 23:44:13 +0000507}
508
509DWORD
Kate Stoneb9c1b512016-09-06 20:57:50 +0000510DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id) {
Pavel Labatha385d2c2017-02-22 10:38:02 +0000511 Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EVENT);
512 LLDB_LOG(log, "encountered error {0} (type={1}) in process {2} thread {3}",
513 info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
Zachary Turner610e5292015-05-07 21:39:33 +0000514
Zachary Turner97206d52017-05-12 04:51:55 +0000515 Status error(info.dwError, eErrorTypeWin32);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000516 m_debug_delegate->OnDebuggerError(error, info.dwType);
Zachary Turner02862bc2014-11-07 23:44:13 +0000517
Kate Stoneb9c1b512016-09-06 20:57:50 +0000518 return DBG_CONTINUE;
Zachary Turner02862bc2014-11-07 23:44:13 +0000519}