blob: 0959fc28489b9fc3ad2affc9c0cab1814fd6a14b [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"
25
Zachary Turner610e5292015-05-07 21:39:33 +000026#include "Plugins/Process/Windows/ProcessWindowsLog.h"
27
Zachary Turnera32d2ce2014-11-12 19:31:56 +000028#include "llvm/ADT/STLExtras.h"
Zachary Turner02862bc2014-11-07 23:44:13 +000029#include "llvm/Support/raw_ostream.h"
30
31using namespace lldb;
32using namespace lldb_private;
33
34namespace
35{
36struct DebugLaunchContext
37{
38 DebugLaunchContext(DebuggerThread *thread, const ProcessLaunchInfo &launch_info)
39 : m_thread(thread)
40 , m_launch_info(launch_info)
41 {
42 }
43 DebuggerThread *m_thread;
44 ProcessLaunchInfo m_launch_info;
45};
46}
47
48DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
49 : m_debug_delegate(debug_delegate)
50 , m_image_file(nullptr)
Zachary Turner02862bc2014-11-07 23:44:13 +000051{
Zachary Turner02862bc2014-11-07 23:44:13 +000052}
53
54DebuggerThread::~DebuggerThread()
55{
Zachary Turner02862bc2014-11-07 23:44:13 +000056}
57
Zachary Turner3985f892014-11-10 22:32:18 +000058Error
Zachary Turner02862bc2014-11-07 23:44:13 +000059DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info)
60{
Zachary Turner610e5292015-05-07 21:39:33 +000061 WINLOG_IFALL(WINDOWS_LOG_PROCESS,
62 "DebuggerThread::DebugLaunch launching '%s'", launch_info.GetExecutableFile().GetPath().c_str());
Zachary Turner02862bc2014-11-07 23:44:13 +000063
Zachary Turner610e5292015-05-07 21:39:33 +000064 Error error;
Zachary Turner02862bc2014-11-07 23:44:13 +000065 DebugLaunchContext *context = new DebugLaunchContext(this, launch_info);
Zachary Turner610e5292015-05-07 21:39:33 +000066 HostThread slave_thread(ThreadLauncher::LaunchThread("lldb.plugin.process-windows.slave[?]",
67 DebuggerThreadRoutine, context, &error));
68
69 if (!error.Success())
70 {
71 WINERR_IFALL(WINDOWS_LOG_PROCESS,
72 "DebugLaunch couldn't launch debugger thread. %s", error.AsCString());
73 }
Zachary Turner02862bc2014-11-07 23:44:13 +000074
Zachary Turner3985f892014-11-10 22:32:18 +000075 return error;
Zachary Turner02862bc2014-11-07 23:44:13 +000076}
77
78lldb::thread_result_t
79DebuggerThread::DebuggerThreadRoutine(void *data)
80{
81 DebugLaunchContext *context = static_cast<DebugLaunchContext *>(data);
82 lldb::thread_result_t result = context->m_thread->DebuggerThreadRoutine(context->m_launch_info);
83 delete context;
84 return result;
85}
86
87lldb::thread_result_t
88DebuggerThread::DebuggerThreadRoutine(const ProcessLaunchInfo &launch_info)
89{
90 // Grab a shared_ptr reference to this so that we know it won't get deleted until after the
91 // thread routine has exited.
92 std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
Zachary Turner02862bc2014-11-07 23:44:13 +000093
Zachary Turner610e5292015-05-07 21:39:33 +000094 WINLOG_IFALL(WINDOWS_LOG_PROCESS,
95 "DebuggerThread preparing to launch '%s'.",
96 launch_info.GetExecutableFile().GetPath().c_str());
97
Zachary Turner02862bc2014-11-07 23:44:13 +000098 Error error;
99 ProcessLauncherWindows launcher;
100 HostProcess process(launcher.LaunchProcess(launch_info, error));
101 // If we couldn't create the process, notify waiters immediately. Otherwise enter the debug
102 // loop and wait until we get the create process debug notification. Note that if the process
103 // was created successfully, we can throw away the process handle we got from CreateProcess
104 // because Windows will give us another (potentially more useful?) handle when it sends us the
105 // CREATE_PROCESS_DEBUG_EVENT.
106 if (error.Success())
107 DebugLoop();
108 else
Zachary Turnerd6a7b632014-11-12 19:31:39 +0000109 m_debug_delegate->OnDebuggerError(error, 0);
Zachary Turner02862bc2014-11-07 23:44:13 +0000110
111 return 0;
112}
113
Zachary Turnerc6a66532014-12-03 22:04:18 +0000114Error
115DebuggerThread::StopDebugging(bool terminate)
116{
117 Error error;
118
Zachary Turner610e5292015-05-07 21:39:33 +0000119 lldb::pid_t pid = m_process.GetProcessId();
120
121 WINLOG_IFALL(WINDOWS_LOG_PROCESS,
122 "StopDebugging('%s') called (inferior=%I64u).",
123 (terminate ? "true" : "false"), pid);
124
Zachary Turnerc6a66532014-12-03 22:04:18 +0000125 if (terminate)
126 {
Zachary Turner610e5292015-05-07 21:39:33 +0000127 // Make a copy of the process, since the termination sequence will reset
128 // DebuggerThread's internal copy and it needs to remain open for the Wait operation.
Zachary Turnerc6a66532014-12-03 22:04:18 +0000129 HostProcess process_copy = m_process;
Zachary Turner610e5292015-05-07 21:39:33 +0000130 lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
Zachary Turnerc6a66532014-12-03 22:04:18 +0000131
Zachary Turner610e5292015-05-07 21:39:33 +0000132 // Initiate the termination before continuing the exception, so that the next debug
133 // event we get is the exit process event, and not some other event.
Zachary Turnerc6a66532014-12-03 22:04:18 +0000134 BOOL terminate_suceeded = TerminateProcess(handle, 0);
Zachary Turner610e5292015-05-07 21:39:33 +0000135 WINLOG_IFALL(WINDOWS_LOG_PROCESS,
136 "StopDebugging called TerminateProcess(0x%p, 0) (inferior=%I64u), success='%s'",
137 handle, pid, (terminate_suceeded ? "true" : "false"));
138
Zachary Turnerc6a66532014-12-03 22:04:18 +0000139
140 // If we're stuck waiting for an exception to continue, continue it now. But only
141 // AFTER setting the termination event, to make sure that we don't race and enter
142 // another wait for another debug event.
143 if (m_active_exception.get())
Zachary Turner610e5292015-05-07 21:39:33 +0000144 {
145 WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_EXCEPTION,
146 "StopDebugging masking active exception");
147
Zachary Turnerc6a66532014-12-03 22:04:18 +0000148 ContinueAsyncException(ExceptionResult::MaskException);
Zachary Turner610e5292015-05-07 21:39:33 +0000149 }
Zachary Turnerc6a66532014-12-03 22:04:18 +0000150
151 // Don't return until the process has exited.
152 if (terminate_suceeded)
153 {
Zachary Turner610e5292015-05-07 21:39:33 +0000154 WINLOG_IFALL(WINDOWS_LOG_PROCESS,
155 "StopDebugging waiting for termination of process %u to complete.", pid);
156
Zachary Turnerc6a66532014-12-03 22:04:18 +0000157 DWORD wait_result = ::WaitForSingleObject(handle, 5000);
158 if (wait_result != WAIT_OBJECT_0)
159 terminate_suceeded = false;
Zachary Turner610e5292015-05-07 21:39:33 +0000160
161 WINLOG_IFALL(WINDOWS_LOG_PROCESS,
162 "StopDebugging WaitForSingleObject(0x%p, 5000) returned %u",
163 handle, wait_result);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000164 }
165
166 if (!terminate_suceeded)
167 error.SetError(GetLastError(), eErrorTypeWin32);
168 }
169 else
170 {
171 error.SetErrorString("Detach not yet supported on Windows.");
172 // TODO: Implement detach.
173 }
Zachary Turner610e5292015-05-07 21:39:33 +0000174
175 if (!error.Success())
176 {
177 WINERR_IFALL(WINDOWS_LOG_PROCESS,
178 "StopDebugging encountered an error while trying to stop process %u. %s",
179 pid, error.AsCString());
180 }
Zachary Turnerc6a66532014-12-03 22:04:18 +0000181 return error;
182}
183
Zachary Turner02862bc2014-11-07 23:44:13 +0000184void
Zachary Turnerdcd80372014-11-11 00:00:14 +0000185DebuggerThread::ContinueAsyncException(ExceptionResult result)
186{
Zachary Turnerc6a66532014-12-03 22:04:18 +0000187 if (!m_active_exception.get())
188 return;
189
Zachary Turner610e5292015-05-07 21:39:33 +0000190 WINLOG_IFANY(WINDOWS_LOG_PROCESS|WINDOWS_LOG_EXCEPTION,
191 "ContinueAsyncException called for inferior process %I64u, broadcasting.",
192 m_process.GetProcessId());
193
Zachary Turnerc6a66532014-12-03 22:04:18 +0000194 m_active_exception.reset();
195 m_exception_pred.SetValue(result, eBroadcastAlways);
196}
197
198void
199DebuggerThread::FreeProcessHandles()
200{
201 m_process = HostProcess();
202 m_main_thread = HostThread();
203 if (m_image_file)
204 {
205 ::CloseHandle(m_image_file);
206 m_image_file = nullptr;
207 }
Zachary Turnerdcd80372014-11-11 00:00:14 +0000208}
209
210void
Zachary Turner02862bc2014-11-07 23:44:13 +0000211DebuggerThread::DebugLoop()
212{
213 DEBUG_EVENT dbe = {0};
Zachary Turnerbe5e1e52014-12-04 22:07:02 +0000214 bool should_debug = true;
Zachary Turner610e5292015-05-07 21:39:33 +0000215 WINLOG_IFALL(WINDOWS_LOG_EVENT, "Entering WaitForDebugEvent loop");
216 while (should_debug)
Zachary Turner02862bc2014-11-07 23:44:13 +0000217 {
Zachary Turner610e5292015-05-07 21:39:33 +0000218 WINLOGD_IFALL(WINDOWS_LOG_EVENT, "Calling WaitForDebugEvent");
219 BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
220 if (wait_result)
Zachary Turner02862bc2014-11-07 23:44:13 +0000221 {
Zachary Turner610e5292015-05-07 21:39:33 +0000222 DWORD continue_status = DBG_CONTINUE;
223 switch (dbe.dwDebugEventCode)
Zachary Turnerdcd80372014-11-11 00:00:14 +0000224 {
Zachary Turner610e5292015-05-07 21:39:33 +0000225 case EXCEPTION_DEBUG_EVENT:
226 {
227 ExceptionResult status = HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
Zachary Turnerdcd80372014-11-11 00:00:14 +0000228
Zachary Turner610e5292015-05-07 21:39:33 +0000229 if (status == ExceptionResult::MaskException)
230 continue_status = DBG_CONTINUE;
231 else if (status == ExceptionResult::SendToApplication)
232 continue_status = DBG_EXCEPTION_NOT_HANDLED;
233 break;
234 }
235 case CREATE_THREAD_DEBUG_EVENT:
236 continue_status = HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
237 break;
238 case CREATE_PROCESS_DEBUG_EVENT:
239 continue_status = HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
240 break;
241 case EXIT_THREAD_DEBUG_EVENT:
242 continue_status = HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
243 break;
244 case EXIT_PROCESS_DEBUG_EVENT:
245 continue_status = HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000246 should_debug = false;
Zachary Turner610e5292015-05-07 21:39:33 +0000247 break;
248 case LOAD_DLL_DEBUG_EVENT:
249 continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
250 break;
251 case UNLOAD_DLL_DEBUG_EVENT:
252 continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
253 break;
254 case OUTPUT_DEBUG_STRING_EVENT:
255 continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
256 break;
257 case RIP_EVENT:
258 continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
259 if (dbe.u.RipInfo.dwType == SLE_ERROR)
260 should_debug = false;
261 break;
262 }
Zachary Turner02862bc2014-11-07 23:44:13 +0000263
Zachary Turner610e5292015-05-07 21:39:33 +0000264 WINLOGD_IFALL(WINDOWS_LOG_EVENT, "DebugLoop calling ContinueDebugEvent(%u, %u, %u) on thread %u.",
265 dbe.dwProcessId, dbe.dwThreadId, continue_status, ::GetCurrentThreadId());
266
267 ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
268 }
269 else
270 {
271 WINERR_IFALL(WINDOWS_LOG_EVENT,
272 "DebugLoop returned FALSE from WaitForDebugEvent. Error = %u",
273 ::GetCurrentThreadId(), ::GetLastError());
274
275 should_debug = false;
276 }
Zachary Turner02862bc2014-11-07 23:44:13 +0000277 }
Zachary Turnerc6a66532014-12-03 22:04:18 +0000278 FreeProcessHandles();
Zachary Turner02862bc2014-11-07 23:44:13 +0000279}
280
Zachary Turnerdcd80372014-11-11 00:00:14 +0000281ExceptionResult
Zachary Turner02862bc2014-11-07 23:44:13 +0000282DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id)
283{
Zachary Turnerdcd80372014-11-11 00:00:14 +0000284 bool first_chance = (info.dwFirstChance != 0);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000285
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000286 m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord, thread_id));
Zachary Turner610e5292015-05-07 21:39:33 +0000287 WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000288 "HandleExceptionEvent encountered %s chance exception 0x%x on thread 0x%x",
Zachary Turner610e5292015-05-07 21:39:33 +0000289 first_chance ? "first" : "second", info.ExceptionRecord.ExceptionCode, thread_id);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000290
Zachary Turner610e5292015-05-07 21:39:33 +0000291 ExceptionResult result = m_debug_delegate->OnDebugException(first_chance,
292 *m_active_exception);
Zachary Turnerc6a66532014-12-03 22:04:18 +0000293 m_exception_pred.SetValue(result, eBroadcastNever);
Zachary Turner610e5292015-05-07 21:39:33 +0000294
295 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
296 "DebuggerThread::HandleExceptionEvent waiting for ExceptionPred != BreakInDebugger");
297
Zachary Turnerc6a66532014-12-03 22:04:18 +0000298 m_exception_pred.WaitForValueNotEqualTo(ExceptionResult::BreakInDebugger, result);
299
Zachary Turner610e5292015-05-07 21:39:33 +0000300 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_EXCEPTION,
301 "DebuggerThread::HandleExceptionEvent got ExceptionPred = %u",
302 m_exception_pred.GetValue());
303
Zachary Turnerc6a66532014-12-03 22:04:18 +0000304 return result;
Zachary Turner02862bc2014-11-07 23:44:13 +0000305}
306
307DWORD
308DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id)
309{
Zachary Turner610e5292015-05-07 21:39:33 +0000310 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000311 "HandleCreateThreadEvent Thread 0x%x spawned in process %I64u",
312 thread_id, m_process.GetProcessId());
313 HostThread thread(info.hThread);
314 thread.GetNativeThread().SetOwnsHandle(false);
315 m_debug_delegate->OnCreateThread(thread);
Zachary Turner02862bc2014-11-07 23:44:13 +0000316 return DBG_CONTINUE;
317}
318
319DWORD
320DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id)
321{
Zachary Turner610e5292015-05-07 21:39:33 +0000322 uint32_t process_id = ::GetProcessId(info.hProcess);
323
324 WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS, "HandleCreateProcessEvent process %u spawned", process_id);
325
Zachary Turner02862bc2014-11-07 23:44:13 +0000326 std::string thread_name;
327 llvm::raw_string_ostream name_stream(thread_name);
Zachary Turner610e5292015-05-07 21:39:33 +0000328 name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
Zachary Turner02862bc2014-11-07 23:44:13 +0000329 name_stream.flush();
330 ThisThread::SetName(thread_name.c_str());
331
332 // info.hProcess and info.hThread are closed automatically by Windows when
333 // EXIT_PROCESS_DEBUG_EVENT is received.
334 m_process = HostProcess(info.hProcess);
335 ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
336 m_main_thread = HostThread(info.hThread);
Zachary Turnerc3018992014-11-17 22:42:57 +0000337 m_main_thread.GetNativeThread().SetOwnsHandle(false);
Zachary Turner02862bc2014-11-07 23:44:13 +0000338 m_image_file = info.hFile;
339
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000340 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
341 m_debug_delegate->OnDebuggerConnected(load_addr);
Zachary Turner02862bc2014-11-07 23:44:13 +0000342
343 return DBG_CONTINUE;
344}
345
346DWORD
347DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id)
348{
Zachary Turner610e5292015-05-07 21:39:33 +0000349 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
350 "HandleExitThreadEvent Thread %u exited with code %u in process %I64u",
351 thread_id, info.dwExitCode, m_process.GetProcessId());
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000352 m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
Zachary Turner02862bc2014-11-07 23:44:13 +0000353 return DBG_CONTINUE;
354}
355
356DWORD
357DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id)
358{
Zachary Turner610e5292015-05-07 21:39:33 +0000359 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
360 "HandleExitProcessEvent process %I64u exited with code %u",
361 m_process.GetProcessId(), info.dwExitCode);
362
Oleksiy Vyalov9953f082015-05-15 02:05:10 +0000363 m_debug_delegate->OnExitProcess(info.dwExitCode);
Adrian McCarthy2f8e4c32015-05-18 23:24:32 +0000364
365 FreeProcessHandles();
Zachary Turner02862bc2014-11-07 23:44:13 +0000366 return DBG_CONTINUE;
367}
368
369DWORD
370DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
371{
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000372 if (info.hFile == nullptr)
373 {
374 // Not sure what this is, so just ignore it.
Zachary Turner610e5292015-05-07 21:39:33 +0000375 WINWARN_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent has a NULL file handle, returning...",
376 m_process.GetProcessId());
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000377 return DBG_CONTINUE;
378 }
379
380 std::vector<char> buffer(1);
381 DWORD required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
382 if (required_size > 0)
383 {
384 buffer.resize(required_size + 1);
385 required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], required_size + 1, VOLUME_NAME_DOS);
386 llvm::StringRef path_str(&buffer[0]);
387 const char *path = path_str.data();
388 if (path_str.startswith("\\\\?\\"))
389 path += 4;
390
391 FileSpec file_spec(path, false);
392 ModuleSpec module_spec(file_spec);
393 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
Zachary Turner610e5292015-05-07 21:39:33 +0000394
395 WINLOG_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent DLL '%s' loaded at address 0x%p...",
396 m_process.GetProcessId(), path, info.lpBaseOfDll);
397
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000398 m_debug_delegate->OnLoadDll(module_spec, load_addr);
399 }
400 else
401 {
Zachary Turner610e5292015-05-07 21:39:33 +0000402 WINERR_IFALL(WINDOWS_LOG_EVENT,
403 "Inferior %I64u - HandleLoadDllEvent Error %u occurred calling GetFinalPathNameByHandle",
404 m_process.GetProcessId(), ::GetLastError());
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000405 }
406 // Windows does not automatically close info.hFile, so we need to do it.
Zachary Turner02862bc2014-11-07 23:44:13 +0000407 ::CloseHandle(info.hFile);
408 return DBG_CONTINUE;
409}
410
411DWORD
412DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
413{
Zachary Turner610e5292015-05-07 21:39:33 +0000414 WINLOG_IFALL(WINDOWS_LOG_EVENT,
415 "HandleUnloadDllEvent process %I64u unloading DLL at addr 0x%p.",
416 m_process.GetProcessId(), info.lpBaseOfDll);
417
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000418 m_debug_delegate->OnUnloadDll(reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
Zachary Turner02862bc2014-11-07 23:44:13 +0000419 return DBG_CONTINUE;
420}
421
422DWORD
423DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id)
424{
425 return DBG_CONTINUE;
426}
427
428DWORD
429DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id)
430{
Zachary Turner610e5292015-05-07 21:39:33 +0000431 WINERR_IFALL(WINDOWS_LOG_EVENT,
432 "HandleRipEvent encountered error %u (type=%u) in process %I64u thread %u",
433 info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
434
Zachary Turner02862bc2014-11-07 23:44:13 +0000435 Error error(info.dwError, eErrorTypeWin32);
Zachary Turnerd6a7b632014-11-12 19:31:39 +0000436 m_debug_delegate->OnDebuggerError(error, info.dwType);
Zachary Turner02862bc2014-11-07 23:44:13 +0000437
438 return DBG_CONTINUE;
439}