LLDB mainline
ProcessDebugger.cpp
Go to the documentation of this file.
1//===-- ProcessDebugger.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 "ProcessDebugger.h"
10
11// Windows includes
13#include <psapi.h>
14
21#include "lldb/Target/Process.h"
23#include "llvm/Support/ConvertUTF.h"
24#include "llvm/Support/Error.h"
25
26#include "DebuggerThread.h"
27#include "ExceptionRecord.h"
28#include "ProcessWindowsLog.h"
29
30#include <string>
31#include <string_view>
32
33using namespace lldb;
34using namespace lldb_private;
35
36static void NormalizeWindowsPathSeparators(std::string &s) {
37 for (char &c : s)
38 if (c == '/')
39 c = '\\';
40}
41
42bool ProcessDebugger::IsSystemDLL(llvm::StringRef path) {
43 if (path.empty())
44 return false;
45
46 static const std::string windows_prefix = []() {
47 std::string prefix;
48 wchar_t buf[MAX_PATH];
49 UINT len = ::GetWindowsDirectoryW(buf, MAX_PATH);
50 if (len == 0 || len >= MAX_PATH)
51 return prefix;
52 llvm::convertWideToUTF8(std::wstring_view(buf, len), prefix);
54 if (!prefix.empty() && prefix.back() != '\\')
55 prefix += '\\';
56 return prefix;
57 }();
58
59 if (windows_prefix.empty())
60 return false;
61
62 std::string normalized = path.str();
64 return llvm::StringRef(normalized).starts_with_insensitive(windows_prefix);
65}
66
68 if (!m_session_data || !m_session_data->m_debugger)
69 return false;
70 lldb::process_t handle = m_session_data->m_debugger->GetProcess()
71 .GetNativeProcess()
72 .GetSystemHandle();
73 if (handle == nullptr || handle == LLDB_INVALID_PROCESS)
74 return false;
75
76 MEMORY_BASIC_INFORMATION mbi = {};
77 if (::VirtualQueryEx(handle, reinterpret_cast<LPCVOID>(addr), &mbi,
78 sizeof(mbi)) != sizeof(mbi))
79 return false;
80 if (mbi.AllocationBase == nullptr)
81 return false;
82
83 // A truncated path still carries the leading directory, which is all
84 // IsSystemDLL() inspects. MAX_PATH is enough.
85 wchar_t module_path[MAX_PATH];
86 DWORD len = ::GetModuleFileNameExW(
87 handle, reinterpret_cast<HMODULE>(mbi.AllocationBase), module_path,
88 MAX_PATH);
89 if (len == 0)
90 return false;
91
92 std::string path_utf8;
93 llvm::convertWideToUTF8(std::wstring_view(module_path, len), path_utf8);
94 return IsSystemDLL(path_utf8);
95}
96
97static DWORD ConvertLldbToWinApiProtect(uint32_t protect) {
98 // We also can process a read / write permissions here, but if the debugger
99 // will make later a write into the allocated memory, it will fail. To get
100 // around it is possible inside DoWriteMemory to remember memory permissions,
101 // allow write, write and restore permissions, but for now we process only
102 // the executable permission.
103 //
104 // TODO: Process permissions other than executable
105 if (protect & ePermissionsExecutable)
106 return PAGE_EXECUTE_READWRITE;
107
108 return PAGE_READWRITE;
109}
110
111// The Windows page protection bits are NOT independent masks that can be
112// bitwise-ORed together. For example, PAGE_EXECUTE_READ is not (PAGE_EXECUTE
113// | PAGE_READ). To test for an access type, it's necessary to test for any of
114// the bits that provide that access type.
115static bool IsPageReadable(uint32_t protect) {
116 return (protect & PAGE_NOACCESS) == 0;
117}
118
119static bool IsPageWritable(uint32_t protect) {
120 return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY |
121 PAGE_READWRITE | PAGE_WRITECOPY)) != 0;
122}
123
124static bool IsPageExecutable(uint32_t protect) {
125 return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE |
126 PAGE_EXECUTE_WRITECOPY)) != 0;
127}
128
129namespace lldb_private {
130
132
134 if (m_session_data)
135 return m_session_data->m_debugger->GetProcess().GetProcessId();
137}
138
141 DebuggerThreadSP debugger_thread;
142 {
143 // Acquire the lock only long enough to get the DebuggerThread.
144 // StopDebugging() will trigger a call back into ProcessDebugger which will
145 // also acquire the lock. Thus we have to release the lock before calling
146 // StopDebugging().
147 llvm::sys::ScopedLock lock(m_mutex);
148
149 if (!m_session_data) {
150 LLDB_LOG(log, "there is no active session.");
151 return Status();
152 }
153
154 debugger_thread = m_session_data->m_debugger;
155 }
156
158
159 LLDB_LOG(log, "detaching from process {0}.",
160 debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle());
161 error = debugger_thread->StopDebugging(false);
162
163 // By the time StopDebugging returns, there is no more debugger thread, so
164 // we can be assured that no other thread will race for the session data.
165 m_session_data.reset();
166
167 return error;
168}
169
171 DebugDelegateSP delegate) {
172 // Even though m_session_data is accessed here, it is before a debugger
173 // thread has been kicked off. So there's no race conditions, and it
174 // shouldn't be necessary to acquire the mutex.
175
177 Status result;
178
179 FileSpec working_dir = launch_info.GetWorkingDirectory();
180 namespace fs = llvm::sys::fs;
181 if (working_dir) {
182 FileSystem::Instance().Resolve(working_dir);
183 if (!FileSystem::Instance().IsDirectory(working_dir)) {
185 "No such file or directory: %s", working_dir.GetPath().c_str());
186 return result;
187 }
188 }
189
190 if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) {
191 StreamString stream;
192 stream.Printf("ProcessDebugger unable to launch '%s'. ProcessDebugger can "
193 "only be used for debug launches.",
194 launch_info.GetExecutableFile().GetPath().c_str());
195 std::string message = stream.GetString().str();
196 result = Status::FromErrorString(message.c_str());
197
198 LLDB_LOG(log, "error: {0}", message);
199 return result;
200 }
201
202 bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
203 m_session_data.reset(new ProcessWindowsData(stop_at_entry));
204 m_session_data->m_debugger.reset(new DebuggerThread(delegate));
205 DebuggerThreadSP debugger = m_session_data->m_debugger;
206
207 // Kick off the DebugLaunch asynchronously and wait for it to complete.
208 result = debugger->DebugLaunch(launch_info);
209 if (result.Fail()) {
210 LLDB_LOG(log, "failed launching '{0}'. {1}",
211 launch_info.GetExecutableFile().GetPath(), result);
212 return result;
213 }
214
215 HostProcess process;
216 Status error = WaitForDebuggerConnection(debugger, process);
217 if (error.Fail()) {
218 LLDB_LOG(log, "failed launching '{0}'. {1}",
219 launch_info.GetExecutableFile().GetPath(), error);
220 return error;
221 }
222
223 LLDB_LOG(log, "successfully launched '{0}'",
224 launch_info.GetExecutableFile().GetPath());
225
226 // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
227 // private state should already be set to eStateStopped as a result of
228 // hitting the initial breakpoint. If it was not set, the breakpoint should
229 // have already been resumed from and the private state should already be
230 // eStateRunning.
231 launch_info.SetProcessID(process.GetProcessId());
232
233 return result;
234}
235
237 const ProcessAttachInfo &attach_info,
238 DebugDelegateSP delegate) {
240 m_session_data.reset(
241 new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));
242 DebuggerThreadSP debugger(new DebuggerThread(delegate));
243
244 m_session_data->m_debugger = debugger;
245
246 DWORD process_id = static_cast<DWORD>(pid);
247 Status error = debugger->DebugAttach(process_id, attach_info);
248 if (error.Fail()) {
249 LLDB_LOG(
250 log,
251 "encountered an error occurred initiating the asynchronous attach. {0}",
252 error);
253 return error;
254 }
255
256 HostProcess process;
257 error = WaitForDebuggerConnection(debugger, process);
258 if (error.Fail()) {
259 LLDB_LOG(log,
260 "encountered an error waiting for the debugger to connect. {0}",
261 error);
262 return error;
263 }
264
265 LLDB_LOG(log, "successfully attached to process with pid={0}", process_id);
266
267 // We've hit the initial stop. If eLaunchFlagsStopAtEntry was specified, the
268 // private state should already be set to eStateStopped as a result of
269 // hitting the initial breakpoint. If it was not set, the breakpoint should
270 // have already been resumed from and the private state should already be
271 // eStateRunning.
272
273 return error;
274}
275
278 DebuggerThreadSP debugger_thread;
279 {
280 // Acquire this lock inside an inner scope, only long enough to get the
281 // DebuggerThread. StopDebugging() will trigger a call back into
282 // ProcessDebugger which will acquire the lock again, so we need to not
283 // deadlock.
284 llvm::sys::ScopedLock lock(m_mutex);
285
286 if (!m_session_data) {
287 LLDB_LOG(log, "warning: state = {0}, but there is no active session.",
288 state);
289 return Status();
290 }
291
292 debugger_thread = m_session_data->m_debugger;
293 }
294
295 if (state == eStateExited || state == eStateDetached) {
296 LLDB_LOG(log, "warning: cannot destroy process {0} while state = {1}.",
297 GetDebuggedProcessId(), state);
298 return Status();
299 }
300
301 LLDB_LOG(log, "Shutting down process {0}.",
302 debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle());
303 auto error = debugger_thread->StopDebugging(true);
304
305 // By the time StopDebugging returns, there is no more debugger thread, so
306 // we can be assured that no other thread will race for the session data.
307 m_session_data.reset();
308
309 return error;
310}
311
315 llvm::sys::ScopedLock lock(m_mutex);
316 if (!m_session_data) {
317 caused_stop = false;
318 LLDB_LOG(log, "HaltProcess called with no active session.");
320 "HaltProcess called with no active debugger session.");
321 }
322 caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess()
323 .GetNativeProcess()
324 .GetSystemHandle());
325 if (!caused_stop) {
326 error = Status(::GetLastError(), eErrorTypeWin32);
327 LLDB_LOG(log, "DebugBreakProcess failed with error {0}", error);
328 }
329
330 return error;
331}
332
333Status ProcessDebugger::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
334 size_t &bytes_read) {
336 bytes_read = 0;
338 llvm::sys::ScopedLock lock(m_mutex);
339
340 if (!m_session_data) {
342 "cannot read, there is no active debugger connection.");
343 LLDB_LOG(log, "error: {0}", error);
344 return error;
345 }
346
347 LLDB_LOG(log, "attempting to read {0} bytes from address {1:x}", size,
348 vm_addr);
349
350 lldb::process_t handle = m_session_data->m_debugger->GetProcess()
351 .GetNativeProcess()
352 .GetSystemHandle();
353 void *addr = reinterpret_cast<void *>(vm_addr);
354 SIZE_T num_of_bytes_read = 0;
355 if (::ReadProcessMemory(handle, addr, buf, size, &num_of_bytes_read)) {
356 bytes_read = num_of_bytes_read;
357 return Status();
358 }
359 error = Status(GetLastError(), eErrorTypeWin32);
360 MemoryRegionInfo info;
361 if (GetMemoryRegionInfo(vm_addr, info).Fail() ||
362 info.GetMapped() != eLazyBoolYes)
363 return error;
364 size = info.GetRange().GetRangeEnd() - vm_addr;
365 LLDB_LOG(log, "retrying the read with size {0:x}", size);
366 if (::ReadProcessMemory(handle, addr, buf, size, &num_of_bytes_read)) {
367 LLDB_LOG(log, "success: read {0:x} bytes", num_of_bytes_read);
368 bytes_read = num_of_bytes_read;
369 return Status();
370 }
371 error = Status(GetLastError(), eErrorTypeWin32);
372 LLDB_LOG(log, "error: {0}", error);
373 return error;
374}
375
377 size_t size, size_t &bytes_written) {
379 bytes_written = 0;
381 llvm::sys::ScopedLock lock(m_mutex);
382 LLDB_LOG(log, "attempting to write {0} bytes into address {1:x}", size,
383 vm_addr);
384
385 if (!m_session_data) {
387 "cannot write, there is no active debugger connection.");
388 LLDB_LOG(log, "error: {0}", error);
389 return error;
390 }
391
392 HostProcess process = m_session_data->m_debugger->GetProcess();
393 void *addr = reinterpret_cast<void *>(vm_addr);
394 SIZE_T num_of_bytes_written = 0;
396 if (::WriteProcessMemory(handle, addr, buf, size, &num_of_bytes_written)) {
397 FlushInstructionCache(handle, addr, num_of_bytes_written);
398 bytes_written = num_of_bytes_written;
399 } else {
400 error = Status(GetLastError(), eErrorTypeWin32);
401 LLDB_LOG(log, "writing failed with error: {0}", error);
402 }
403 return error;
404}
405
406Status ProcessDebugger::AllocateMemory(size_t size, uint32_t permissions,
407 lldb::addr_t &addr) {
411 llvm::sys::ScopedLock lock(m_mutex);
412 LLDB_LOG(log, "attempting to allocate {0} bytes with permissions {1}", size,
413 permissions);
414
415 if (!m_session_data) {
417 "cannot allocate, there is no active debugger connection");
418 LLDB_LOG(log, "error: {0}", error);
419 return error;
420 }
421
422 HostProcess process = m_session_data->m_debugger->GetProcess();
424 auto protect = ConvertLldbToWinApiProtect(permissions);
425 auto result = ::VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, protect);
426 if (!result) {
427 error = Status(GetLastError(), eErrorTypeWin32);
428 LLDB_LOG(log, "allocating failed with error: {0}", error);
429 } else {
430 addr = reinterpret_cast<addr_t>(result);
431 }
432 return error;
433}
434
436 Status result;
437
439 llvm::sys::ScopedLock lock(m_mutex);
440 LLDB_LOG(log, "attempting to deallocate bytes at address {0}", vm_addr);
441
442 if (!m_session_data) {
444 "cannot deallocate, there is no active debugger connection");
445 LLDB_LOG(log, "error: {0}", result);
446 return result;
447 }
448
449 HostProcess process = m_session_data->m_debugger->GetProcess();
451 if (!::VirtualFreeEx(handle, reinterpret_cast<LPVOID>(vm_addr), 0,
452 MEM_RELEASE)) {
453 result = Status(GetLastError(), eErrorTypeWin32);
454 LLDB_LOG(log, "deallocating failed with error: {0}", result);
455 }
456
457 return result;
458}
459
461 MemoryRegionInfo &info) {
464 llvm::sys::ScopedLock lock(m_mutex);
465 info.Clear();
466
467 if (!m_session_data) {
469 "GetMemoryRegionInfo called with no debugging session.");
470 LLDB_LOG(log, "error: {0}", error);
471 return error;
472 }
473 HostProcess process = m_session_data->m_debugger->GetProcess();
475 if (handle == nullptr || handle == LLDB_INVALID_PROCESS) {
477 "GetMemoryRegionInfo called with an invalid target process.");
478 LLDB_LOG(log, "error: {0}", error);
479 return error;
480 }
481
482 LLDB_LOG(log, "getting info for address {0:x}", vm_addr);
483
484 void *addr = reinterpret_cast<void *>(vm_addr);
485 MEMORY_BASIC_INFORMATION mem_info = {};
486 SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
487 if (result == 0) {
488 DWORD last_error = ::GetLastError();
489 if (last_error == ERROR_INVALID_PARAMETER) {
490 // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with
491 // an address past the highest accessible address. We should return a
492 // range from the vm_addr to LLDB_INVALID_ADDRESS
493 info.GetRange().SetRangeBase(vm_addr);
499 return error;
500 } else {
501 error = Status(last_error, eErrorTypeWin32);
502 LLDB_LOG(log,
503 "VirtualQueryEx returned error {0} while getting memory "
504 "region info for address {1:x}",
505 error, vm_addr);
506 return error;
507 }
508 }
509
510 // Protect bits are only valid for MEM_COMMIT regions.
511 if (mem_info.State == MEM_COMMIT) {
512 const bool readable = IsPageReadable(mem_info.Protect);
513 const bool executable = IsPageExecutable(mem_info.Protect);
514 const bool writable = IsPageWritable(mem_info.Protect);
515 info.SetReadable(readable ? eLazyBoolYes : eLazyBoolNo);
516 info.SetExecutable(executable ? eLazyBoolYes : eLazyBoolNo);
517 info.SetWritable(writable ? eLazyBoolYes : eLazyBoolNo);
518 } else {
522 }
523
524 // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
525 if (mem_info.State != MEM_FREE) {
526 info.GetRange().SetRangeBase(
527 reinterpret_cast<addr_t>(mem_info.BaseAddress));
528 info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) +
529 mem_info.RegionSize);
531 } else {
532 // In the unmapped case we need to return the distance to the next block of
533 // memory. VirtualQueryEx nearly does that except that it gives the
534 // distance from the start of the page containing vm_addr.
535 SYSTEM_INFO data;
536 ::GetSystemInfo(&data);
537 DWORD page_offset = vm_addr % data.dwPageSize;
538 info.GetRange().SetRangeBase(vm_addr);
539 info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
541 }
542
544 "Memory region info for address {0}: readable={1}, "
545 "executable={2}, writable={3}",
546 vm_addr, info.GetReadable(), info.GetExecutable(),
547 info.GetWritable());
548 return error;
549}
550
551void ProcessDebugger::OnExitProcess(uint32_t exit_code) {
552 // If the process exits before any initial stop then notify the debugger
553 // of the error otherwise WaitForDebuggerConnection() will be blocked.
554 // An example of this issue is when a process fails to load a dependent DLL.
555 if (m_session_data && !m_session_data->m_initial_stop_received) {
557 "Process prematurely exited with {0:x}", exit_code);
559 }
560}
561
563
566 const ExceptionRecord &record) {
568 llvm::sys::ScopedLock lock(m_mutex);
569 // FIXME: Without this check, occasionally when running the test suite
570 // there is an issue where m_session_data can be null. It's not clear how
571 // this could happen but it only surfaces while running the test suite. In
572 // order to properly diagnose this, we probably need to first figure allow the
573 // test suite to print out full lldb logs, and then add logging to the process
574 // plugin.
575 if (!m_session_data) {
576 LLDB_LOG(log,
577 "Debugger thread reported exception {0:x} at address {1:x}, but "
578 "there is no session.",
579 record.GetExceptionValue(), record.GetExceptionAddress());
581 }
582
584 if ((record.GetExceptionValue() == EXCEPTION_BREAKPOINT ||
585 record.GetExceptionValue() ==
586 0x4000001FL /*WOW64 STATUS_WX86_BREAKPOINT*/) &&
587 !m_session_data->m_initial_stop_received) {
588 // Handle breakpoints at the first chance.
590 LLDB_LOG(
591 log,
592 "Hit loader breakpoint at address {0:x}, setting initial stop event.",
593 record.GetExceptionAddress());
594 m_session_data->m_initial_stop_received = true;
595 ::SetEvent(m_session_data->m_initial_stop_event);
596 }
597 return result;
598}
599
601 // Do nothing by default
602}
603
604void ProcessDebugger::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) {
605 // Do nothing by default
606}
607
609 lldb::addr_t module_addr,
610 lldb::tid_t thread_id) {
612}
613
618
620 bool is_unicode,
621 uint16_t length_lower_word) {
622 // Do nothing by default
623}
624
625llvm::Error
627 bool is_unicode, uint16_t length_lower_word,
629 if (is_unicode && length_lower_word % 2 != 0)
630 return llvm::createStringError(
631 "Utf16 string can't have uneven size in bytes");
632
633 const auto is_zero_terminated = [&] {
634 // The zero terminator is always at the end of the buffer.
635 if (is_unicode)
636 return output.size() >= 2 && output.back() == 0 &&
637 output[output.size() - 2] == 0;
638
639 return !output.empty() && output.back() == 0;
640 };
641
642 // Read at most 1 MiB ((1 << 16) * 16 - 1 Bytes) since we don't know the exact
643 // size of the string. We know that `strlen(string) & 0xffff ==
644 // length_lower_word`, so we read in chunks until we reach the terminator:
645 // - 0: `length_lower_word` Bytes
646 // - 1..16: 64 KiB (= 2^16 Bytes)
647 size_t start = length_lower_word == 0 ? 1 : 0;
648 for (size_t i = start; i < 16; ++i) {
649 output.resize_for_overwrite(length_lower_word + i * (1 << 16));
650 size_t chunk_size = i == 0 ? length_lower_word : (1 << 16);
651 lldb::addr_t addr = debug_string_addr + output.size_in_bytes() - chunk_size;
652
653 size_t bytes_read = 0;
654 Status error =
655 ReadMemory(addr, output.end() - chunk_size, chunk_size, bytes_read);
656 if (error.Fail())
657 return error.takeError();
658
659 if (bytes_read != chunk_size) {
660 return llvm::createStringErrorV(
661 "Expected to read {0} bytes, but read {1}", chunk_size, bytes_read);
662 }
663
664 if (is_zero_terminated())
665 break;
666 }
667
668 if (!is_zero_terminated())
669 return llvm::createStringError("String is 1 MiB or larger");
670
671 // Remove null terminator.
672 output.pop_back_n(is_unicode ? 2 : 1);
673 return llvm::Error::success();
674}
675
676void ProcessDebugger::OnDebuggerError(const Status &error, uint32_t type) {
677 llvm::sys::ScopedLock lock(m_mutex);
679
680 if (!m_session_data) {
681 LLDB_LOG(log,
682 "OnDebuggerError called with no active session: error {0}: {1}",
683 error.GetError(), error);
684 return;
685 }
686
687 if (m_session_data->m_initial_stop_received) {
688 // This happened while debugging. Do we shutdown the debugging session,
689 // try to continue, or do something else?
690 LLDB_LOG(log,
691 "Error {0} occurred during debugging. Unexpected behavior "
692 "may result. {1}",
693 error.GetError(), error);
694 } else {
695 // If we haven't actually launched the process yet, this was an error
696 // launching the process. Set the internal error and signal the initial
697 // stop event so that the DoLaunch method wakes up and returns a failure.
698 m_session_data->m_launch_error = error.Clone();
699 ::SetEvent(m_session_data->m_initial_stop_event);
700 LLDB_LOG(log,
701 "Error {0} occurred launching the process before the initial "
702 "stop. {1}",
703 error.GetError(), error);
704 return;
705 }
706}
707
709 HostProcess &process) {
710 Status result;
712 LLDB_LOG(log, "Waiting for loader breakpoint.");
713
714 // Block this function until we receive the initial stop from the process.
715 if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) ==
716 WAIT_OBJECT_0) {
717 LLDB_LOG(log, "hit loader breakpoint, returning.");
718
719 process = debugger->GetProcess();
720 return m_session_data->m_launch_error.Clone();
721 } else
722 return Status(::GetLastError(), eErrorTypeWin32);
723}
724
725} // namespace lldb_private
static llvm::raw_ostream & error(Stream &strm)
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 MAX_PATH
static bool IsPageExecutable(uint32_t protect)
static bool IsPageWritable(uint32_t protect)
static bool IsPageReadable(uint32_t protect)
static DWORD ConvertLldbToWinApiProtect(uint32_t protect)
static void NormalizeWindowsPathSeparators(std::string &s)
unsigned long GetExceptionValue() const
lldb::addr_t GetExceptionAddress() const
A file utility class.
Definition FileSpec.h:57
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:376
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
bool Test(ValueType bit) const
Test a single flag bit.
Definition Flags.h:96
HostNativeProcessBase & GetNativeProcess()
lldb::pid_t GetProcessId() const
bool GetContinueOnceAttached() const
Definition Process.h:154
Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written)
Status DestroyProcess(lldb::StateType process_state)
Status LaunchProcess(ProcessLaunchInfo &launch_info, DebugDelegateSP delegate)
Status WaitForDebuggerConnection(DebuggerThreadSP debugger, HostProcess &process)
virtual DllEventAction OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr, lldb::tid_t thread_id)
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
virtual void OnCreateThread(const HostThread &thread)
virtual void OnDebuggerError(const Status &error, uint32_t type)
virtual void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code)
virtual void OnDebuggerConnected(lldb::addr_t image_base)
std::unique_ptr< ProcessWindowsData > m_session_data
Status AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr)
virtual ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record)
Status AttachProcess(lldb::pid_t pid, const ProcessAttachInfo &attach_info, DebugDelegateSP delegate)
lldb::pid_t GetDebuggedProcessId() const
virtual void OnDebugString(lldb::addr_t debug_string_addr, bool is_unicode, uint16_t length_lower_word)
Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read)
bool IsSystemModuleAddress(lldb::addr_t addr)
virtual void OnExitProcess(uint32_t exit_code)
virtual DllEventAction OnUnloadDll(lldb::addr_t module_addr, lldb::tid_t thread_id)
static bool IsSystemDLL(llvm::StringRef path)
llvm::Error ReadDebugString(lldb::addr_t debug_string_addr, bool is_unicode, uint16_t length_lower_word, llvm::SmallVectorImpl< char > &output)
Read an OUTPUT_DEBUG_STRING_INFO payload from the inferior.
Status HaltProcess(bool &caused_stop)
Status DeallocateMemory(lldb::addr_t addr)
void SetProcessID(lldb::pid_t pid)
Definition ProcessInfo.h:68
FileSpec & GetExecutableFile()
Definition ProcessInfo.h:41
const FileSpec & GetWorkingDirectory() const
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:293
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_PROCESS_ID
#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::shared_ptr< DebuggerThread > DebuggerThreadSP
Definition ForwardDecl.h:46
std::shared_ptr< IDebugDelegate > DebugDelegateSP
Definition ForwardDecl.h:45
StateType
Process and Thread States.
@ eStateDetached
Process has been detached and can't be examined.
@ eStateExited
Process has exited and can't be examined.
@ eErrorTypeWin32
Standard Win32 error codes.
uint64_t pid_t
Definition lldb-types.h:83
uint64_t addr_t
Definition lldb-types.h:80
uint64_t tid_t
Definition lldb-types.h:84
uint64_t process_t
Definition lldb-types.h:57
void SetRangeEnd(BaseType end)
Definition RangeMap.h:80
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
Definition RangeMap.h:48
BaseType GetRangeEnd() const
Definition RangeMap.h:78
void SetByteSize(SizeType s)
Definition RangeMap.h:89