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 lldb::pid_t pid = m_process.GetProcessId();
172
174 LLDB_LOG(log, "terminate = {0}, inferior={1}.", terminate, pid);
175
176 // Set m_is_shutting_down to true if it was false. Return if it was already
177 // true.
178 bool expected = false;
179 if (!m_is_shutting_down.compare_exchange_strong(expected, true))
180 return error;
181
182 // Make a copy of the process, since the termination sequence will reset
183 // DebuggerThread's internal copy and it needs to remain open for the Wait
184 // operation.
185 HostProcess process_copy = m_process;
186 lldb::process_t handle = m_process.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.
219
220 // Force a fresh break so that the detach can happen from the debugger
221 // thread.
222 if (!::DebugBreakProcess(
223 GetProcess().GetNativeProcess().GetSystemHandle())) {
224 error = Status(::GetLastError(), eErrorTypeWin32);
225 }
226 }
227
228 LLDB_LOG(log, "waiting for detach from process {0} to complete.", pid);
229
230 DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
231 if (wait_result != WAIT_OBJECT_0) {
232 error = Status(GetLastError(), eErrorTypeWin32);
233 LLDB_LOG(log, "error: WaitForSingleObject({0}, 5000) returned {1}",
234 m_debugging_ended_event, wait_result);
235 } else
236 LLDB_LOG(log, "detach from process {0} completed successfully.", pid);
237
238 if (!error.Success()) {
239 LLDB_LOG(log, "encountered an error while trying to stop process {0}. {1}",
240 pid, error);
241 }
242 return error;
243}
244
246 std::lock_guard<std::mutex> guard(m_active_exception_mutex);
247 return m_active_exception;
248}
249
251 {
252 std::lock_guard<std::mutex> guard(m_active_exception_mutex);
254 return;
255 m_active_exception.reset();
256 }
257
259 LLDB_LOG(log, "broadcasting for inferior process {0}.",
260 m_process.GetProcessId());
261
262 m_exception_pred.SetValue(result, eBroadcastAlways);
263}
264
266 m_dll_event_pred.SetValue(false, eBroadcastNever);
267 m_debug_delegate->ReportDeferredStop();
269 m_dll_event_pred.WaitForValueEqualTo(true);
270}
271
275
279 if (m_image_file) {
280 ::CloseHandle(m_image_file);
281 m_image_file = nullptr;
282 }
283}
284
287 DEBUG_EVENT dbe = {};
288 bool should_debug = true;
289 constexpr unsigned max_drained_events = 64;
290 unsigned drained_events = 0;
291 LLDB_LOG_VERBOSE(log, "Entering WaitForDebugEventEx loop");
292 while (should_debug) {
293 bool draining = !m_is_shutting_down && m_debug_delegate->HasDeferredStop();
294
295 if (draining && drained_events >= max_drained_events) {
296 LLDB_LOG(log, "reporting the stop after taking {0} queued debug events",
297 drained_events);
299 draining = false;
300 }
301
302 if (!draining)
303 drained_events = 0;
304
305 LLDB_LOG_VERBOSE(log, "Calling WaitForDebugEvent");
306 BOOL wait_result = g_wait_for_debug_event(&dbe, draining ? 0 : INFINITE);
307
308 if (draining) {
309 if (!wait_result) {
311 continue;
312 }
313 ++drained_events;
314 }
315
316 if (wait_result) {
317 DWORD continue_status = DBG_CONTINUE;
318 bool shutting_down = m_is_shutting_down;
319 HANDLE exited_process = nullptr;
320 switch (dbe.dwDebugEventCode) {
321 default:
322 llvm_unreachable("Unhandled debug event code!");
323 case EXCEPTION_DEBUG_EVENT: {
325 dbe.u.Exception, dbe.dwThreadId, shutting_down);
326
327 if (status == ExceptionResult::MaskException)
328 continue_status = DBG_CONTINUE;
329 else if (status == ExceptionResult::SendToApplication)
330 continue_status = DBG_EXCEPTION_NOT_HANDLED;
331
332 break;
333 }
334 case CREATE_THREAD_DEBUG_EVENT:
335 continue_status =
336 HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
337 break;
338 case CREATE_PROCESS_DEBUG_EVENT:
339 continue_status =
340 HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
341 break;
342 case EXIT_THREAD_DEBUG_EVENT:
343 continue_status =
344 HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
345 break;
346 case EXIT_PROCESS_DEBUG_EVENT:
347 if (!::DuplicateHandle(::GetCurrentProcess(),
348 m_process.GetNativeProcess().GetSystemHandle(),
349 ::GetCurrentProcess(), &exited_process,
350 SYNCHRONIZE, FALSE, 0))
351 exited_process = nullptr;
352 should_debug = false;
353 break;
354 case LOAD_DLL_DEBUG_EVENT:
355 continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
356 break;
357 case UNLOAD_DLL_DEBUG_EVENT:
358 continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
359 break;
360 case OUTPUT_DEBUG_STRING_EVENT:
361 continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
362 break;
363 case RIP_EVENT:
364 continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
365 if (dbe.u.RipInfo.dwType == SLE_ERROR)
366 should_debug = false;
367 break;
368 }
369
371 log, "calling ContinueDebugEvent({0}, {1}, {2}) on thread {3}.",
372 dbe.dwProcessId, dbe.dwThreadId, continue_status,
373 ::GetCurrentThreadId());
374
375 ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
376
377 if (dbe.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) {
378 if (exited_process) {
379 ::WaitForSingleObject(exited_process, INFINITE);
380 ::CloseHandle(exited_process);
381 }
382 HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
383 }
384
385 // We have to DebugActiveProcessStop after ContinueDebugEvent, otherwise
386 // the target process will crash
387 if (shutting_down) {
388 // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a
389 // magic exception that we use simply to wake up the DebuggerThread so
390 // that we can close out the debug loop.
391 if (m_pid_to_detach != 0 &&
392 (dbe.u.Exception.ExceptionRecord.ExceptionCode ==
393 EXCEPTION_BREAKPOINT ||
394 dbe.u.Exception.ExceptionRecord.ExceptionCode ==
396 LLDB_LOG(log,
397 "Breakpoint exception is cue to detach from process {0:x}",
398 m_pid_to_detach.load());
399
400 // detaching with leaving breakpoint exception event on the queue may
401 // cause target process to crash so process events as possible since
402 // target threads are running at this time, there is possibility to
403 // have some breakpoint exception between last WaitForDebugEventEx and
404 // DebugActiveProcessStop but ignore for now.
405 while (g_wait_for_debug_event(&dbe, 0)) {
406 continue_status = DBG_CONTINUE;
407 if (dbe.dwDebugEventCode == EXCEPTION_DEBUG_EVENT &&
408 !(dbe.u.Exception.ExceptionRecord.ExceptionCode ==
409 EXCEPTION_BREAKPOINT ||
410 dbe.u.Exception.ExceptionRecord.ExceptionCode ==
412 dbe.u.Exception.ExceptionRecord.ExceptionCode ==
413 EXCEPTION_SINGLE_STEP))
414 continue_status = DBG_EXCEPTION_NOT_HANDLED;
415 ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId,
416 continue_status);
417 }
418
419 ::DebugActiveProcessStop(m_pid_to_detach);
420 m_detached = true;
421 }
422 }
423
424 if (m_detached)
425 should_debug = false;
426 } else {
427 LLDB_LOG(log, "returned FALSE from WaitForDebugEventEx. Error = {0}",
428 ::GetLastError());
429
430 should_debug = false;
431 }
432 }
434
435 LLDB_LOG(log, "WaitForDebugEventEx loop completed, exiting.");
436 ::SetEvent(m_debugging_ended_event);
437}
438
440DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
441 DWORD thread_id, bool shutting_down) {
443 if (shutting_down) {
444 bool is_breakpoint =
445 (info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT ||
446 info.ExceptionRecord.ExceptionCode == STATUS_WX86_BREAKPOINT);
447
448 // Don't perform any blocking operations while we're shutting down. That
449 // will cause TerminateProcess -> WaitForSingleObject to time out.
450 // We should not send breakpoint exceptions to the application.
451 return is_breakpoint ? ExceptionResult::MaskException
453 }
454
455 bool first_chance = (info.dwFirstChance != 0);
456
457 ExceptionRecordSP active_exception =
458 std::make_shared<ExceptionRecord>(info.ExceptionRecord, thread_id);
459 {
460 std::lock_guard<std::mutex> guard(m_active_exception_mutex);
461 m_active_exception = active_exception;
462 }
463 // Set this before calling the delegate. The delegate can wake up the thread
464 // driving the debugger, and that thread can call ContinueAsyncException
465 // before OnDebugException returns.
467
468 LLDB_LOG(log, "encountered {0} chance exception {1:x} on thread {2:x}",
469 first_chance ? "first" : "second",
470 info.ExceptionRecord.ExceptionCode, thread_id);
471
472 ExceptionResult result =
473 m_debug_delegate->OnDebugException(first_chance, *active_exception);
474 // The delegate only says what to do, it never continues the exception. If the
475 // result is not BreakInDebugger, continue it here, or the wait below never
476 // ends. If the other thread already continued it, this does nothing and its
477 // result is what the wait below returns.
480 else
481 m_debug_delegate->ReportDeferredStop();
482
483 LLDB_LOG(log, "waiting for ExceptionPred != BreakInDebugger");
484 result = *m_exception_pred.WaitForValueNotEqualTo(
486
487 LLDB_LOG(log, "got ExceptionPred = {0}", (int)m_exception_pred.GetValue());
488 return result;
489}
490
491DWORD
492DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
493 DWORD thread_id) {
495 LLDB_LOG(log, "Thread {0} spawned in process {1}", thread_id,
496 m_process.GetProcessId());
497 HostThread thread(info.hThread);
498 thread.GetNativeThread().SetOwnsHandle(false);
499 m_debug_delegate->OnCreateThread(thread);
500 return DBG_CONTINUE;
501}
502
503/// Read the path the process was created with from its process parameters
504/// (PEB::ProcessParameters->ImagePathName).
505///
506/// This keeps the subst drive, junction or symbolic link the process was
507/// launched through.
508static std::optional<std::string> GetImagePathFromPEB(HANDLE process) {
509 // winternl.h declares NtQueryInformationProcess, but there is no import
510 // library for it.
511 static LazyImport<decltype(&::NtQueryInformationProcess)>
512 s_query_information_process{L"ntdll.dll", "NtQueryInformationProcess"};
513 if (!s_query_information_process)
514 return std::nullopt;
515
516 PROCESS_BASIC_INFORMATION pbi = {};
517 if ((*s_query_information_process)(process, ProcessBasicInformation, &pbi,
518 sizeof(pbi), nullptr) < 0 ||
519 !pbi.PebBaseAddress)
520 return std::nullopt;
521
522 PEB peb = {};
523 if (!::ReadProcessMemory(process, pbi.PebBaseAddress, &peb, sizeof(peb),
524 nullptr) ||
525 !peb.ProcessParameters)
526 return std::nullopt;
527
528 RTL_USER_PROCESS_PARAMETERS params = {};
529 if (!::ReadProcessMemory(process, peb.ProcessParameters, &params,
530 sizeof(params), nullptr) ||
531 !params.ImagePathName.Buffer || params.ImagePathName.Length == 0)
532 return std::nullopt;
533
534 std::wstring wpath(params.ImagePathName.Length / sizeof(wchar_t), L'\0');
535 if (!::ReadProcessMemory(process, params.ImagePathName.Buffer, wpath.data(),
536 params.ImagePathName.Length, nullptr))
537 return std::nullopt;
538
539 std::string path;
540 if (!llvm::convertWideToUTF8(wpath, path))
541 return std::nullopt;
542 // A process launched through an extended-length path has the "\\?\" prefix.
543 return StripExtendedLengthPrefix(path);
544}
545
546DWORD
547DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
548 DWORD thread_id) {
550 uint32_t process_id = ::GetProcessId(info.hProcess);
551
552 LLDB_LOG(log, "process {0} spawned", process_id);
553
554 std::string thread_name;
555 llvm::raw_string_ostream name_stream(thread_name);
556 name_stream << "lldb.plugin.process-windows.secondary[" << process_id << "]";
557 llvm::set_thread_name(thread_name);
558
559 // info.hProcess and info.hThread are closed automatically by Windows when
560 // EXIT_PROCESS_DEBUG_EVENT is received.
561 m_process = HostProcess(info.hProcess);
562 static_cast<HostProcessWindows &>(m_process.GetNativeProcess())
563 .SetOwnsHandle(false);
564 m_main_thread = HostThread(info.hThread);
565 m_main_thread.GetNativeThread().SetOwnsHandle(false);
566 m_image_file = info.hFile;
567
568 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
569 m_image_path = GetImagePathFromPEB(info.hProcess).value_or("");
570 m_debug_delegate->OnDebuggerConnected(load_addr);
571
572 return DBG_CONTINUE;
573}
574
575DWORD
576DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
577 DWORD thread_id) {
579 LLDB_LOG(log, "Thread {0} exited with code {1} in process {2}", thread_id,
580 info.dwExitCode, m_process.GetProcessId());
581 m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
582 return DBG_CONTINUE;
583}
584
585DWORD
586DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
587 DWORD thread_id) {
589 LLDB_LOG(log, "process {0} exited with code {1}", m_process.GetProcessId(),
590 info.dwExitCode);
591
592 m_debug_delegate->OnExitProcess(info.dwExitCode);
593
594 return DBG_CONTINUE;
595}
596
597static std::optional<std::string>
598ConvertNtDevicePathToDosPath(llvm::ArrayRef<wchar_t> nt_path) {
600
601 llvm::SmallVector<wchar_t, MAX_PATH> vol_name(MAX_PATH);
602 HANDLE vol_iter = ::FindFirstVolumeW(vol_name.data(), vol_name.size());
603 if (vol_iter == INVALID_HANDLE_VALUE) {
604 LLDB_LOG(log,
605 "ConvertNtDevicePathToDosPath: FindFirstVolumeW failed, "
606 "error={0}",
607 ::GetLastError());
608 return std::nullopt;
609 }
610 llvm::scope_exit close_iter([&] { ::FindVolumeClose(vol_iter); });
611
612 do {
613 // FindFirstVolumeW yields "\\?\Volume{GUID}\".
614 // QueryDosDeviceW expects "Volume{GUID}".
615 size_t vol_len = ::wcsnlen(vol_name.data(), vol_name.size());
616 if (vol_len < 5 || vol_name[vol_len - 1] != L'\\')
617 continue;
618
619 vol_name[vol_len - 1] = L'\0'; // strip trailing '\' for QueryDosDeviceW
620 llvm::SmallVector<wchar_t, MAX_PATH> dev_name(MAX_PATH);
621 bool ok = ::QueryDosDeviceW(vol_name.data() + 4, // skip "\\?\"
622 dev_name.data(), dev_name.size());
623 vol_name[vol_len - 1] = L'\\'; // restore
624 if (!ok)
625 continue;
626
627 // Check that nt_path begins with this device name followed by '\'.
628 size_t dev_len = ::wcsnlen(dev_name.data(), dev_name.size());
629 if (dev_len == 0 || dev_len >= nt_path.size())
630 continue;
631 if (_wcsnicmp(nt_path.data(), dev_name.data(), dev_len) != 0)
632 continue;
633 if (nt_path[dev_len] != L'\\')
634 continue;
635
636 // Prefer a drive-letter/mount-point over the raw volume GUID path.
637 llvm::ArrayRef<wchar_t> mount(vol_name.data(), vol_len);
638 llvm::SmallVector<wchar_t> mount_names;
639 DWORD names_size = 0;
640 ::GetVolumePathNamesForVolumeNameW(vol_name.data(), nullptr, 0,
641 &names_size);
642 if (names_size > 1) {
643 mount_names.resize(names_size);
644 DWORD written = 0;
645 if (::GetVolumePathNamesForVolumeNameW(
646 vol_name.data(), mount_names.data(), names_size, &written) &&
647 mount_names[0] != L'\0') {
648 mount = llvm::ArrayRef<wchar_t>(
649 mount_names.data(),
650 ::wcsnlen(mount_names.data(), mount_names.size()));
651 }
652 }
653
654 // Build the final path: mount point + rest of nt_path.
655 llvm::SmallVector<wchar_t> dos_wide(mount.begin(), mount.end());
656 if (!dos_wide.empty() && dos_wide.back() == L'\\')
657 dos_wide.pop_back();
658 dos_wide.append(nt_path.begin() + dev_len, nt_path.end());
659
660 std::string result;
661 llvm::convertWideToUTF8(std::wstring_view(dos_wide.data(), dos_wide.size()),
662 result);
663 return result;
664 } while (::FindNextVolumeW(vol_iter, vol_name.data(), vol_name.size()));
665
666 LLDB_LOG(log, "ConvertNtDevicePathToDosPath: no matching volume found");
667 return std::nullopt;
668}
669
670// Query the file name backing the mapping at `addr` in `process` and convert
671// the resulting NT device path to a DOS path.
672static std::optional<std::string> GetMappedFileDosPath(HANDLE process,
673 LPVOID addr) {
674 std::vector<wchar_t> mapped_filename(MAX_PATH + 1);
675 DWORD mapped_len = 0;
676 while (mapped_filename.size() <= PATHCCH_MAX_CCH) {
677 mapped_len = ::GetMappedFileNameW(process, addr, mapped_filename.data(),
678 mapped_filename.size());
679 if (mapped_len == 0)
680 return std::nullopt;
681 if (mapped_len < mapped_filename.size())
682 break;
683 mapped_filename.resize(mapped_filename.size() * 2);
684 }
686 llvm::ArrayRef<wchar_t>(mapped_filename.data(), mapped_len + 1));
687}
688
689static std::optional<std::string> GetFileNameFromHandleFallback(HANDLE hFile) {
690 // Check that file is not empty as we cannot map a file with zero length.
691 DWORD dwFileSizeHi = 0;
692 DWORD dwFileSizeLo = ::GetFileSize(hFile, &dwFileSizeHi);
693 if (dwFileSizeLo == 0 && dwFileSizeHi == 0)
694 return std::nullopt;
695
696 AutoHandle filemap(
697 ::CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 1, nullptr),
698 nullptr);
699 if (!filemap.IsValid())
700 return std::nullopt;
701
702 auto view_deleter = [](void *pMem) { ::UnmapViewOfFile(pMem); };
703 std::unique_ptr<void, decltype(view_deleter)> pMem(
704 ::MapViewOfFile(filemap.get(), FILE_MAP_READ, 0, 0, 1), view_deleter);
705 if (!pMem)
706 return std::nullopt;
707
708 return GetMappedFileDosPath(::GetCurrentProcess(), pMem.get());
709}
710
711/// The path the loader recorded for the module at \p base_addr, or nullopt if
712/// the loader's module list has no entry for it yet.
713static std::optional<std::string> GetLoaderModuleName(HANDLE process,
714 LPVOID base_addr) {
715 std::vector<wchar_t> module_filename(MAX_PATH + 1);
716 while (module_filename.size() <= PATHCCH_MAX_CCH) {
717 DWORD len =
718 ::GetModuleFileNameExW(process, reinterpret_cast<HMODULE>(base_addr),
719 module_filename.data(), module_filename.size());
720 if (len == 0)
721 return std::nullopt;
722 if (len < module_filename.size()) {
723 std::string path_utf8;
724 llvm::convertWideToUTF8(std::wstring_view(module_filename.data(), len),
725 path_utf8);
726 return path_utf8;
727 }
728 module_filename.resize(module_filename.size() * 2);
729 }
730 return std::nullopt;
731}
732
733// Determine how many bytes can be read at `addr` in `process` before crossing
734// out of the committed memory region containing it. Returns 0 if the address is
735// not within a committed region.
736static SIZE_T BytesReadableAt(HANDLE process, LPCVOID addr) {
737 MEMORY_BASIC_INFORMATION mbi{};
738 if (!::VirtualQueryEx(process, addr, &mbi, sizeof(mbi)))
739 return 0;
740 if (mbi.State != MEM_COMMIT)
741 return 0;
742 uintptr_t region_end =
743 reinterpret_cast<uintptr_t>(mbi.BaseAddress) + mbi.RegionSize;
744 uintptr_t a = reinterpret_cast<uintptr_t>(addr);
745 assert(a < region_end);
746 return region_end - a;
747}
748
749static std::optional<std::string> ReadRemotePathStringW(HANDLE process,
750 LPCVOID addr) {
751 SIZE_T limit = std::min<SIZE_T>(PATHCCH_MAX_CCH * sizeof(wchar_t),
752 BytesReadableAt(process, addr));
753 std::vector<wchar_t> buf;
754 for (SIZE_T capacity = MAX_PATH * sizeof(wchar_t);; capacity *= 2) {
755 SIZE_T to_read = std::min<SIZE_T>(capacity, limit);
756 to_read &= ~SIZE_T(1); // round down to a wchar_t boundary
757 if (to_read < sizeof(wchar_t))
758 return std::nullopt;
759
760 buf.resize(to_read / sizeof(wchar_t));
761 SIZE_T bytes_read = 0;
762 if (!::ReadProcessMemory(process, addr, buf.data(), to_read, &bytes_read))
763 return std::nullopt;
764
765 size_t max_chars = bytes_read / sizeof(wchar_t);
766 size_t len = ::wcsnlen(buf.data(), max_chars);
767 if (len < max_chars) { // found the null terminator
768 if (len == 0) // empty string
769 return std::nullopt;
770 std::string result;
771 llvm::convertWideToUTF8(std::wstring_view(buf.data(), len), result);
772 return result;
773 }
774 if (to_read >= limit) // read everything available without a terminator
775 return std::nullopt;
776 }
777}
778
779static std::optional<std::string> ReadRemotePathStringA(HANDLE process,
780 LPCVOID addr) {
781 SIZE_T limit =
782 std::min<SIZE_T>(PATHCCH_MAX_CCH, BytesReadableAt(process, addr));
783 std::vector<char> buf;
784 for (SIZE_T capacity = MAX_PATH;; capacity *= 2) {
785 SIZE_T to_read = std::min<SIZE_T>(capacity, limit);
786 if (to_read == 0)
787 return std::nullopt;
788
789 buf.resize(to_read);
790 SIZE_T bytes_read = 0;
791 if (!::ReadProcessMemory(process, addr, buf.data(), to_read, &bytes_read))
792 return std::nullopt;
793
794 size_t len = ::strnlen(buf.data(), bytes_read);
795 if (len < bytes_read) { // found the null terminator
796 if (len == 0) // empty string
797 return std::nullopt;
798 return std::string(buf.data(), len);
799 }
800 if (to_read >= limit) // read everything available without a terminator
801 return std::nullopt;
802 }
803}
804
805// Resolve the LOAD_DLL_DEBUG_INFO::lpImageName field.
806static std::optional<std::string>
807GetFileNameFromImageNameField(HANDLE process, const LOAD_DLL_DEBUG_INFO &info) {
808 if (info.lpImageName == nullptr)
809 return std::nullopt;
810
811 LPVOID string_addr = nullptr;
812 SIZE_T bytes_read = 0;
813 if (!::ReadProcessMemory(process, info.lpImageName, &string_addr,
814 sizeof(string_addr), &bytes_read) ||
815 bytes_read != sizeof(string_addr))
816 return std::nullopt;
817
818 if (info.fUnicode)
819 return ReadRemotePathStringW(process, string_addr);
820 return ReadRemotePathStringA(process, string_addr);
821}
822
823DWORD
824DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info,
825 DWORD thread_id) {
827
829 auto on_load_dll = [&](llvm::StringRef path) {
830 FileSpec file_spec(path);
831 ModuleSpec module_spec(file_spec);
832 lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
833
834 LLDB_LOG(log, "Inferior {0} - DLL '{1}' loaded at address {2:x}...",
835 m_process.GetProcessId(), path, info.lpBaseOfDll);
836
837 m_dll_event_pred.SetValue(false, eBroadcastNever);
838 action = m_debug_delegate->OnLoadDll(module_spec, load_addr, thread_id);
839 };
840
841 HANDLE process = m_process.GetNativeProcess().GetSystemHandle();
842
843 // Prefer the path the loader used for the DLL, which keeps the subst drive,
844 // junction or symbolic link it was reached through.
845 std::optional<std::string> loader_path =
846 GetFileNameFromImageNameField(process, info);
847 if (loader_path && !llvm::sys::path::is_absolute(
848 *loader_path, llvm::sys::path::Style::windows))
849 loader_path.reset();
850 if (!loader_path)
851 loader_path = GetLoaderModuleName(process, info.lpBaseOfDll);
852 if (loader_path)
853 loader_path = StripExtendedLengthPrefix(*loader_path);
854
855 // The file handle gives the resolved path, with the on-disk case.
856 std::optional<std::string> file_path;
857 if (info.hFile != nullptr) {
858 std::vector<wchar_t> buffer(1);
859 DWORD required_size =
860 GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
861 if (required_size > 0) {
862 buffer.resize(required_size + 1);
863 GetFinalPathNameByHandleW(info.hFile, &buffer[0], required_size,
864 VOLUME_NAME_DOS);
865 std::string path_str_utf8;
866 llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
867 file_path = StripExtendedLengthPrefix(path_str_utf8);
868 } else {
869 file_path = GetFileNameFromHandleFallback(info.hFile);
870 }
871 }
872
873 // The loader's path often differs from the on-disk one only in case (e.g.
874 // C:\windows\System32\KERNEL32.DLL). If that's the case, keep the on disk
875 // spelling.
876 std::optional<std::string> resolved_path = loader_path;
877 if (!resolved_path ||
878 (file_path &&
879 llvm::StringRef(*file_path).equals_insensitive(*resolved_path)))
880 resolved_path = file_path;
881 if (!resolved_path)
882 resolved_path = GetFileNameFromImageNameField(process, info);
883 if (!resolved_path)
884 resolved_path = GetMappedFileDosPath(process, info.lpBaseOfDll);
885
886 if (resolved_path)
887 on_load_dll(*resolved_path);
888 else
889 LLDB_LOG(log,
890 "Inferior {0} - could not resolve path for LOAD_DLL_DEBUG_EVENT "
891 "(hFile={1}, base={2:x}, last error={3})",
892 m_process.GetProcessId(), info.hFile, info.lpBaseOfDll,
893 ::GetLastError());
894
895 // Windows does not automatically close info.hFile, so we need to do it.
896 if (info.hFile != nullptr)
897 ::CloseHandle(info.hFile);
898
899 if (action == DllEventAction::ParkDebugLoop && !m_is_shutting_down.load()) {
900 m_debug_delegate->ReportDeferredStop();
901 m_dll_event_pred.WaitForValueEqualTo(true);
902 }
903 return DBG_CONTINUE;
904}
905
906DWORD
907DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
908 DWORD thread_id) {
910 LLDB_LOG(log, "process {0} unloading DLL at addr {1:x}.",
911 m_process.GetProcessId(), info.lpBaseOfDll);
912
913 m_dll_event_pred.SetValue(false, eBroadcastNever);
914 DllEventAction action = m_debug_delegate->OnUnloadDll(
915 reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll), thread_id);
916 if (action == DllEventAction::ParkDebugLoop && !m_is_shutting_down.load()) {
917 m_debug_delegate->ReportDeferredStop();
918 m_dll_event_pred.WaitForValueEqualTo(true);
919 }
920 return DBG_CONTINUE;
921}
922
923DWORD
924DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info,
925 DWORD thread_id) {
926 m_debug_delegate->OnDebugString(
927 static_cast<lldb::addr_t>(
928 reinterpret_cast<uintptr_t>(info.lpDebugStringData)),
929 info.fUnicode == TRUE, info.nDebugStringLength);
930 return DBG_CONTINUE;
931}
932
933DWORD
934DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id) {
936 LLDB_LOG(log, "encountered error {0} (type={1}) in process {2} thread {3}",
937 info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
938
939 Status error(info.dwError, eErrorTypeWin32);
940 m_debug_delegate->OnDebuggerError(error, info.dwType);
941
942 return DBG_CONTINUE;
943}
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)
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
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