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);
251 caused_stop = ::DebugBreakProcess(
m_session_data->m_debugger->GetProcess()
256 LLDB_LOG(log,
"DebugBreakProcess failed with error {0}",
error);
263 size_t &bytes_read) {
267 llvm::sys::ScopedLock lock(
m_mutex);
271 "cannot read, there is no active debugger connection.");
276 LLDB_LOG(log,
"attempting to read {0} bytes from address {1:x}", size,
282 void *addr =
reinterpret_cast<void *
>(vm_addr);
283 SIZE_T num_of_bytes_read = 0;
285 bytes_read = num_of_bytes_read;
294 LLDB_LOG(log,
"retrying the read with size {0:x}", size);
296 LLDB_LOG(log,
"success: read {0:x} bytes", num_of_bytes_read);
297 bytes_read = num_of_bytes_read;
306 size_t size,
size_t &bytes_written) {
310 llvm::sys::ScopedLock lock(
m_mutex);
311 LLDB_LOG(log,
"attempting to write {0} bytes into address {1:x}", size,
316 "cannot write, there is no active debugger connection.");
322 void *addr =
reinterpret_cast<void *
>(vm_addr);
323 SIZE_T num_of_bytes_written = 0;
325 if (::WriteProcessMemory(handle, addr, buf, size, &num_of_bytes_written)) {
326 FlushInstructionCache(handle, addr, num_of_bytes_written);
327 bytes_written = num_of_bytes_written;
340 llvm::sys::ScopedLock lock(
m_mutex);
341 LLDB_LOG(log,
"attempting to allocate {0} bytes with permissions {1}", size,
346 "cannot allocate, there is no active debugger connection");
354 auto result = ::VirtualAllocEx(handle,
nullptr, size, MEM_COMMIT, protect);
359 addr =
reinterpret_cast<addr_t>(result);
368 llvm::sys::ScopedLock lock(
m_mutex);
369 LLDB_LOG(log,
"attempting to deallocate bytes at address {0}", vm_addr);
373 "cannot deallocate, there is no active debugger connection");
374 LLDB_LOG(log,
"error: {0}", result);
380 if (!::VirtualFreeEx(handle,
reinterpret_cast<LPVOID
>(vm_addr), 0,
383 LLDB_LOG(log,
"deallocating failed with error: {0}", result);
393 llvm::sys::ScopedLock lock(
m_mutex);
398 "GetMemoryRegionInfo called with no debugging session.");
406 "GetMemoryRegionInfo called with an invalid target process.");
411 LLDB_LOG(log,
"getting info for address {0:x}", vm_addr);
413 void *addr =
reinterpret_cast<void *
>(vm_addr);
414 MEMORY_BASIC_INFORMATION mem_info = {};
415 SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info,
sizeof(mem_info));
417 DWORD last_error = ::GetLastError();
418 if (last_error == ERROR_INVALID_PARAMETER) {
432 "VirtualQueryEx returned error {0} while getting memory "
433 "region info for address {1:x}",
440 if (mem_info.State == MEM_COMMIT) {
455 if (mem_info.State != MEM_FREE) {
457 reinterpret_cast<addr_t>(mem_info.BaseAddress));
459 mem_info.RegionSize);
466 ::GetSystemInfo(&data);
467 DWORD page_offset = vm_addr % data.dwPageSize;
474 "Memory region info for address {0}: readable={1}, "
475 "executable={2}, writable={3}",
497 llvm::sys::ScopedLock lock(
m_mutex);
506 "Debugger thread reported exception {0:x} at address {1:x}, but "
507 "there is no session.",
509 return ExceptionResult::SendToApplication;
518 result = ExceptionResult::BreakInDebugger;
521 "Hit loader breakpoint at address {0:x}, setting initial stop event.",
549 llvm::sys::ScopedLock lock(
m_mutex);
556 "Error {0} occurred during debugging. Unexpected behavior "
566 "Error {0} occurred launching the process before the initial "
577 LLDB_LOG(log,
"Waiting for loader breakpoint.");
580 if (::WaitForSingleObject(
m_session_data->m_initial_stop_event, INFINITE) ==
582 LLDB_LOG(log,
"hit loader breakpoint, returning.");
584 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_LOGV(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.
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
static FileSystem & Instance()
bool Test(ValueType bit) const
Test a single flag bit.
lldb::process_t GetSystemHandle() const
HostNativeProcessBase & GetNativeProcess()
lldb::pid_t GetProcessId() const
OptionalBool GetWritable() const
void SetMapped(OptionalBool val)
OptionalBool GetMapped() const
void SetReadable(OptionalBool val)
void SetExecutable(OptionalBool val)
void SetWritable(OptionalBool val)
OptionalBool GetReadable() const
OptionalBool GetExecutable() const
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 void OnDebugString(const std::string &string)
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
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.
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< IDebugDelegate > DebugDelegateSP
std::shared_ptr< DebuggerThread > DebuggerThreadSP
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)