blob: dfc4924f1d07a2d915bbe5b3c95096a200748cb0 [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
286 m_active_exception.reset(new ExceptionRecord(info.ExceptionRecord));
Zachary Turner610e5292015-05-07 21:39:33 +0000287 WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_EXCEPTION,
288 "HandleExceptionEvent encountered %s chance exception 0x%x on thread %u",
289 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,
311 "HandleCreateThreadEvent Thread %u spawned in process %I64u",
312 m_process.GetProcessId(), thread_id);
313
Zachary Turner02862bc2014-11-07 23:44:13 +0000314 return DBG_CONTINUE;
315}
316
317DWORD
318DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id)
319{
Zachary Turner610e5292015-05-07 21:39:33 +0000320 uint32_t process_id = ::GetProcessId(info.hProcess);
321
322 WINLOG_IFANY(WINDOWS_LOG_EVENT | WINDOWS_LOG_PROCESS, "HandleCreateProcessEvent process %u spawned", process_id);
323
Zachary Turner02862bc2014-11-07 23:44:13 +0000324 std::string thread_name;
325 llvm::raw_string_ostream name_stream(thread_name);
Zachary Turner610e5292015-05-07 21:39:33 +0000326 name_stream << "lldb.plugin.process-windows.slave[" << process_id << "]";
Zachary Turner02862bc2014-11-07 23:44:13 +0000327 name_stream.flush();
328 ThisThread::SetName(thread_name.c_str());
329
330 // info.hProcess and info.hThread are closed automatically by Windows when
331 // EXIT_PROCESS_DEBUG_EVENT is received.
332 m_process = HostProcess(info.hProcess);
333 ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
334 m_main_thread = HostThread(info.hThread);
Zachary Turnerc3018992014-11-17 22:42:57 +0000335 m_main_thread.GetNativeThread().SetOwnsHandle(false);
Zachary Turner02862bc2014-11-07 23:44:13 +0000336 m_image_file = info.hFile;
337
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000338 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
339 m_debug_delegate->OnDebuggerConnected(load_addr);
Zachary Turner02862bc2014-11-07 23:44:13 +0000340
341 return DBG_CONTINUE;
342}
343
344DWORD
345DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id)
346{
Zachary Turner610e5292015-05-07 21:39:33 +0000347 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
348 "HandleExitThreadEvent Thread %u exited with code %u in process %I64u",
349 thread_id, info.dwExitCode, m_process.GetProcessId());
350
Zachary Turner02862bc2014-11-07 23:44:13 +0000351 return DBG_CONTINUE;
352}
353
354DWORD
355DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id)
356{
Zachary Turner610e5292015-05-07 21:39:33 +0000357 WINLOG_IFANY(WINDOWS_LOG_EVENT|WINDOWS_LOG_THREAD,
358 "HandleExitProcessEvent process %I64u exited with code %u",
359 m_process.GetProcessId(), info.dwExitCode);
360
Zachary Turnerc6a66532014-12-03 22:04:18 +0000361 FreeProcessHandles();
Zachary Turner02862bc2014-11-07 23:44:13 +0000362
Zachary Turnerc6a66532014-12-03 22:04:18 +0000363 m_debug_delegate->OnExitProcess(info.dwExitCode);
Zachary Turner02862bc2014-11-07 23:44:13 +0000364 return DBG_CONTINUE;
365}
366
367DWORD
368DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
369{
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000370 if (info.hFile == nullptr)
371 {
372 // Not sure what this is, so just ignore it.
Zachary Turner610e5292015-05-07 21:39:33 +0000373 WINWARN_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent has a NULL file handle, returning...",
374 m_process.GetProcessId());
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000375 return DBG_CONTINUE;
376 }
377
378 std::vector<char> buffer(1);
379 DWORD required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
380 if (required_size > 0)
381 {
382 buffer.resize(required_size + 1);
383 required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], required_size + 1, VOLUME_NAME_DOS);
384 llvm::StringRef path_str(&buffer[0]);
385 const char *path = path_str.data();
386 if (path_str.startswith("\\\\?\\"))
387 path += 4;
388
389 FileSpec file_spec(path, false);
390 ModuleSpec module_spec(file_spec);
391 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
Zachary Turner610e5292015-05-07 21:39:33 +0000392
393 WINLOG_IFALL(WINDOWS_LOG_EVENT, "Inferior %I64u - HandleLoadDllEvent DLL '%s' loaded at address 0x%p...",
394 m_process.GetProcessId(), path, info.lpBaseOfDll);
395
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000396 m_debug_delegate->OnLoadDll(module_spec, load_addr);
397 }
398 else
399 {
Zachary Turner610e5292015-05-07 21:39:33 +0000400 WINERR_IFALL(WINDOWS_LOG_EVENT,
401 "Inferior %I64u - HandleLoadDllEvent Error %u occurred calling GetFinalPathNameByHandle",
402 m_process.GetProcessId(), ::GetLastError());
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000403 }
404 // Windows does not automatically close info.hFile, so we need to do it.
Zachary Turner02862bc2014-11-07 23:44:13 +0000405 ::CloseHandle(info.hFile);
406 return DBG_CONTINUE;
407}
408
409DWORD
410DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
411{
Zachary Turner610e5292015-05-07 21:39:33 +0000412 WINLOG_IFALL(WINDOWS_LOG_EVENT,
413 "HandleUnloadDllEvent process %I64u unloading DLL at addr 0x%p.",
414 m_process.GetProcessId(), info.lpBaseOfDll);
415
Zachary Turnera32d2ce2014-11-12 19:31:56 +0000416 m_debug_delegate->OnUnloadDll(reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
Zachary Turner02862bc2014-11-07 23:44:13 +0000417 return DBG_CONTINUE;
418}
419
420DWORD
421DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id)
422{
423 return DBG_CONTINUE;
424}
425
426DWORD
427DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id)
428{
Zachary Turner610e5292015-05-07 21:39:33 +0000429 WINERR_IFALL(WINDOWS_LOG_EVENT,
430 "HandleRipEvent encountered error %u (type=%u) in process %I64u thread %u",
431 info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
432
Zachary Turner02862bc2014-11-07 23:44:13 +0000433 Error error(info.dwError, eErrorTypeWin32);
Zachary Turnerd6a7b632014-11-12 19:31:39 +0000434 m_debug_delegate->OnDebuggerError(error, info.dwType);
Zachary Turner02862bc2014-11-07 23:44:13 +0000435
436 return DBG_CONTINUE;
437}