22#include "llvm/Support/ConvertUTF.h"
23#include "llvm/Support/Error.h"
40 if (protect & ePermissionsExecutable)
41 return PAGE_EXECUTE_READWRITE;
43 return PAGE_READWRITE;
51 return (protect & PAGE_NOACCESS) == 0;
55 return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY |
56 PAGE_READWRITE | PAGE_WRITECOPY)) != 0;
60 return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE |
61 PAGE_EXECUTE_WRITECOPY)) != 0;
82 llvm::sys::ScopedLock lock(
m_mutex);
85 LLDB_LOG(log,
"there is no active session.");
94 LLDB_LOG(log,
"detaching from process {0}.",
95 debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle());
96 error = debugger_thread->StopDebugging(
false);
115 namespace fs = llvm::sys::fs;
120 "No such file or directory: %s", working_dir.
GetPath().c_str());
127 stream.
Printf(
"ProcessDebugger unable to launch '%s'. ProcessDebugger can "
128 "only be used for debug launches.",
130 std::string message = stream.
GetString().str();
133 LLDB_LOG(log,
"error: {0}", message);
137 bool stop_at_entry = launch_info.
GetFlags().
Test(eLaunchFlagStopAtEntry);
143 result = debugger->DebugLaunch(launch_info);
145 LLDB_LOG(log,
"failed launching '{0}'. {1}",
153 LLDB_LOG(log,
"failed launching '{0}'. {1}",
158 LLDB_LOG(log,
"successfully launched '{0}'",
181 DWORD process_id =
static_cast<DWORD
>(pid);
182 Status error = debugger->DebugAttach(process_id, attach_info);
186 "encountered an error occurred initiating the asynchronous attach. {0}",
195 "encountered an error waiting for the debugger to connect. {0}",
200 LLDB_LOG(log,
"successfully attached to process with pid={0}", process_id);
219 llvm::sys::ScopedLock lock(
m_mutex);
222 LLDB_LOG(log,
"warning: state = {0}, but there is no active session.",
231 LLDB_LOG(log,
"warning: cannot destroy process {0} while state = {1}.",
236 LLDB_LOG(log,
"Shutting down process {0}.",
237 debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle());
238 auto error = debugger_thread->StopDebugging(
true);
250 llvm::sys::ScopedLock lock(
m_mutex);
253 LLDB_LOG(log,
"HaltProcess called with no active session.");
255 "HaltProcess called with no active debugger session.");
257 caused_stop = ::DebugBreakProcess(
m_session_data->m_debugger->GetProcess()
262 LLDB_LOG(log,
"DebugBreakProcess failed with error {0}",
error);
269 size_t &bytes_read) {
273 llvm::sys::ScopedLock lock(
m_mutex);
277 "cannot read, there is no active debugger connection.");
282 LLDB_LOG(log,
"attempting to read {0} bytes from address {1:x}", size,
288 void *addr =
reinterpret_cast<void *
>(vm_addr);
289 SIZE_T num_of_bytes_read = 0;
291 bytes_read = num_of_bytes_read;
300 LLDB_LOG(log,
"retrying the read with size {0:x}", size);
302 LLDB_LOG(log,
"success: read {0:x} bytes", num_of_bytes_read);
303 bytes_read = num_of_bytes_read;
312 size_t size,
size_t &bytes_written) {
316 llvm::sys::ScopedLock lock(
m_mutex);
317 LLDB_LOG(log,
"attempting to write {0} bytes into address {1:x}", size,
322 "cannot write, there is no active debugger connection.");
328 void *addr =
reinterpret_cast<void *
>(vm_addr);
329 SIZE_T num_of_bytes_written = 0;
331 if (::WriteProcessMemory(handle, addr, buf, size, &num_of_bytes_written)) {
332 FlushInstructionCache(handle, addr, num_of_bytes_written);
333 bytes_written = num_of_bytes_written;
346 llvm::sys::ScopedLock lock(
m_mutex);
347 LLDB_LOG(log,
"attempting to allocate {0} bytes with permissions {1}", size,
352 "cannot allocate, there is no active debugger connection");
360 auto result = ::VirtualAllocEx(handle,
nullptr, size, MEM_COMMIT, protect);
365 addr =
reinterpret_cast<addr_t>(result);
374 llvm::sys::ScopedLock lock(
m_mutex);
375 LLDB_LOG(log,
"attempting to deallocate bytes at address {0}", vm_addr);
379 "cannot deallocate, there is no active debugger connection");
380 LLDB_LOG(log,
"error: {0}", result);
386 if (!::VirtualFreeEx(handle,
reinterpret_cast<LPVOID
>(vm_addr), 0,
389 LLDB_LOG(log,
"deallocating failed with error: {0}", result);
399 llvm::sys::ScopedLock lock(
m_mutex);
404 "GetMemoryRegionInfo called with no debugging session.");
412 "GetMemoryRegionInfo called with an invalid target process.");
417 LLDB_LOG(log,
"getting info for address {0:x}", vm_addr);
419 void *addr =
reinterpret_cast<void *
>(vm_addr);
420 MEMORY_BASIC_INFORMATION mem_info = {};
421 SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info,
sizeof(mem_info));
423 DWORD last_error = ::GetLastError();
424 if (last_error == ERROR_INVALID_PARAMETER) {
438 "VirtualQueryEx returned error {0} while getting memory "
439 "region info for address {1:x}",
446 if (mem_info.State == MEM_COMMIT) {
460 if (mem_info.State != MEM_FREE) {
462 reinterpret_cast<addr_t>(mem_info.BaseAddress));
464 mem_info.RegionSize);
471 ::GetSystemInfo(&data);
472 DWORD page_offset = vm_addr % data.dwPageSize;
479 "Memory region info for address {0}: readable={1}, "
480 "executable={2}, writable={3}",
492 "Process prematurely exited with {0:x}", exit_code);
503 llvm::sys::ScopedLock lock(
m_mutex);
512 "Debugger thread reported exception {0:x} at address {1:x}, but "
513 "there is no session.",
527 "Hit loader breakpoint at address {0:x}, setting initial stop event.",
554 uint16_t length_lower_word) {
559 llvm::sys::ScopedLock lock(
m_mutex);
564 "OnDebuggerError called with no active session: error {0}: {1}",
573 "Error {0} occurred during debugging. Unexpected behavior "
583 "Error {0} occurred launching the process before the initial "
594 LLDB_LOG(log,
"Waiting for loader breakpoint.");
597 if (::WaitForSingleObject(
m_session_data->m_initial_stop_event, INFINITE) ==
599 LLDB_LOG(log,
"hit loader breakpoint, returning.");
601 process = debugger->GetProcess();
static llvm::raw_ostream & error(Stream &strm)
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.
#define LLDB_LOG_VERBOSE(log,...)
static bool IsPageExecutable(uint32_t protect)
static bool IsPageWritable(uint32_t protect)
static bool IsPageReadable(uint32_t protect)
static DWORD ConvertLldbToWinApiProtect(uint32_t protect)
DWORD GetExceptionCode() const
lldb::addr_t GetExceptionAddress() const
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
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.
lldb::process_t GetSystemHandle() const
HostNativeProcessBase & GetNativeProcess()
lldb::pid_t GetProcessId() const
LazyBool GetMapped() const
void SetReadable(LazyBool val)
LazyBool GetReadable() const
LazyBool GetExecutable() const
LazyBool GetWritable() const
void SetMapped(LazyBool val)
void SetExecutable(LazyBool val)
void SetWritable(LazyBool val)
bool GetContinueOnceAttached() const
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)
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)
virtual void OnUnloadDll(lldb::addr_t module_addr)
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)
virtual void OnExitProcess(uint32_t exit_code)
virtual void OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr)
Status HaltProcess(bool &caused_stop)
virtual ~ProcessDebugger()
Status DeallocateMemory(lldb::addr_t addr)
void SetProcessID(lldb::pid_t pid)
FileSpec & GetExecutableFile()
const FileSpec & GetWorkingDirectory() const
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_PROCESS_ID
#define LLDB_INVALID_PROCESS
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.
std::shared_ptr< DebuggerThread > DebuggerThreadSP
std::shared_ptr< IDebugDelegate > DebugDelegateSP
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.
void SetRangeEnd(BaseType end)
void SetRangeBase(BaseType b)
Set the start value for the range, and keep the same size.
BaseType GetRangeEnd() const
void SetByteSize(SizeType s)