38#include "llvm/Support/ConvertUTF.h"
39#include "llvm/Support/Format.h"
40#include "llvm/Support/Threading.h"
41#include "llvm/Support/raw_ostream.h"
56std::string GetProcessExecutableName(
HANDLE process_handle) {
57 std::vector<wchar_t> file_name;
58 DWORD file_name_size = MAX_PATH;
62 file_name.resize(file_name_size);
63 copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(),
65 }
while (copied >= file_name_size);
66 file_name.resize(copied);
68 llvm::convertWideToUTF8(file_name.data(), result);
72std::string GetProcessExecutableName(DWORD pid) {
73 std::string file_name;
75 ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
76 if (process_handle != NULL) {
77 file_name = GetProcessExecutableName(process_handle);
78 ::CloseHandle(process_handle);
96 llvm::StringRef use_lldb_server = ::getenv(
"LLDB_USE_LLDB_SERVER");
97 return use_lldb_server.equals_insensitive(
"on") ||
98 use_lldb_server.equals_insensitive(
"yes") ||
99 use_lldb_server.equals_insensitive(
"1") ||
100 use_lldb_server.equals_insensitive(
"true");
116 return "Process plugin for Windows";
135 LLDB_LOG(log,
"bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
139 if (!
error.Success())
146 LLDB_LOG(log,
"bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
151 if (!
error.Success())
166 LLDB_LOG(log,
"process {0} is in state {1}. Resuming for detach...",
170 LLDB_LOG(log,
"resuming {0} threads for detach.",
175 auto thread = std::static_pointer_cast<TargetThreadWindows>(
177 Status result = thread->DoResume();
181 "Trying to resume thread at index {0}, but failed with "
200 "error: process {0} in state = {1}, but "
201 "cannot detach it in this state.",
202 GetID(), private_state);
231 llvm::sys::ScopedLock lock(
m_mutex);
235 "{0} does not support reverse execution of processes",
GetPluginName());
242 LLDB_LOG(log,
"process {0} is in state {1}. Resuming...",
250 auto thread = std::static_pointer_cast<TargetThreadWindows>(
252 Status result = thread->DoResume();
257 "Trying to resume thread at index {0}, but failed with error {1}.",
270 if (active_exception) {
278 LLDB_LOG(log,
"error: process {0} is in state {1}. Returning...",
304 llvm::sys::ScopedLock lock(
m_mutex);
320 const int addr_min_width = 2 + 8;
322 const std::vector<ULONG_PTR> &args = exception->GetExceptionArguments();
323 switch (exception->GetExceptionCode()) {
324 case EXCEPTION_ACCESS_VIOLATION: {
329 const int access_violation_code = args[0];
331 switch (access_violation_code) {
333 stream <<
"Access violation reading";
336 stream <<
"Access violation writing";
339 stream <<
"User-mode data execution prevention (DEP) violation at";
342 stream <<
"Unknown access violation (code " << access_violation_code
346 stream <<
" location "
347 << llvm::format_hex(access_violation_address, addr_min_width);
350 case EXCEPTION_IN_PAGE_ERROR: {
355 const int page_load_error_code = args[0];
357 const DWORD underlying_code = args[2];
358 switch (page_load_error_code) {
360 stream <<
"In page error reading";
363 stream <<
"In page error writing";
366 stream <<
"User-mode data execution prevention (DEP) violation at";
369 stream <<
"Unknown page loading error (code " << page_load_error_code
373 stream <<
" location "
374 << llvm::format_hex(page_load_error_address, addr_min_width)
375 <<
" (status code " << llvm::format_hex(underlying_code, 8) <<
")";
383 llvm::sys::ScopedLock lock(
m_mutex);
386 LLDB_LOG(log,
"no active session. Returning...");
392 std::weak_ptr<ExceptionRecord> exception_record =
395 if (!active_exception) {
397 "there is no active exception in process {0}. Why is the "
404 m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
410 uint64_t
pc = register_context->GetPC();
415 if (site && site->IsEnabled())
416 stop_thread->SetThreadStoppedAtUnexecutedBP(
pc);
418 switch (active_exception->GetExceptionCode()) {
419 case EXCEPTION_SINGLE_STEP: {
421 stop_thread->GetRegisterContext().get());
426 "Single-stepped onto a watchpoint in process {0} at address "
427 "{1:x} with watchpoint {2}",
431 stop_thread->SetStopInfo(stop_info);
436 LLDB_LOG(log,
"single stepping thread {0}", stop_thread->GetID());
438 stop_thread->SetStopInfo(stop_info);
443 case EXCEPTION_BREAKPOINT: {
444 int breakpoint_size = 1;
445 switch (
GetTarget().GetArchitecture().GetMachine()) {
446 case llvm::Triple::aarch64:
450 case llvm::Triple::arm:
451 case llvm::Triple::thumb:
455 case llvm::Triple::x86:
456 case llvm::Triple::x86_64:
461 LLDB_LOG(log,
"Unknown breakpoint size for architecture");
466 pc = register_context->GetPC() - breakpoint_size;
471 "detected breakpoint in process {0} at address {1:x} with "
472 "breakpoint site {2}",
476 stop_thread->SetThreadHitBreakpointSite();
477 if (site->ValidForThisThread(*stop_thread)) {
479 "Breakpoint site {0} is valid for this thread ({1:x}), "
480 "creating stop info.",
481 site->GetID(), stop_thread->GetID());
484 *stop_thread, site->GetID());
485 register_context->SetPC(
pc);
488 "Breakpoint site {0} is not valid for this thread, "
489 "creating empty stop info.",
492 stop_thread->SetStopInfo(stop_info);
498 "No breakpoint site matches for this thread. __debugbreak()? "
499 "Creating stop info with the exception.");
508 llvm::raw_string_ostream desc_stream(desc);
509 desc_stream <<
"Exception "
510 << llvm::format_hex(active_exception->GetExceptionCode(), 8)
511 <<
" encountered at address "
512 << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
517 stop_thread->SetStopInfo(stop_info);
525 bool plugin_specified_by_name) {
526 if (plugin_specified_by_name)
530 ModuleSP exe_module_sp(target_sp->GetExecutableModule());
531 if (exe_module_sp.get())
544 int continued_threads = 0;
545 int exited_threads = 0;
550 auto exited_thread_iter =
552 if (exited_thread_iter ==
m_session_data->m_exited_threads.end()) {
556 LLDB_LOGV(log,
"Thread {0} was running and is still running.",
559 LLDB_LOGV(log,
"Thread {0} was running and has exited.", old_thread_id);
567 new_thread_list.
AddThread(thread_info.second);
570 LLDB_LOGV(log,
"Thread {0} is new since last update.", thread_info.first);
573 LLDB_LOG(log,
"{0} new threads, {1} old threads, {2} exited threads.",
574 new_threads, continued_threads, exited_threads);
597 return HostInfo::GetArchitecture();
602 size_t bytes_read = 0;
609 size_t bytes_written = 0;
611 return bytes_written;
650 LLDB_LOG(log,
"Process {0} exited with code {1}",
GetID(), exit_code);
653 m_pty->SetStopping(
true);
660 ModuleSP executable_module = target->GetExecutableModule();
662 unloaded_modules.
Append(executable_module);
663 target->ModulesDidUnload(unloaded_modules,
true);
675 LLDB_LOG(log,
"Debugger connected to process {0}. Image base = {1:x}",
676 debugger->GetProcess().GetProcessId(), image_base);
680 const DWORD pid = debugger->GetProcess().GetProcessId();
681 const std::string file_name = GetProcessExecutableName(pid);
682 if (file_name.empty()) {
686 FileSpec executable_file(file_name);
691 GetTarget().GetOrCreateModule(module_spec, true , &error);
699 dyld->OnLoadModule(module,
ModuleSpec(), image_base);
705 llvm::sys::ScopedLock lock(
m_mutex);
707 const HostThread &host_main_thread = debugger->GetMainThread();
709 std::make_shared<TargetThreadWindows>(*
this, host_main_thread);
712 main_thread->SetID(
id);
721 llvm::sys::ScopedLock lock(
m_mutex);
732 "Debugger thread reported exception {0:x} at address {1:x}, "
733 "but there is no session.",
746 case EXCEPTION_BREAKPOINT:
753 "Hit loader breakpoint at address {0:x}, setting initial stop event.",
758 LLDB_LOG(log,
"Hit non-loader breakpoint at address {0:x}.",
763 case EXCEPTION_SINGLE_STEP:
769 "Debugger thread reported exception {0:x} at address {1:x} "
770 "(first_chance={2})",
785 llvm::sys::ScopedLock lock(
m_mutex);
787 ThreadSP thread = std::make_shared<TargetThreadWindows>(*
this, new_thread);
790 tid_t id = native_new_thread.GetThreadId();
795 for (
const std::map<int, WatchpointInfo>::value_type &p :
m_watchpoints) {
797 thread->GetRegisterContext().get());
799 p.second.size, p.second.read,
805 llvm::sys::ScopedLock lock(
m_mutex);
825 dyld->OnLoadModule(
nullptr, module_spec, module_addr);
830 dyld->OnUnloadModule(module_addr);
836 llvm::sys::ScopedLock lock(
m_mutex);
843 "Error {0} occurred during debugging. Unexpected behavior "
854 "Error {0} occurred launching the process before the initial stop. {1}",
867 if (wp_sp->IsEnabled()) {
868 wp_sp->SetEnabled(
true, notify);
880 "Can't find free slot for watchpoint %i", wp_sp->GetID());
883 info.
address = wp_sp->GetLoadAddress();
884 info.
size = wp_sp->GetByteSize();
885 info.
read = wp_sp->WatchpointRead();
886 info.
write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
891 thread->GetRegisterContext().get());
895 "Can't enable watchpoint %i on thread 0x%llx", wp_sp->GetID(),
904 thread->GetRegisterContext().get());
913 wp_sp->SetEnabled(
true, notify);
921 if (!wp_sp->IsEnabled()) {
922 wp_sp->SetEnabled(
false, notify);
929 "Info about watchpoint %i is not found", wp_sp->GetID());
936 thread->GetRegisterContext().get());
937 if (!reg_ctx->RemoveHardwareBreakpoint(it->second.slot_id)) {
939 "Can't disable watchpoint %i on thread 0x%llx", wp_sp->GetID(),
950 wp_sp->SetEnabled(
false, notify);
964 CreateEvent(NULL, FALSE,
973 std::lock_guard<std::mutex> guard(
m_mutex);
989 DWORD bytesAvailable = 0;
990 if (PeekNamedPipe(hStdin, NULL, 0, NULL, &bytesAvailable, NULL)) {
991 if (bytesAvailable > 0)
996 INPUT_RECORD inputRecord;
998 if (!PeekConsoleInput(hStdin, &inputRecord, 1, &numRead))
999 return llvm::createStringError(
"Failed to peek standard input.");
1004 if (inputRecord.EventType == KEY_EVENT &&
1005 inputRecord.Event.KeyEvent.bKeyDown &&
1006 inputRecord.Event.KeyEvent.uChar.AsciiChar != 0)
1009 if (!ReadConsoleInput(hStdin, &inputRecord, 1, &numRead))
1010 return llvm::createStringError(
"Failed to read standard input.");
1027 bool isConsole = GetConsoleMode(hStdin, &consoleMode) != 0;
1032 DWORD oldConsoleMode = consoleMode;
1033 SetConsoleMode(hStdin,
1034 consoleMode & ~ENABLE_LINE_INPUT & ~ENABLE_ECHO_INPUT);
1038 std::lock_guard<std::mutex> guard(
m_mutex);
1043 DWORD result = WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE);
1047 case WAIT_OBJECT_0: {
1050 if (!hasInputOrErr) {
1053 "failed to process debuggee's IO: {0}");
1058 if (!*hasInputOrErr)
1064 if (!ReadFile(hStdin, &ch, 1, &read,
nullptr) || read != 1)
1068 if (!WriteFile(
m_write_file, &ch, 1, &written,
nullptr) || written != 1)
1072 case WAIT_OBJECT_0 + 1: {
1089 SetConsoleMode(hStdin, oldConsoleMode);
1093 std::lock_guard<std::mutex> guard(
m_mutex);
1135 if (
m_pty ==
nullptr)
1138 std::make_unique<ConnectionConPTY>(
m_pty));
1149 this,
m_pty->GetSTDINHandle());
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_LOGV(log,...)
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
bool IsValid() const
Check if the object state is valid.
An architecture specification class.
Class that manages the actual breakpoint that will be inserted into the running program.
static llvm::StringRef GetPluginNameStatic()
static DynamicLoader * FindPlugin(Process *process, llvm::StringRef plugin_name)
Find a dynamic loader plugin for a given process.
DWORD GetExceptionCode() const
lldb::addr_t GetExceptionAddress() const
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
An abstract base class for files.
HostNativeThread & GetNativeThread()
bool Interrupt() override
NativeFile m_read_file
Read from this file (usually actual STDIN for LLDB)
void SetIsRunning(bool running)
~IOHandlerProcessSTDIOWindows() override
llvm::Expected< bool > ConsoleHasTextInput(const HANDLE hStdin)
Peek the console for input.
std::atomic< ControlOp > m_pending_op
HANDLE m_write_file
Write to this file (usually the primary pty for getting io to debuggee)
IOHandlerProcessSTDIOWindows(Process *process, HANDLE conpty_input)
IOHandler(Debugger &debugger, IOHandler::Type type)
A collection class for Module objects.
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
A class that describes an executable image and its associated object and symbol files.
A plug-in interface definition class for object file parsers.
virtual lldb_private::Address GetImageInfoAddress(Target *target)
Similar to Process::GetImageInfoAddress().
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
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 GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
std::unique_ptr< ProcessWindowsData > m_session_data
Status AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr)
Status AttachProcess(lldb::pid_t pid, const ProcessAttachInfo &attach_info, DebugDelegateSP delegate)
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)
Status HaltProcess(bool &caused_stop)
Status DeallocateMemory(lldb::addr_t addr)
lldb::pid_t GetProcessID() const
std::shared_ptr< PTY > TakePTY()
void OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr) override
void OnDebugString(const std::string &string) override
ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
void OnDebuggerConnected(lldb::addr_t image_base) override
Status DoDeallocateMemory(lldb::addr_t ptr) override
Actually deallocate memory in the process.
Status DoDestroy() override
std::shared_ptr< PTY > m_pty
Status EnableBreakpointSite(BreakpointSite *bp_site) override
void SetPseudoConsoleHandle() override
void DidLaunch() override
Called after launching a process.
std::optional< uint32_t > GetWatchpointSlotCount() override
Get the number of watchpoints supported by this target.
Status DoResume(lldb::RunDirection direction) override
Resumes all of a process's threads as configured using the Thread run control functions.
void OnUnloadDll(lldb::addr_t module_addr) override
DynamicLoaderWindowsDYLD * GetDynamicLoader() override
Get the dynamic loader plug-in for this process.
Status DisableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
bool IsAlive() override
Check if a process is still alive.
Status DoGetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) override
DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has removed non address bits from loa...
void OnCreateThread(const HostThread &thread) override
static llvm::StringRef GetPluginDescriptionStatic()
size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error) override
Actually do the writing of memory to a process.
llvm::StringRef GetPluginName() override
Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override
Launch a new process.
size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error) override
Actually do the reading of memory from a process.
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
static llvm::StringRef GetPluginNameStatic()
void DidAttach(lldb_private::ArchSpec &arch_spec) override
Called after attaching a process.
void OnExitProcess(uint32_t exit_code) override
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *, bool can_connect)
void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override
Status DoAttachToProcessWithID(lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info) override
Attach to an existing process using a process ID.
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) override
std::map< lldb::break_id_t, WatchpointInfo > m_watchpoints
void OnDebuggerError(const Status &error, uint32_t type) override
ArchSpec GetSystemArchitecture() override
Get the system architecture for this process.
Status DoDetach(bool keep_stopped) override
Detaches from a running or stopped process.
std::vector< lldb::break_id_t > m_watchpoint_ids
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, Status &error) override
Actually allocate memory in the process.
Status DisableBreakpointSite(BreakpointSite *bp_site) override
Status DoHalt(bool &caused_stop) override
Halts a running process.
Status EnableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
A plug-in interface definition class for debugging a process.
lldb::IOHandlerSP m_process_input_reader
std::mutex m_process_input_reader_mutex
StopPointSiteList< lldb_private::BreakpointSite > & GetBreakpointSiteList()
virtual Status DisableSoftwareBreakpoint(BreakpointSite *bp_site)
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
Construct with a shared pointer to a target, and the Process listener.
lldb::StateType GetPrivateState() const
lldb::DynamicLoaderUP m_dyld_up
lldb::TargetSP CalculateTarget() override
virtual Status EnableSoftwareBreakpoint(BreakpointSite *bp_site)
void SetID(lldb::pid_t new_pid)
Sets the stored pid.
virtual bool SetExitStatus(int exit_status, llvm::StringRef exit_string)
Set accessor for the process exit status (return code).
static void STDIOReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
void SetPrivateState(lldb::StateType state)
ThreadList m_thread_list
The threads for this process as the user will see them.
ThreadedCommunication m_stdio_communication
Target & GetTarget()
Get the target object pointer for this module.
static constexpr uint32_t GetNumHardwareBreakpointSlots()
uint32_t GetTriggeredHardwareBreakpointSlotId()
bool RemoveHardwareBreakpoint(uint32_t slot)
bool AddHardwareBreakpoint(uint32_t slot, lldb::addr_t address, uint32_t size, bool read, bool write)
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)
static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread)
static lldb::StopInfoSP CreateStopReasonWithWatchpointID(Thread &thread, lldb::break_id_t watch_id, bool silently_continue=false)
static lldb::StopInfoSP CreateStopReasonWithException(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(Thread &thread, lldb::break_id_t break_id)
StopPointSiteSP FindByAddress(lldb::addr_t addr)
Returns a shared pointer to the site at address addr.
lldb::break_id_t GetID() const
virtual lldb::addr_t GetLoadAddress() const
bool HardwareRequired() const
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
void SetExecutableModule(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Set the main executable module.
void AddThread(const lldb::ThreadSP &thread_sp)
virtual ThreadIterable Threads()
#define LLDB_INVALID_BREAK_ID
#define LLDB_INVALID_INDEX32
#define LLDB_INVALID_ADDRESS
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< ExceptionRecord > ExceptionRecordSP
HostThreadPosix HostNativeThread
bool StateIsRunningState(lldb::StateType state)
Check if a state represents a state where the process or thread is running.
std::shared_ptr< IDebugDelegate > DebugDelegateSP
std::shared_ptr< DebuggerThread > DebuggerThreadSP
static void DumpAdditionalExceptionInformation(llvm::raw_ostream &stream, const ExceptionRecordSP &exception)
static bool ShouldUseLLDBServer()
std::shared_ptr< lldb_private::BreakpointSite > BreakpointSiteSP
RunDirection
Execution directions.
std::shared_ptr< lldb_private::Thread > ThreadSP
StateType
Process and Thread States.
@ eStateUnloaded
Process is object is valid, but not currently loaded.
@ eStateDetached
Process has been detached and can't be examined.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateExited
Process has exited and can't be examined.
@ eStateCrashed
Process or thread has crashed and can be examined.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Watchpoint > WatchpointSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::Module > ModuleSP