LLDB mainline
DebuggerThread.cpp
Go to the documentation of this file.
1//===-- DebuggerThread.cpp ------------------------------------------------===//
2//
3// 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
6//
7//===----------------------------------------------------------------------===//
8
9#include "DebuggerThread.h"
10#include "ExceptionRecord.h"
11#include "IDebugDelegate.h"
12
22#include "lldb/Target/Process.h"
24#include "lldb/Utility/Log.h"
26#include "lldb/Utility/Status.h"
27
29
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/Support/ConvertUTF.h"
33#include "llvm/Support/Path.h"
34#include "llvm/Support/Threading.h"
35#include "llvm/Support/raw_ostream.h"
36
37#include <optional>
38#include <pathcch.h>
39#include <psapi.h>
40#include <winternl.h>
41
42#ifndef STATUS_WX86_BREAKPOINT
43#define STATUS_WX86_BREAKPOINT 0x4000001FL // For WOW64
44#endif
45
46using namespace lldb;
47using namespace lldb_private;
48
49typedef BOOL WINAPI WaitForDebugEventFn(LPDEBUG_EVENT, DWORD);
51
52/// WaitForDebugEventEx is only available on Windows 10+. This lazily checks if
53/// the function is available and falls back to WaitForDebugEvent if
54/// unavailable. The -Ex version ensures correct forwarding of
55/// OutputDebugStringW events.
57 static LazyImport<WaitForDebugEventFn *> s_wait_for_debug_event_ex = {
58 L"kernel32.dll", "WaitForDebugEventEx"};
59
61 return;
62
63 if (!s_wait_for_debug_event_ex) {
66 "WaitForDebugEventEx unavailable, using WaitForDebugEvent instead. "
67 "Unicode strings from OutputDebugStringW might show incorrectly.");
68 g_wait_for_debug_event = &WaitForDebugEvent;
69 } else {
70 g_wait_for_debug_event = *s_wait_for_debug_event_ex;
71 }
72}
73
75 : m_debug_delegate(debug_delegate), m_pid_to_detach(0),
76 m_is_shutting_down(false) {
78 m_debugging_ended_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
79}
80
82
85 LLDB_LOG(log, "launching '{0}'", launch_info.GetExecutableFile().GetPath());
86
87 Status result;
88 llvm::Expected<HostThread> secondary_thread = ThreadLauncher::LaunchThread(
89 "lldb.plugin.process-windows.secondary[?]",
90 [this, launch_info] { return DebuggerThreadLaunchRoutine(launch_info); });
91 if (!secondary_thread) {
92 result = Status::FromError(secondary_thread.takeError());
93 LLDB_LOG(log, "couldn't launch debugger thread. {0}", result);
94 }
95
96 return result;
97}
98
100 const ProcessAttachInfo &attach_info) {
102 LLDB_LOG(log, "attaching to '{0}'", pid);
103
104 Status result;
105 llvm::Expected<HostThread> secondary_thread = ThreadLauncher::LaunchThread(
106 "lldb.plugin.process-windows.secondary[?]", [this, pid, attach_info] {
107 return DebuggerThreadAttachRoutine(pid, attach_info);
108 });
109 if (!secondary_thread) {
110 result = Status::FromError(secondary_thread.takeError());
111 LLDB_LOG(log, "couldn't attach to process '{0}'. {1}", pid, result);
112 }
113
114 return result;
115}
116
118 const ProcessLaunchInfo &launch_info) {
119 // Grab a shared_ptr reference to this so that we know it won't get deleted
120 // until after the thread routine has exited.
121 std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
122
124 LLDB_LOG(log, "preparing to launch '{0}' on background thread.",
125 launch_info.GetExecutableFile().GetPath());
126
128 ProcessLauncherWindows launcher;
129 HostProcess process(launcher.LaunchProcess(launch_info, error));
130 // If we couldn't create the process, notify waiters immediately. Otherwise
131 // enter the debug loop and wait until we get the create process debug
132 // notification. Note that if the process was created successfully, we can
133 // throw away the process handle we got from CreateProcess because Windows
134 // will give us another (potentially more useful?) handle when it sends us
135 // the CREATE_PROCESS_DEBUG_EVENT.
136 if (error.Success())
137 DebugLoop();
138 else
139 m_debug_delegate->OnDebuggerError(error, 0);
140
141 return {};
142}
143
145 lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
146 // Grab a shared_ptr reference to this so that we know it won't get deleted
147 // until after the thread routine has exited.
148 std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
149
151 LLDB_LOG(log, "preparing to attach to process '{0}' on background thread.",
152 pid);
153
154 if (!DebugActiveProcess(static_cast<DWORD>(pid))) {
155 Status error(::GetLastError(), eErrorTypeWin32);
156 m_debug_delegate->OnDebuggerError(error, 0);
157 return {};
158 }
159
160 // The attach was successful, enter the debug loop. From here on out, this
161 // is no different than a create process operation, so all the same comments
162 // in DebugLaunch should apply from this point out.
163 DebugLoop();
164
165 return {};
166}
167
170
171 // Make a copy of the process, since the termination sequence will reset
172 // DebuggerThread's internal copy and it needs to remain open for the Wait
173 // operation.
174 HostProcess process_copy = GetProcess();
175 lldb::pid_t pid = process_copy.GetProcessId();
176
178 LLDB_LOG(log, "terminate = {0}, inferior={1}.", terminate, pid);
179
180 // Set m_is_shutting_down to true if it was false. Return if it was already
181 // true.
182 bool expected = false;
183 if (!m_is_shutting_down.compare_exchange_strong(expected, true))
184 return error;
185
186 lldb::process_t handle = process_copy.GetNativeProcess().GetSystemHandle();
187
188 if (terminate) {
189 if (handle != nullptr && handle != LLDB_INVALID_PROCESS) {
190 // Initiate the termination before continuing the exception, so that the
191 // next debug event we get is the exit process event, and not some other
192 // event.
193 BOOL terminate_succeeded = TerminateProcess(handle, 0);
194 LLDB_LOG(log,
195 "calling TerminateProcess({0}, 0) (inferior={1}), success={2}",
196 handle, pid, terminate_succeeded);
197 } else {
198 LLDB_LOG(log,
199 "NOT calling TerminateProcess because the inferior is not valid "
200 "({0}, 0) (inferior={1})",
201 handle, pid);
202 }
203 }
204
205 // If we're stuck waiting for an exception to continue (e.g. the user is at a
206 // breakpoint messing around in the debugger), continue it now. But only
207 // AFTER calling TerminateProcess to make sure that the very next call to
208 // WaitForDebugEventEx is an exit process event.
209 if (GetActiveException()) {
210 LLDB_LOG(log, "masking active exception");
212 }
213
215
216 if (!terminate) {
217 // Indicate that we want to detach.
218 m_pid_to_detach = pid;
219
220 // Force a fresh break so that the detach can happen from the debugger
221 // thread.
222 if (!::DebugBreakProcess(handle)) {
223 error = Status(::GetLastError(), eErrorTypeWin32);
224 }
225 }
226
227 LLDB_LOG(log, "waiting for detach from process {0} to complete.", pid);
228
229 DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
230 if (wait_result != WAIT_OBJECT_0) {
231 error = Status(GetLastError(), eErrorTypeWin32);
232 LLDB_LOG(log, "error: WaitForSingleObject({0}, 5000) returned {1}",
233 m_debugging_ended_event, wait_result);
234 } else
235 LLDB_LOG(log, "detach from process {0} completed successfully.", pid);
236
237 if (!error.Success()) {
238 LLDB_LOG(log, "encountered an error while trying to stop process {0}. {1}",
239 pid, error);
240 }
241 return error;
242}
243
245 std::lock_guard<std::mutex> guard(m_active_exception_mutex);
246 return m_active_exception;
247}
248
250 {
251 std::lock_guard<std::mutex> guard(m_active_exception_mutex);
253 return;
254 m_active_exception.reset();
255 }
256
258 LLDB_LOG(log, "broadcasting for inferior process {0}.",
259 GetProcess().GetProcessId());
260
261 m_exception_pred.SetValue(result, eBroadcastAlways);
262}
263
265 m_dll_event_pred.SetValue(false, eBroadcastNever);
266 m_debug_delegate->ReportDeferredStop();
268 m_dll_event_pred.WaitForValueEqualTo(true);
269}
270
274
276 *m_process.Lock() = HostProcess();
278 if (m_image_file) {
279 ::CloseHandle(m_image_file);
280 m_image_file = nullptr;
281 }
282}
283
286 DEBUG_EVENT dbe = {};
287 bool should_debug = true;
288 constexpr unsigned max_drained_events = 64;
289 unsigned drained_events = 0;
290 LLDB_LOG_VERBOSE(log, "Entering WaitForDebugEventEx loop");
291 while (should_debug) {
292 bool draining = !m_is_shutting_down && m_debug_delegate->HasDeferredStop();
293
294 if (draining && drained_events >= max_drained_events) {
295 LLDB_LOG(log, "reporting the stop after taking {0} queued debug events",
296 drained_events);
298 draining = false;
299 }
300
301 if (!draining)
302 drained_events = 0;
303
304 LLDB_LOG_VERBOSE(log, "Calling WaitForDebugEvent");
305 BOOL wait_result = g_wait_for_debug_event(&dbe, draining ? 0 : INFINITE);
306
307 if (draining) {
308 if (!wait_result) {
310 continue;
311 }
312 ++drained_events;
313 }
314
315 if (wait_result) {
316 DWORD continue_status = DBG_CONTINUE;
317 bool shutting_down = m_is_shutting_down;
318 HANDLE exited_process = nullptr;
319 switch (dbe.dwDebugEventCode) {
320 default:
321 llvm_unreachable("Unhandled debug event code!");
322 case EXCEPTION_DEBUG_EVENT: {
324 dbe.u.Exception, dbe.dwThreadId, shutting_down);
325
326 if (status == ExceptionResult::MaskException)
327 continue_status = DBG_CONTINUE;
328 else if (status == ExceptionResult::SendToApplication)
329 continue_status = DBG_EXCEPTION_NOT_HANDLED;
330
331 break;
332 }
333 case CREATE_THREAD_DEBUG_EVENT:
334 continue_status =
335 HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
336 break;
337 case CREATE_PROCESS_DEBUG_EVENT:
338 continue_status =
339 HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
340 break;
341 case EXIT_THREAD_DEBUG_EVENT:
342 continue_status =
343 HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
344 break;
345 case EXIT_PROCESS_DEBUG_EVENT:
346 if (!::DuplicateHandle(
347 ::GetCurrentProcess(),
348 GetProcess().GetNativeProcess().GetSystemHandle(),
349 ::GetCurrentProcess(), &exited_process, SYNCHRONIZE, FALSE, 0))
350 exited_process = nullptr;
351 should_debug = false;
352 break;
353 case LOAD_DLL_DEBUG_EVENT:
354 continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
355 break;
356 case UNLOAD_DLL_DEBUG_EVENT:
357 continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
358 break;
359 case OUTPUT_DEBUG_STRING_EVENT:
360 continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
361 break;
362 case RIP_EVENT:
363 continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
364 if (dbe.u.RipInfo.dwType == SLE_ERROR)
365 should_debug = false;
366 break;
367 }
368
370 log, "calling ContinueDebugEvent({0}, {1}, {2}) on thread {3}.",
371 dbe.dwProcessId, dbe.dwThreadId, continue_status,
372 ::GetCurrentThreadId());
373
374 ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
375
376 if (dbe.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) {
377 if (exited_process) {
378 ::WaitForSingleObject(exited_process, INFINITE);
379 ::CloseHandle(exited_process);
380 }
381 HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
382 }
383
384 // We have to DebugActiveProcessStop after ContinueDebugEvent, otherwise
385 // the target process will crash
386 if (shutting_down) {
387 // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a
388 // magic exception that we use simply to wake up the DebuggerThread so
389 // that we can close out the debug loop.
390 if (m_pid_to_detach != 0 &&
391 (dbe.u.Exception.ExceptionRecord.ExceptionCode ==
392 EXCEPTION_BREAKPOINT ||
393 dbe.u.Exception.ExceptionRecord.ExceptionCode ==
395 LLDB_LOG(log,
396 "Breakpoint exception is cue to detach from process {0:x}",
397 m_pid_to_detach.load());
398
399 // detaching with leaving breakpoint exception event on the queue may
400 // cause target process to crash so process events as possible since
401 // target threads are running at this time, there is possibility to
402 // have some breakpoint exception between last WaitForDebugEventEx and
403 // DebugActiveProcessStop but ignore for now.
404 while (g_wait_for_debug_event(&dbe, 0)) {
405 continue_status = DBG_CONTINUE;
406 if (dbe.dwDebugEventCode == EXCEPTION_DEBUG_EVENT &&
407 !(dbe.u.Exception.ExceptionRecord.ExceptionCode ==
408 EXCEPTION_BREAKPOINT ||
409 dbe.u.Exception.ExceptionRecord.ExceptionCode ==
411 dbe.u.Exception.ExceptionRecord.ExceptionCode ==
412 EXCEPTION_SINGLE_STEP))
413 continue_status = DBG_EXCEPTION_NOT_HANDLED;
414 ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId,
415 continue_status);
416 }
417
418 ::DebugActiveProcessStop(m_pid_to_detach);
419 m_detached = true;
420 }
421 }
422
423 if (m_detached)
424 should_debug = false;
425 } else {
426 LLDB_LOG(log, "returned FALSE from WaitForDebugEventEx. Error = {0}",
427 ::GetLastError());
428
429 should_debug = false;
430 }
431 }
433
434 LLDB_LOG(log, "WaitForDebugEventEx loop completed, exiting.");
435 ::SetEvent(m_debugging_ended_event);
436}
437
439DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
440 DWORD thread_id, bool shutting_down) {
442 if (shutting_down) {
443 bool is_breakpoint =
444 (info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT ||
445 info.ExceptionRecord.ExceptionCode == STATUS_WX86_BREAKPOINT);
446
447 // Don't perform any blocking operations while we're shutting down. That
448 // will cause TerminateProcess -> WaitForSingleObject to time out.
449 // We should not send breakpoint exceptions to the application.
450 return is_breakpoint ? ExceptionResult::MaskException
452 }
453
454 bool first_chance = (info.dwFirstChance != 0);
455
456 ExceptionRecordSP active_exception =
457 std::make_shared<ExceptionRecord>(info.ExceptionRecord, thread_id);
458 {
459 std::lock_guard<std::mutex> guard(m_active_exception_mutex);
460 m_active_exception = active_exception;
461 }
462 // Set this before calling the delegate. The delegate can wake up the thread
463 // driving the debugger, and that thread can call ContinueAsyncException
464 // before OnDebugException returns.
466
467 LLDB_LOG(log, "encountered {0} chance exception {1:x} on thread {2:x}",
468 first_chance ? "first" : "second",
469 info.ExceptionRecord.ExceptionCode, thread_id);
470
471 ExceptionResult result =
472 m_debug_delegate->OnDebugException(first_chance, *active_exception);
473 // The delegate only says what to do, it never continues the exception. If the
474 // result is not BreakInDebugger, continue it here, or the wait below never
475 // ends. If the other thread already continued it, this does nothing and its
476 // result is what the wait below returns.
479 else
480 m_debug_delegate->ReportDeferredStop();
481
482 LLDB_LOG(log, "waiting for ExceptionPred != BreakInDebugger");
483 result = *m_exception_pred.WaitForValueNotEqualTo(
485
486 LLDB_LOG(log, "got ExceptionPred = {0}", (int)m_exception_pred.GetValue());
487 return result;
488}
489
490DWORD
491DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
492 DWORD thread_id) {
494 LLDB_LOG(log, "Thread {0} spawned in process {1}", thread_id,
495 GetProcess().GetProcessId());
496 HostThread thread(info.hThread);
497 thread.GetNativeThread().SetOwnsHandle(false);
498 m_debug_delegate->OnCreateThread(thread);
499 return DBG_CONTINUE;
500}
501
502/// Read the path the process was created with from its process parameters
503/// (PEB::ProcessParameters->ImagePathName).
504///
505/// This keeps the subst drive, junction or symbolic link the process was
506/// launched through.
507static std::optional<std::string> GetImagePathFromPEB(HANDLE process) {
508 // winternl.h declares NtQueryInformationProcess, but there is no import
509 // library for it.
510 static LazyImport<decltype(&::NtQueryInformationProcess)>
511 s_query_information_process{L"ntdll.dll", "NtQueryInformationProcess"};
512 if (!s_query_information_process)
513 return std::nullopt;
514
515 PROCESS_BASIC_INFORMATION pbi = {};
516 if ((*s_query_information_process)(process, ProcessBasicInformation, &pbi,
517 sizeof(pbi), nullptr) < 0 ||
518 !pbi.PebBaseAddress)
519 return std::nullopt;
520
521 PEB peb = {};
522 if (!::ReadProcessMemory(process, pbi.PebBaseAddress, &peb, sizeof(peb),
523 nullptr) ||
524 !peb.ProcessParameters)
525 return std::nullopt;
526
527 RTL_USER_PROCESS_PARAMETERS params = {};
528 if (!::ReadProcessMemory(process, peb.ProcessParameters, &params,
529 sizeof(params), nullptr) ||
530 !params.ImagePathName.Buffer || params.ImagePathName.Length == 0)
531 return std::nullopt;
532
533 std::wstring wpath(params.ImagePathName.Length / sizeof(wchar_t), L'\0');
534 if (!::ReadProcessMemory(process, params.ImagePathName.Buffer, wpath.data(),
535 params.ImagePathName.Length, nullptr))
536 return std::nullopt;
537
538 std::string path;
539 if (!llvm::convertWideToUTF8(wpath, path))
540 return std::nullopt;
541 // A process launched through an extended-length path has the "\\?\" prefix.
542 return StripExtendedLengthPrefix(path);
543}
544
545DWORD
546DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
547 DWORD thread_id) {
549 uint32_t process_id = ::GetProcessId(info.hProcess);
550
551 LLDB_LOG(log, "process {0} spawned", process_id);
552
553 std::string thread_name;
554 llvm::raw_string_ostream name_stream(thread_name);
555 name_stream << "lldb.plugin.process-windows.secondary[" << process_id << "]";
556 llvm::set_thread_name(thread_name);
557
558 // info.hProcess and info.hThread are closed automatically by Windows when
559 // EXIT_PROCESS_DEBUG_EVENT is received.
560 {
561 auto process = m_process.Lock();
562 *process = HostProcess(info.hProcess);
563 static_cast<HostProcessWindows &>(process->GetNativeProcess())
564 .SetOwnsHandle(false);
565 }
566 m_main_thread = HostThread(info.hThread);
567 m_main_thread.GetNativeThread().SetOwnsHandle(false);
568 m_image_file = info.hFile;
569
570 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
571 m_image_path = GetImagePathFromPEB(info.hProcess).value_or("");
572 m_debug_delegate->OnDebuggerConnected(load_addr);
573
574 return DBG_CONTINUE;
575}
576
577DWORD
578DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
579 DWORD thread_id) {
581 LLDB_LOG(log, "Thread {0} exited with code {1} in process {2}", thread_id,
582 info.dwExitCode, GetProcess().GetProcessId());
583 m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
584 return DBG_CONTINUE;
585}
586
587DWORD
588DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
589 DWORD thread_id) {
591 LLDB_LOG(log, "process {0} exited with code {1}", GetProcess().GetProcessId(),
592 info.dwExitCode);
593
594 m_debug_delegate->OnExitProcess(info.dwExitCode);
595
596 return DBG_CONTINUE;
597}
598
599static std::optional<std::string>
600ConvertNtDevicePathToDosPath(llvm::ArrayRef<wchar_t> nt_path) {
602
603 llvm::SmallVector<wchar_t, MAX_PATH> vol_name(MAX_PATH);
604 HANDLE vol_iter = ::FindFirstVolumeW(vol_name.data(), vol_name.size());
605 if (vol_iter == INVALID_HANDLE_VALUE) {
606 LLDB_LOG(log,
607 "ConvertNtDevicePathToDosPath: FindFirstVolumeW failed, "
608 "error={0}",
609 ::GetLastError());
610 return std::nullopt;
611 }
612 llvm::scope_exit close_iter([&] { ::FindVolumeClose(vol_iter); });
613
614 do {
615 // FindFirstVolumeW yields "\\?\Volume{GUID}\".
616 // QueryDosDeviceW expects "Volume{GUID}".
617 size_t vol_len = ::wcsnlen(vol_name.data(), vol_name.size());
618 if (vol_len < 5 || vol_name[vol_len - 1] != L'\\')
619 continue;
620
621 vol_name[vol_len - 1] = L'\0'; // strip trailing '\' for QueryDosDeviceW
622 llvm::SmallVector<wchar_t, MAX_PATH> dev_name(MAX_PATH);
623 bool ok = ::QueryDosDeviceW(vol_name.data() + 4, // skip "\\?\"
624 dev_name.data(), dev_name.size());
625 vol_name[vol_len - 1] = L'\\'; // restore
626 if (!ok)
627 continue;
628
629 // Check that nt_path begins with this device name followed by '\'.
630 size_t dev_len = ::wcsnlen(dev_name.data(), dev_name.size());
631 if (dev_len == 0 || dev_len >= nt_path.size())
632 continue;
633 if (_wcsnicmp(nt_path.data(), dev_name.data(), dev_len) != 0)
634 continue;
635 if (nt_path[dev_len] != L'\\')
636 continue;
637
638 // Prefer a drive-letter/mount-point over the raw volume GUID path.
639 llvm::ArrayRef<wchar_t> mount(vol_name.data(), vol_len);
640 llvm::SmallVector<wchar_t> mount_names;
641 DWORD names_size = 0;
642 ::GetVolumePathNamesForVolumeNameW(vol_name.data(), nullptr, 0,
643 &names_size);
644 if (names_size > 1) {
645 mount_names.resize(names_size);
646 DWORD written = 0;
647 if (::GetVolumePathNamesForVolumeNameW(
648 vol_name.data(), mount_names.data(), names_size, &written) &&
649 mount_names[0] != L'\0') {
650 mount = llvm::ArrayRef<wchar_t>(
651 mount_names.data(),
652 ::wcsnlen(mount_names.data(), mount_names.size()));
653 }
654 }
655
656 // Build the final path: mount point + rest of nt_path.
657 llvm::SmallVector<wchar_t> dos_wide(mount.begin(), mount.end());
658 if (!dos_wide.empty() && dos_wide.back() == L'\\')
659 dos_wide.pop_back();
660 dos_wide.append(nt_path.begin() + dev_len, nt_path.end());
661
662 std::string result;
663 llvm::convertWideToUTF8(std::wstring_view(dos_wide.data(), dos_wide.size()),
664 result);
665 return result;
666 } while (::FindNextVolumeW(vol_iter, vol_name.data(), vol_name.size()));
667
668 LLDB_LOG(log, "ConvertNtDevicePathToDosPath: no matching volume found");
669 return std::nullopt;
670}
671
672// Query the file name backing the mapping at `addr` in `process` and convert
673// the resulting NT device path to a DOS path.
674static std::optional<std::string> GetMappedFileDosPath(HANDLE process,
675 LPVOID addr) {
676 std::vector<wchar_t> mapped_filename(MAX_PATH + 1);
677 DWORD mapped_len = 0;
678 while (mapped_filename.size() <= PATHCCH_MAX_CCH) {
679 mapped_len = ::GetMappedFileNameW(process, addr, mapped_filename.data(),
680 mapped_filename.size());
681 if (mapped_len == 0)
682 return std::nullopt;
683 if (mapped_len < mapped_filename.size())
684 break;
685 mapped_filename.resize(mapped_filename.size() * 2);
686 }
688 llvm::ArrayRef<wchar_t>(mapped_filename.data(), mapped_len + 1));
689}
690
691static std::optional<std::string> GetFileNameFromHandleFallback(HANDLE hFile) {
692 // Check that file is not empty as we cannot map a file with zero length.
693 DWORD dwFileSizeHi = 0;
694 DWORD dwFileSizeLo = ::GetFileSize(hFile, &dwFileSizeHi);
695 if (dwFileSizeLo == 0 && dwFileSizeHi == 0)
696 return std::nullopt;
697
698 AutoHandle filemap(
699 ::CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 1, nullptr),
700 nullptr);
701 if (!filemap.IsValid())
702 return std::nullopt;
703
704 auto view_deleter = [](void *pMem) { ::UnmapViewOfFile(pMem); };
705 std::unique_ptr<void, decltype(view_deleter)> pMem(
706 ::MapViewOfFile(filemap.get(), FILE_MAP_READ, 0, 0, 1), view_deleter);
707 if (!pMem)
708 return std::nullopt;
709
710 return GetMappedFileDosPath(::GetCurrentProcess(), pMem.get());
711}
712
713/// The path the loader recorded for the module at \p base_addr, or nullopt if
714/// the loader's module list has no entry for it yet.
715static std::optional<std::string> GetLoaderModuleName(HANDLE process,
716 LPVOID base_addr) {
717 std::vector<wchar_t> module_filename(MAX_PATH + 1);
718 while (module_filename.size() <= PATHCCH_MAX_CCH) {
719 DWORD len =
720 ::GetModuleFileNameExW(process, reinterpret_cast<HMODULE>(base_addr),
721 module_filename.data(), module_filename.size());
722 if (len == 0)
723 return std::nullopt;
724 if (len < module_filename.size()) {
725 std::string path_utf8;
726 llvm::convertWideToUTF8(std::wstring_view(module_filename.data(), len),
727 path_utf8);
728 return path_utf8;
729 }
730 module_filename.resize(module_filename.size() * 2);
731 }
732 return std::nullopt;
733}
734
735// Determine how many bytes can be read at `addr` in `process` before crossing
736// out of the committed memory region containing it. Returns 0 if the address is
737// not within a committed region.
738static SIZE_T BytesReadableAt(HANDLE process, LPCVOID addr) {
739 MEMORY_BASIC_INFORMATION mbi{};
740 if (!::VirtualQueryEx(process, addr, &mbi, sizeof(mbi)))
741 return 0;
742 if (mbi.State != MEM_COMMIT)
743 return 0;
744 uintptr_t region_end =
745 reinterpret_cast<uintptr_t>(mbi.BaseAddress) + mbi.RegionSize;
746 uintptr_t a = reinterpret_cast<uintptr_t>(addr);
747 assert(a < region_end);
748 return region_end - a;
749}
750
751static std::optional<std::string> ReadRemotePathStringW(HANDLE process,
752 LPCVOID addr) {
753 SIZE_T limit = std::min<SIZE_T>(PATHCCH_MAX_CCH * sizeof(wchar_t),
754 BytesReadableAt(process, addr));
755 std::vector<wchar_t> buf;
756 for (SIZE_T capacity = MAX_PATH * sizeof(wchar_t);; capacity *= 2) {
757 SIZE_T to_read = std::min<SIZE_T>(capacity, limit);
758 to_read &= ~SIZE_T(1); // round down to a wchar_t boundary
759 if (to_read < sizeof(wchar_t))
760 return std::nullopt;
761
762 buf.resize(to_read / sizeof(wchar_t));
763 SIZE_T bytes_read = 0;
764 if (!::ReadProcessMemory(process, addr, buf.data(), to_read, &bytes_read))
765 return std::nullopt;
766
767 size_t max_chars = bytes_read / sizeof(wchar_t);
768 size_t len = ::wcsnlen(buf.data(), max_chars);
769 if (len < max_chars) { // found the null terminator
770 if (len == 0) // empty string
771 return std::nullopt;
772 std::string result;
773 llvm::convertWideToUTF8(std::wstring_view(buf.data(), len), result);
774 return result;
775 }
776 if (to_read >= limit) // read everything available without a terminator
777 return std::nullopt;
778 }
779}
780
781static std::optional<std::string> ReadRemotePathStringA(HANDLE process,
782 LPCVOID addr) {
783 SIZE_T limit =
784 std::min<SIZE_T>(PATHCCH_MAX_CCH, BytesReadableAt(process, addr));
785 std::vector<char> buf;
786 for (SIZE_T capacity = MAX_PATH;; capacity *= 2) {
787 SIZE_T to_read = std::min<SIZE_T>(capacity, limit);
788 if (to_read == 0)
789 return std::nullopt;
790
791 buf.resize(to_read);
792 SIZE_T bytes_read = 0;
793 if (!::ReadProcessMemory(process, addr, buf.data(), to_read, &bytes_read))
794 return std::nullopt;
795
796 size_t len = ::strnlen(buf.data(), bytes_read);
797 if (len < bytes_read) { // found the null terminator
798 if (len == 0) // empty string
799 return std::nullopt;
800 return std::string(buf.data(), len);
801 }
802 if (to_read >= limit) // read everything available without a terminator
803 return std::nullopt;
804 }
805}
806
807// Resolve the LOAD_DLL_DEBUG_INFO::lpImageName field.
808static std::optional<std::string>
809GetFileNameFromImageNameField(HANDLE process, const LOAD_DLL_DEBUG_INFO &info) {
810 if (info.lpImageName == nullptr)
811 return std::nullopt;
812
813 LPVOID string_addr = nullptr;
814 SIZE_T bytes_read = 0;
815 if (!::ReadProcessMemory(process, info.lpImageName, &string_addr,
816 sizeof(string_addr), &bytes_read) ||
817 bytes_read != sizeof(string_addr))
818 return std::nullopt;
819
820 if (info.fUnicode)
821 return ReadRemotePathStringW(process, string_addr);
822 return ReadRemotePathStringA(process, string_addr);
823}
824
825DWORD
826DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info,
827 DWORD thread_id) {
829
831 auto on_load_dll = [&](llvm::StringRef path) {
832 FileSpec file_spec(path);
833 ModuleSpec module_spec(file_spec);
834 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
835
836 LLDB_LOG(log, "Inferior {0} - DLL '{1}' loaded at address {2:x}...",
837 GetProcess().GetProcessId(), path, info.lpBaseOfDll);
838
839 m_dll_event_pred.SetValue(false, eBroadcastNever);
840 action = m_debug_delegate->OnLoadDll(module_spec, load_addr, thread_id);
841 };
842
844
845 // Prefer the path the loader used for the DLL, which keeps the subst drive,
846 // junction or symbolic link it was reached through.
847 std::optional<std::string> loader_path =
848 GetFileNameFromImageNameField(process, info);
849 if (loader_path && !llvm::sys::path::is_absolute(
850 *loader_path, llvm::sys::path::Style::windows))
851 loader_path.reset();
852 if (!loader_path)
853 loader_path = GetLoaderModuleName(process, info.lpBaseOfDll);
854 if (loader_path)
855 loader_path = StripExtendedLengthPrefix(*loader_path);
856
857 // The file handle gives the resolved path, with the on-disk case.
858 std::optional<std::string> file_path;
859 if (info.hFile != nullptr) {
860 std::vector<wchar_t> buffer(1);
861 DWORD required_size =
862 GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
863 if (required_size > 0) {
864 buffer.resize(required_size + 1);
865 GetFinalPathNameByHandleW(info.hFile, &buffer[0], required_size,
866 VOLUME_NAME_DOS);
867 std::string path_str_utf8;
868 llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
869 file_path = StripExtendedLengthPrefix(path_str_utf8);
870 } else {
871 file_path = GetFileNameFromHandleFallback(info.hFile);
872 }
873 }
874
875 // The loader's path often differs from the on-disk one only in case (e.g.
876 // C:\windows\System32\KERNEL32.DLL). If that's the case, keep the on disk
877 // spelling.
878 std::optional<std::string> resolved_path = loader_path;
879 if (!resolved_path ||
880 (file_path &&
881 llvm::StringRef(*file_path).equals_insensitive(*resolved_path)))
882 resolved_path = file_path;
883 if (!resolved_path)
884 resolved_path = GetFileNameFromImageNameField(process, info);
885 if (!resolved_path)
886 resolved_path = GetMappedFileDosPath(process, info.lpBaseOfDll);
887
888 if (resolved_path)
889 on_load_dll(*resolved_path);
890 else
891 LLDB_LOG(log,
892 "Inferior {0} - could not resolve path for LOAD_DLL_DEBUG_EVENT "
893 "(hFile={1}, base={2:x}, last error={3})",
894 GetProcess().GetProcessId(), info.hFile, info.lpBaseOfDll,
895 ::GetLastError());
896
897 // Windows does not automatically close info.hFile, so we need to do it.
898 if (info.hFile != nullptr)
899 ::CloseHandle(info.hFile);
900
901 if (action == DllEventAction::ParkDebugLoop && !m_is_shutting_down.load()) {
902 m_debug_delegate->ReportDeferredStop();
903 m_dll_event_pred.WaitForValueEqualTo(true);
904 }
905 return DBG_CONTINUE;
906}
907
908DWORD
909DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
910 DWORD thread_id) {
912 LLDB_LOG(log, "process {0} unloading DLL at addr {1:x}.",
913 GetProcess().GetProcessId(), info.lpBaseOfDll);
914
915 m_dll_event_pred.SetValue(false, eBroadcastNever);
916 DllEventAction action = m_debug_delegate->OnUnloadDll(
917 reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll), thread_id);
918 if (action == DllEventAction::ParkDebugLoop && !m_is_shutting_down.load()) {
919 m_debug_delegate->ReportDeferredStop();
920 m_dll_event_pred.WaitForValueEqualTo(true);
921 }
922 return DBG_CONTINUE;
923}
924
925DWORD
926DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info,
927 DWORD thread_id) {
928 m_debug_delegate->OnDebugString(
929 static_cast<lldb::addr_t>(
930 reinterpret_cast<uintptr_t>(info.lpDebugStringData)),
931 info.fUnicode == TRUE, info.nDebugStringLength);
932 return DBG_CONTINUE;
933}
934
935DWORD
936DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id) {
938 LLDB_LOG(log, "encountered error {0} (type={1}) in process {2} thread {3}",
939 info.dwError, info.dwType, GetProcess().GetProcessId(), thread_id);
940
941 Status error(info.dwError, eErrorTypeWin32);
942 m_debug_delegate->OnDebuggerError(error, info.dwType);
943
944 return DBG_CONTINUE;
945}
static llvm::raw_ostream & error(Stream &strm)
static std::optional< std::string > GetLoaderModuleName(HANDLE process, LPVOID base_addr)
The path the loader recorded for the module at base_addr, or nullopt if the loader's module list has ...
static std::optional< std::string > GetMappedFileDosPath(HANDLE process, LPVOID addr)
static SIZE_T BytesReadableAt(HANDLE process, LPCVOID addr)
static std::optional< std::string > GetImagePathFromPEB(HANDLE process)
Read the path the process was created with from its process parameters (PEB::ProcessParameters->Image...
static WaitForDebugEventFn * g_wait_for_debug_event
static std::optional< std::string > GetFileNameFromImageNameField(HANDLE process, const LOAD_DLL_DEBUG_INFO &info)
static std::optional< std::string > GetFileNameFromHandleFallback(HANDLE hFile)
static std::optional< std::string > ConvertNtDevicePathToDosPath(llvm::ArrayRef< wchar_t > nt_path)
#define STATUS_WX86_BREAKPOINT
BOOL WINAPI WaitForDebugEventFn(LPDEBUG_EVENT, DWORD)
static std::optional< std::string > ReadRemotePathStringW(HANDLE process, LPCVOID addr)
static void InitializeWaitForDebugEvent()
WaitForDebugEventEx is only available on Windows 10+.
static std::optional< std::string > ReadRemotePathStringA(HANDLE process, LPCVOID addr)
DllEventAction
Definition ForwardDecl.h:29
static int ReadProcessMemory(uint8_t *buffer, size_t size, const pt_asid *, uint64_t pc, void *context)
Callback used by libipt for reading the process memory.
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
#define LLDB_LOG_VERBOSE(log,...)
Definition Log.h:382
#define PATHCCH_MAX_CCH
#define MAX_PATH
void * HANDLE
std::atomic< bool > m_is_shutting_down
std::atomic< DWORD > m_pid_to_detach
void ContinueAsyncDllEvent()
Release a HandleLoadDllEvent / HandleUnloadDllEvent that is parked on m_dll_event_pred.
Predicate< bool > m_dll_event_pred
DWORD HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info, DWORD thread_id)
DWORD HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id)
DWORD HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
DWORD HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info, DWORD thread_id)
Status StopDebugging(bool terminate)
DWORD HandleRipEvent(const RIP_INFO &info, DWORD thread_id)
void ContinueAsyncException(ExceptionResult result)
HostProcess GetProcess() const
lldb::thread_result_t DebuggerThreadAttachRoutine(lldb::pid_t pid, const ProcessAttachInfo &launch_info)
DebuggerThread(DebugDelegateSP debug_delegate)
ExceptionRecordSP GetActiveException()
Returns the exception the debug loop is currently reporting, or null if there is none.
void ReportDeferredStopAndWaitForResume()
Have the delegate report the stop it collected, then wait until the client resumes before taking the ...
DWORD HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info, DWORD thread_id)
ExceptionResult HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info, DWORD thread_id, bool shutting_down)
Status DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info)
Guarded< HostProcess > m_process
lldb::thread_result_t DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info)
ExceptionRecordSP m_active_exception
Predicate< ExceptionResult > m_exception_pred
Status DebugLaunch(const ProcessLaunchInfo &launch_info)
DWORD HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info, DWORD thread_id)
DWORD HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info, DWORD thread_id)
A file utility class.
Definition FileSpec.h:56
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
HostNativeProcessBase & GetNativeProcess()
lldb::pid_t GetProcessId() const
FileSpec & GetExecutableFile()
Definition ProcessInfo.h:41
HostProcess LaunchProcess(const ProcessLaunchInfo &launch_info, Status &error) override
An error handling class.
Definition Status.h:118
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
static llvm::Expected< HostThread > LaunchThread(llvm::StringRef name, std::function< lldb::thread_result_t()> thread_function, size_t min_stack_byte_size=0)
#define LLDB_INVALID_PROCESS
Definition lldb-types.h:68
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
std::string StripExtendedLengthPrefix(llvm::StringRef path)
Convert an extended-length path to a regular DOS path: "\\?\C:\a" becomes "C:\a" and "\\?...
Definition PathUtils.h:21
std::shared_ptr< IDebugDelegate > DebugDelegateSP
Definition ForwardDecl.h:45
std::shared_ptr< ExceptionRecord > ExceptionRecordSP
Definition ForwardDecl.h:47
@ eBroadcastNever
No broadcast will be sent when the value is modified.
Definition Predicate.h:28
@ eBroadcastAlways
Always send a broadcast when the value is modified.
Definition Predicate.h:29
void * thread_result_t
Definition lldb-types.h:62
@ eErrorTypeWin32
Standard Win32 error codes.
uint64_t pid_t
Definition lldb-types.h:84
uint64_t addr_t
Definition lldb-types.h:80
uint64_t process_t
Definition lldb-types.h:57