24#include "lldb/Host/Config.h"
44#include "llvm/Support/ConvertUTF.h"
45#include "llvm/Support/ErrorExtras.h"
46#include "llvm/Support/Format.h"
47#include "llvm/Support/Threading.h"
48#include "llvm/Support/raw_ostream.h"
63std::string GetProcessExecutableName(
HANDLE process_handle) {
64 std::vector<wchar_t> file_name;
69 file_name.resize(file_name_size);
70 copied = ::GetModuleFileNameExW(process_handle,
nullptr, file_name.data(),
72 }
while (copied >= file_name_size);
73 file_name.resize(copied);
75 llvm::convertWideToUTF8(file_name.data(), result);
80std::string GetProcessExecutableName(DWORD pid) {
81 std::string file_name;
83 ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
84 if (process_handle !=
nullptr) {
85 file_name = GetProcessExecutableName(process_handle);
86 ::CloseHandle(process_handle);
104 if (
const char *env = ::getenv(
"LLDB_USE_LLDB_SERVER")) {
105 llvm::StringRef use_lldb_server(env);
106 return use_lldb_server.equals_insensitive(
"on") ||
107 use_lldb_server.equals_insensitive(
"yes") ||
108 use_lldb_server.equals_insensitive(
"1") ||
109 use_lldb_server.equals_insensitive(
"true");
111 return LLDB_ENABLE_LIBXML2;
127 return "Process plugin for Windows";
146 LLDB_LOG(log,
"bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
150 if (!
error.Success())
157 LLDB_LOG(log,
"bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
162 if (!
error.Success())
177 LLDB_LOG(log,
"process {0} is in state {1}. Resuming for detach...",
181 LLDB_LOG(log,
"resuming {0} threads for detach.",
186 auto thread = std::static_pointer_cast<TargetThreadWindows>(
188 Status result = thread->DoResume();
192 "Trying to resume thread at index {0}, but failed with "
211 "error: process {0} in state = {1}, but "
212 "cannot detach it in this state.",
213 GetID(), private_state);
245 llvm::sys::ScopedLock lock(
m_mutex);
249 "{0} does not support reverse execution of processes",
GetPluginName());
256 LLDB_LOG(log,
"process {0} is in state {1}. Resuming...",
264 auto thread = std::static_pointer_cast<TargetThreadWindows>(
266 Status result = thread->DoResume();
271 "Trying to resume thread at index {0}, but failed with error {1}.",
284 if (active_exception) {
292 LLDB_LOG(log,
"error: process {0} is in state {1}. Returning...",
309 if (
error.Fail() || !caused_stop)
322 llvm::sys::ScopedLock lock(
m_mutex);
333 llvm::sys::ScopedLock lock(
m_mutex);
336 LLDB_LOG(log,
"no active session. Returning...");
344 if (!active_exception) {
346 "there is no active exception in process {0}. Why is the "
353 m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
359 uint64_t
pc = register_context->GetPC();
365 stop_thread->SetThreadStoppedAtUnexecutedBP(
pc);
367 switch (active_exception->GetExceptionValue()) {
368 case EXCEPTION_SINGLE_STEP: {
370 stop_thread->GetRegisterContext().get());
375 "Single-stepped onto a watchpoint in process {0} at address "
376 "{1:x} with watchpoint {2}",
380 stop_thread->SetStopInfo(stop_info);
385 LLDB_LOG(log,
"single stepping thread {0}", stop_thread->GetID());
387 stop_thread->SetStopInfo(stop_info);
392 case EXCEPTION_BREAKPOINT: {
393 int breakpoint_size = 1;
394 switch (
GetTarget().GetArchitecture().GetMachine()) {
395 case llvm::Triple::aarch64:
399 case llvm::Triple::arm:
400 case llvm::Triple::thumb:
404 case llvm::Triple::x86:
405 case llvm::Triple::x86_64:
410 LLDB_LOG(log,
"Unknown breakpoint size for architecture");
415 pc = register_context->GetPC() - breakpoint_size;
420 "detected breakpoint in process {0} at address {1:x} with "
421 "breakpoint site {2}",
425 stop_thread->SetThreadHitBreakpointSite();
426 if (site->ValidForThisThread(*stop_thread)) {
428 "Breakpoint site {0} is valid for this thread ({1:x}), "
429 "creating stop info.",
430 site->GetID(), stop_thread->GetID());
433 *stop_thread, site->GetID());
434 register_context->SetPC(
pc);
437 "Breakpoint site {0} is not valid for this thread, "
438 "creating empty stop info.",
441 stop_thread->SetStopInfo(stop_info);
447 "No breakpoint site matches for this thread. __debugbreak()? "
448 "Creating stop info with the exception.");
457 llvm::raw_string_ostream desc_stream(desc);
458 desc_stream <<
"Exception "
459 << llvm::format_hex(active_exception->GetExceptionValue(), 8)
460 <<
" encountered at address "
461 << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
462 active_exception->Dump(desc_stream);
466 stop_thread->SetStopInfo(stop_info);
474 bool plugin_specified_by_name) {
475 if (plugin_specified_by_name)
479 ModuleSP exe_module_sp(target_sp->GetExecutableModule());
480 if (exe_module_sp.get())
493 int continued_threads = 0;
494 int exited_threads = 0;
499 auto exited_thread_iter =
501 if (exited_thread_iter ==
m_session_data->m_exited_threads.end()) {
517 new_thread_list.
AddThread(thread_info.second);
524 LLDB_LOG(log,
"{0} new threads, {1} old threads, {2} exited threads.",
525 new_threads, continued_threads, exited_threads);
548 return HostInfo::GetArchitecture();
554 size_t bytes_read = 0;
561 size_t bytes_written = 0;
563 return bytes_written;
587 ObjectFile *obj_file = executable_sp->GetObjectFile();
605 LLDB_LOG(log,
"Process {0} exited with code {1}",
GetID(), exit_code);
609 m_pty->SetStopping(
true);
617 ModuleSP executable_module = target->GetExecutableModule();
619 unloaded_modules.
Append(executable_module);
620 target->ModulesDidUnload(unloaded_modules,
false);
637 for (
int consec_empty = 0; consec_empty < 3;) {
642 if (!::PeekNamedPipe(pipe,
nullptr, 0,
nullptr, &avail,
nullptr))
649 if (consec_empty < 3)
658 LLDB_LOG(log,
"Debugger connected to process {0}. Image base = {1:x}",
659 debugger->GetProcess().GetProcessId(), image_base);
663 const DWORD pid = debugger->GetProcess().GetProcessId();
664 const std::string file_name = GetProcessExecutableName(pid);
665 if (file_name.empty())
668 FileSpec executable_file(file_name);
673 GetTarget().GetOrCreateModule(module_spec, true, &error);
680 dyld->OnLoadModule(module,
ModuleSpec(), image_base);
686 llvm::sys::ScopedLock lock(
m_mutex);
688 const HostThread &host_main_thread = debugger->GetMainThread();
690 std::make_shared<TargetThreadWindows>(*
this, host_main_thread);
693 main_thread->SetID(
id);
702 llvm::sys::ScopedLock lock(
m_mutex);
713 "Debugger thread reported exception {0:x} at address {1:x}, "
714 "but there is no session.",
728 case EXCEPTION_BREAKPOINT: {
738 "Skipping expected loader breakpoint at address {0:x} in a "
750 "Hit loader breakpoint at address {0:x}, setting initial stop event.",
755 LLDB_LOG(log,
"Hit non-loader breakpoint at address {0:x}.",
767 case EXCEPTION_SINGLE_STEP:
774 "Debugger thread reported exception {0:x} at address {1:x} "
775 "(first_chance={2})",
790 llvm::sys::ScopedLock lock(
m_mutex);
792 ThreadSP thread = std::make_shared<TargetThreadWindows>(*
this, new_thread);
795 tid_t id = native_new_thread.GetThreadId();
800 for (
const std::map<int, WatchpointInfo>::value_type &p :
m_watchpoints) {
802 thread->GetRegisterContext().get());
804 p.second.size, p.second.read,
810 llvm::sys::ScopedLock lock(
m_mutex);
831 dyld->OnLoadModule(
nullptr, module_spec, module_addr);
838 dyld->OnUnloadModule(module_addr);
844 uint16_t length_lower_word) {
847 llvm::SmallVector<char, 256> buffer;
849 ReadDebugString(debug_string_addr, is_unicode, length_lower_word, buffer);
852 "Failed to read debug string at {1:x} (size & 0xffff={2}, "
854 debug_string_addr, length_lower_word, is_unicode);
861 assert(buffer.size() % 2 == 0);
862 llvm::ArrayRef<unsigned short> utf16(
863 reinterpret_cast<const unsigned short *
>(buffer.data()),
866 if (!llvm::convertUTF16ToUTF8String(utf16, out)) {
867 LLDB_LOG(log,
"Debug string is not valid Utf 16");
878 llvm::sys::ScopedLock lock(
m_mutex);
885 "Error {0} occurred during debugging. Unexpected behavior "
896 "Error {0} occurred launching the process before the initial stop. {1}",
912 return exc->GetExceptionValue();
918 if (wp_sp->IsEnabled()) {
919 wp_sp->SetEnabled(
true, notify);
931 "Can't find free slot for watchpoint %i", wp_sp->GetID());
934 info.
address = wp_sp->GetLoadAddress();
935 info.
size = wp_sp->GetByteSize();
936 info.
read = wp_sp->WatchpointRead();
937 info.
write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
942 thread->GetRegisterContext().get());
946 "Can't enable watchpoint %i on thread 0x%llx", wp_sp->GetID(),
955 thread->GetRegisterContext().get());
964 wp_sp->SetEnabled(
true, notify);
972 if (!wp_sp->IsEnabled()) {
973 wp_sp->SetEnabled(
false, notify);
980 "Info about watchpoint %i is not found", wp_sp->GetID());
987 thread->GetRegisterContext().get());
988 if (!reg_ctx->RemoveHardwareBreakpoint(it->second.slot_id)) {
990 "Can't disable watchpoint %i on thread 0x%llx", wp_sp->GetID(),
1001 wp_sp->SetEnabled(
false, notify);
1017 if (
m_pty ==
nullptr)
1020 std::make_unique<ConnectionConPTY>(
m_pty));
1031 std::make_shared<IOHandlerProcessSTDIOWindows>(
this);
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_LOG_VERBOSE(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.
unsigned long GetExceptionValue() 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.
HostNativeThread & GetNativeThread()
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)
An address in a process, qualified by an address space.
lldb::addr_t GetValue() 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 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)
bool IsSystemModuleAddress(lldb::addr_t addr)
virtual void OnExitProcess(uint32_t exit_code)
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)
lldb::pid_t GetProcessID() const
std::shared_ptr< PTY > TakePTY()
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.
DllEventAction OnUnloadDll(lldb::addr_t module_addr, lldb::tid_t thread_id) override
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 DrainProcessStdout()
Block until the stdio read thread has surfaced everything currently buffered in the ConPTY/pipe to th...
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.
DynamicLoaderWindowsDYLD * GetDynamicLoader() override
Get the dynamic loader plug-in for this process.
void OnDebugString(lldb::addr_t debug_string_addr, bool is_unicode, uint16_t length_lower_word) override
size_t DoReadMemory(const ProcessAddress &vm_addr, void *buf, size_t size, Status &error) override
Actually do the reading of memory from a 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
DllEventAction OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr, lldb::tid_t thread_id) 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.
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.
size_t PutSTDIN(const char *src, size_t src_len, Status &error) override
Puts data into this process's STDIN.
ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) override
std::map< lldb::break_id_t, WatchpointInfo > m_watchpoints
std::optional< DWORD > GetActiveExceptionCode() const
Returns the exception code of the active (current) debug exception, or std::nullopt if there is no ac...
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
bool m_expecting_loader_int3
Status DoHalt(bool &caused_stop) override
Halts a running process.
Status EnableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
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
bool IsBreakpointSitePhysicallyEnabled(const BreakpointSite &site)
void AppendSTDOUT(const char *s, size_t len)
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 RebuildModuleListWithExecutable(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Clear the module list and rebuild it around a new main executable.
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::string StripExtendedLengthPrefix(llvm::StringRef path)
Convert an extended-length path to a regular DOS path: "\\?\C:\a" becomes "C:\a" and "\\?...
HostThreadPosix HostNativeThread
std::shared_ptr< DebuggerThread > DebuggerThreadSP
std::shared_ptr< IDebugDelegate > DebugDelegateSP
std::shared_ptr< ExceptionRecord > ExceptionRecordSP
static bool ShouldUseLLDBServer()
std::shared_ptr< lldb_private::BreakpointSite > BreakpointSiteSP
RunDirection
Execution directions.
std::shared_ptr< lldb_private::Thread > ThreadSP
ConnectionStatus
Connection Status Types.
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