diff options
Diffstat (limited to 'source/Plugins/Platform/Windows/PlatformWindows.cpp')
-rw-r--r-- | source/Plugins/Platform/Windows/PlatformWindows.cpp | 1036 |
1 files changed, 463 insertions, 573 deletions
diff --git a/source/Plugins/Platform/Windows/PlatformWindows.cpp b/source/Plugins/Platform/Windows/PlatformWindows.cpp index cef5684d9bac..290d8eab792f 100644 --- a/source/Plugins/Platform/Windows/PlatformWindows.cpp +++ b/source/Plugins/Platform/Windows/PlatformWindows.cpp @@ -11,7 +11,7 @@ // C Includes #include <stdio.h> -#if defined (_WIN32) +#if defined(_WIN32) #include "lldb/Host/windows/windows.h" #include <winsock2.h> #endif @@ -19,14 +19,14 @@ // C++ Includes // Other libraries and framework includes // Project includes -#include "lldb/Core/Error.h" +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/Module.h" -#include "lldb/Breakpoint/BreakpointLocation.h" -#include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Target/Process.h" using namespace lldb; @@ -34,161 +34,133 @@ using namespace lldb_private; static uint32_t g_initialize_count = 0; -namespace -{ - class SupportedArchList - { - public: - SupportedArchList() - { - AddArch(ArchSpec("i686-pc-windows")); - AddArch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault)); - AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind32)); - AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind64)); - AddArch(ArchSpec("i386-pc-windows")); - } - - size_t Count() const { return m_archs.size(); } - - const ArchSpec& operator[](int idx) { return m_archs[idx]; } - - private: - void AddArch(const ArchSpec& spec) - { - auto iter = std::find_if( - m_archs.begin(), m_archs.end(), - [spec](const ArchSpec& rhs) { return spec.IsExactMatch(rhs); }); - if (iter != m_archs.end()) - return; - if (spec.IsValid()) - m_archs.push_back(spec); - } - - std::vector<ArchSpec> m_archs; - }; +namespace { +class SupportedArchList { +public: + SupportedArchList() { + AddArch(ArchSpec("i686-pc-windows")); + AddArch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault)); + AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind32)); + AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind64)); + AddArch(ArchSpec("i386-pc-windows")); + } + + size_t Count() const { return m_archs.size(); } + + const ArchSpec &operator[](int idx) { return m_archs[idx]; } + +private: + void AddArch(const ArchSpec &spec) { + auto iter = std::find_if( + m_archs.begin(), m_archs.end(), + [spec](const ArchSpec &rhs) { return spec.IsExactMatch(rhs); }); + if (iter != m_archs.end()) + return; + if (spec.IsValid()) + m_archs.push_back(spec); + } + + std::vector<ArchSpec> m_archs; +}; } // anonymous namespace -PlatformSP -PlatformWindows::CreateInstance (bool force, const lldb_private::ArchSpec *arch) -{ - // The only time we create an instance is when we are creating a remote - // windows platform - const bool is_host = false; - - bool create = force; - if (create == false && arch && arch->IsValid()) - { - const llvm::Triple &triple = arch->GetTriple(); - switch (triple.getVendor()) - { - case llvm::Triple::PC: - create = true; - break; +PlatformSP PlatformWindows::CreateInstance(bool force, + const lldb_private::ArchSpec *arch) { + // The only time we create an instance is when we are creating a remote + // windows platform + const bool is_host = false; + + bool create = force; + if (create == false && arch && arch->IsValid()) { + const llvm::Triple &triple = arch->GetTriple(); + switch (triple.getVendor()) { + case llvm::Triple::PC: + create = true; + break; + + case llvm::Triple::UnknownArch: + create = !arch->TripleVendorWasSpecified(); + break; + + default: + break; + } - case llvm::Triple::UnknownArch: - create = !arch->TripleVendorWasSpecified(); - break; + if (create) { + switch (triple.getOS()) { + case llvm::Triple::Win32: + break; - default: - break; - } + case llvm::Triple::UnknownOS: + create = arch->TripleOSWasSpecified(); + break; - if (create) - { - switch (triple.getOS()) - { - case llvm::Triple::Win32: - break; - - case llvm::Triple::UnknownOS: - create = arch->TripleOSWasSpecified(); - break; - - default: - create = false; - break; - } - } + default: + create = false; + break; + } } - if (create) - return PlatformSP(new PlatformWindows (is_host)); - return PlatformSP(); + } + if (create) + return PlatformSP(new PlatformWindows(is_host)); + return PlatformSP(); } -lldb_private::ConstString -PlatformWindows::GetPluginNameStatic(bool is_host) -{ - if (is_host) - { - static ConstString g_host_name(Platform::GetHostPlatformName ()); - return g_host_name; - } - else - { - static ConstString g_remote_name("remote-windows"); - return g_remote_name; - } +lldb_private::ConstString PlatformWindows::GetPluginNameStatic(bool is_host) { + if (is_host) { + static ConstString g_host_name(Platform::GetHostPlatformName()); + return g_host_name; + } else { + static ConstString g_remote_name("remote-windows"); + return g_remote_name; + } } -const char * -PlatformWindows::GetPluginDescriptionStatic(bool is_host) -{ - return is_host ? - "Local Windows user platform plug-in." : - "Remote Windows user platform plug-in."; +const char *PlatformWindows::GetPluginDescriptionStatic(bool is_host) { + return is_host ? "Local Windows user platform plug-in." + : "Remote Windows user platform plug-in."; } -lldb_private::ConstString -PlatformWindows::GetPluginName() -{ - return GetPluginNameStatic(IsHost()); +lldb_private::ConstString PlatformWindows::GetPluginName() { + return GetPluginNameStatic(IsHost()); } -void -PlatformWindows::Initialize() -{ - Platform::Initialize (); - - if (g_initialize_count++ == 0) - { -#if defined (_WIN32) - WSADATA dummy; - WSAStartup(MAKEWORD(2,2), &dummy); - // Force a host flag to true for the default platform object. - PlatformSP default_platform_sp (new PlatformWindows(true)); - default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); - Platform::SetHostPlatform (default_platform_sp); +void PlatformWindows::Initialize() { + Platform::Initialize(); + + if (g_initialize_count++ == 0) { +#if defined(_WIN32) + WSADATA dummy; + WSAStartup(MAKEWORD(2, 2), &dummy); + // Force a host flag to true for the default platform object. + PlatformSP default_platform_sp(new PlatformWindows(true)); + default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture()); + Platform::SetHostPlatform(default_platform_sp); #endif - PluginManager::RegisterPlugin(PlatformWindows::GetPluginNameStatic(false), - PlatformWindows::GetPluginDescriptionStatic(false), - PlatformWindows::CreateInstance); - } + PluginManager::RegisterPlugin( + PlatformWindows::GetPluginNameStatic(false), + PlatformWindows::GetPluginDescriptionStatic(false), + PlatformWindows::CreateInstance); + } } -void -PlatformWindows::Terminate( void ) -{ - if (g_initialize_count > 0) - { - if (--g_initialize_count == 0) - { +void PlatformWindows::Terminate(void) { + if (g_initialize_count > 0) { + if (--g_initialize_count == 0) { #ifdef _WIN32 - WSACleanup(); + WSACleanup(); #endif - PluginManager::UnregisterPlugin (PlatformWindows::CreateInstance); - } + PluginManager::UnregisterPlugin(PlatformWindows::CreateInstance); } + } - Platform::Terminate (); + Platform::Terminate(); } //------------------------------------------------------------------ /// Default Constructor //------------------------------------------------------------------ -PlatformWindows::PlatformWindows (bool is_host) : - Platform(is_host) -{ -} +PlatformWindows::PlatformWindows(bool is_host) : Platform(is_host) {} //------------------------------------------------------------------ /// Destructor. @@ -198,520 +170,438 @@ PlatformWindows::PlatformWindows (bool is_host) : //------------------------------------------------------------------ PlatformWindows::~PlatformWindows() = default; -bool -PlatformWindows::GetModuleSpec (const FileSpec& module_file_spec, - const ArchSpec& arch, - ModuleSpec &module_spec) -{ - if (m_remote_platform_sp) - return m_remote_platform_sp->GetModuleSpec (module_file_spec, arch, module_spec); +bool PlatformWindows::GetModuleSpec(const FileSpec &module_file_spec, + const ArchSpec &arch, + ModuleSpec &module_spec) { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetModuleSpec(module_file_spec, arch, + module_spec); - return Platform::GetModuleSpec (module_file_spec, arch, module_spec); + return Platform::GetModuleSpec(module_file_spec, arch, module_spec); } -Error -PlatformWindows::ResolveExecutable (const ModuleSpec &ms, - lldb::ModuleSP &exe_module_sp, - const FileSpecList *module_search_paths_ptr) -{ - Error error; - // Nothing special to do here, just use the actual file and architecture - - char exe_path[PATH_MAX]; - ModuleSpec resolved_module_spec(ms); - - if (IsHost()) - { - // if we cant resolve the executable loation based on the current path variables - if (!resolved_module_spec.GetFileSpec().Exists()) - { - resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); - resolved_module_spec.GetFileSpec().SetFile(exe_path, true); - } +Error PlatformWindows::ResolveExecutable( + const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp, + const FileSpecList *module_search_paths_ptr) { + Error error; + // Nothing special to do here, just use the actual file and architecture + + char exe_path[PATH_MAX]; + ModuleSpec resolved_module_spec(ms); + + if (IsHost()) { + // if we cant resolve the executable loation based on the current path + // variables + if (!resolved_module_spec.GetFileSpec().Exists()) { + resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); + resolved_module_spec.GetFileSpec().SetFile(exe_path, true); + } - if (!resolved_module_spec.GetFileSpec().Exists()) - resolved_module_spec.GetFileSpec().ResolveExecutableLocation (); + if (!resolved_module_spec.GetFileSpec().Exists()) + resolved_module_spec.GetFileSpec().ResolveExecutableLocation(); - if (resolved_module_spec.GetFileSpec().Exists()) - error.Clear(); - else - { - ms.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); - error.SetErrorStringWithFormat("unable to find executable for '%s'", exe_path); - } + if (resolved_module_spec.GetFileSpec().Exists()) + error.Clear(); + else { + ms.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); + error.SetErrorStringWithFormat("unable to find executable for '%s'", + exe_path); } - else - { - if (m_remote_platform_sp) - { - error = GetCachedExecutable (resolved_module_spec, exe_module_sp, nullptr, *m_remote_platform_sp); - } - else - { - // We may connect to a process and use the provided executable (Don't use local $PATH). - if (resolved_module_spec.GetFileSpec().Exists()) - error.Clear(); - else - error.SetErrorStringWithFormat("the platform is not currently connected, and '%s' doesn't exist in the system root.", exe_path); - } + } else { + if (m_remote_platform_sp) { + error = GetCachedExecutable(resolved_module_spec, exe_module_sp, nullptr, + *m_remote_platform_sp); + } else { + // We may connect to a process and use the provided executable (Don't use + // local $PATH). + if (resolved_module_spec.GetFileSpec().Exists()) + error.Clear(); + else + error.SetErrorStringWithFormat("the platform is not currently " + "connected, and '%s' doesn't exist in " + "the system root.", + exe_path); } - - if (error.Success()) - { - if (resolved_module_spec.GetArchitecture().IsValid()) - { - error = ModuleList::GetSharedModule(resolved_module_spec, - exe_module_sp, - nullptr, - nullptr, - nullptr); - - if (!exe_module_sp || exe_module_sp->GetObjectFile() == nullptr) - { - exe_module_sp.reset(); - error.SetErrorStringWithFormat ("'%s' doesn't contain the architecture %s", - resolved_module_spec.GetFileSpec().GetPath().c_str(), - resolved_module_spec.GetArchitecture().GetArchitectureName()); - } + } + + if (error.Success()) { + if (resolved_module_spec.GetArchitecture().IsValid()) { + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + nullptr, nullptr, nullptr); + + if (!exe_module_sp || exe_module_sp->GetObjectFile() == nullptr) { + exe_module_sp.reset(); + error.SetErrorStringWithFormat( + "'%s' doesn't contain the architecture %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + resolved_module_spec.GetArchitecture().GetArchitectureName()); + } + } else { + // No valid architecture was specified, ask the platform for + // the architectures that we should be using (in the correct order) + // and see if we can find a match that way + StreamString arch_names; + for (uint32_t idx = 0; GetSupportedArchitectureAtIndex( + idx, resolved_module_spec.GetArchitecture()); + ++idx) { + error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp, + nullptr, nullptr, nullptr); + // Did we find an executable using one of the + if (error.Success()) { + if (exe_module_sp && exe_module_sp->GetObjectFile()) + break; + else + error.SetErrorToGenericError(); } - else - { - // No valid architecture was specified, ask the platform for - // the architectures that we should be using (in the correct order) - // and see if we can find a match that way - StreamString arch_names; - for (uint32_t idx = 0; GetSupportedArchitectureAtIndex (idx, resolved_module_spec.GetArchitecture()); ++idx) - { - error = ModuleList::GetSharedModule(resolved_module_spec, - exe_module_sp, - nullptr, - nullptr, - nullptr); - // Did we find an executable using one of the - if (error.Success()) - { - if (exe_module_sp && exe_module_sp->GetObjectFile()) - break; - else - error.SetErrorToGenericError(); - } - - if (idx > 0) - arch_names.PutCString (", "); - arch_names.PutCString (resolved_module_spec.GetArchitecture().GetArchitectureName()); - } - - if (error.Fail() || !exe_module_sp) - { - if (resolved_module_spec.GetFileSpec().Readable()) - { - error.SetErrorStringWithFormat ("'%s' doesn't contain any '%s' platform architectures: %s", - resolved_module_spec.GetFileSpec().GetPath().c_str(), - GetPluginName().GetCString(), - arch_names.GetString().c_str()); - } - else - { - error.SetErrorStringWithFormat("'%s' is not readable", resolved_module_spec.GetFileSpec().GetPath().c_str()); - } - } + + if (idx > 0) + arch_names.PutCString(", "); + arch_names.PutCString( + resolved_module_spec.GetArchitecture().GetArchitectureName()); + } + + if (error.Fail() || !exe_module_sp) { + if (resolved_module_spec.GetFileSpec().Readable()) { + error.SetErrorStringWithFormat( + "'%s' doesn't contain any '%s' platform architectures: %s", + resolved_module_spec.GetFileSpec().GetPath().c_str(), + GetPluginName().GetCString(), arch_names.GetData()); + } else { + error.SetErrorStringWithFormat( + "'%s' is not readable", + resolved_module_spec.GetFileSpec().GetPath().c_str()); } + } } + } - return error; + return error; } -bool -PlatformWindows::GetRemoteOSVersion () -{ - if (m_remote_platform_sp) - return m_remote_platform_sp->GetOSVersion (m_major_os_version, - m_minor_os_version, - m_update_os_version); - return false; +bool PlatformWindows::GetRemoteOSVersion() { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetOSVersion( + m_major_os_version, m_minor_os_version, m_update_os_version); + return false; } -bool -PlatformWindows::GetRemoteOSBuildString (std::string &s) -{ - if (m_remote_platform_sp) - return m_remote_platform_sp->GetRemoteOSBuildString (s); - s.clear(); - return false; +bool PlatformWindows::GetRemoteOSBuildString(std::string &s) { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteOSBuildString(s); + s.clear(); + return false; } -bool -PlatformWindows::GetRemoteOSKernelDescription (std::string &s) -{ - if (m_remote_platform_sp) - return m_remote_platform_sp->GetRemoteOSKernelDescription (s); - s.clear(); - return false; +bool PlatformWindows::GetRemoteOSKernelDescription(std::string &s) { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteOSKernelDescription(s); + s.clear(); + return false; } // Remote Platform subclasses need to override this function -ArchSpec -PlatformWindows::GetRemoteSystemArchitecture () -{ - if (m_remote_platform_sp) - return m_remote_platform_sp->GetRemoteSystemArchitecture (); - return ArchSpec(); +ArchSpec PlatformWindows::GetRemoteSystemArchitecture() { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteSystemArchitecture(); + return ArchSpec(); } -const char * -PlatformWindows::GetHostname () -{ - if (IsHost()) - return Platform::GetHostname(); +const char *PlatformWindows::GetHostname() { + if (IsHost()) + return Platform::GetHostname(); - if (m_remote_platform_sp) - return m_remote_platform_sp->GetHostname (); - return nullptr; + if (m_remote_platform_sp) + return m_remote_platform_sp->GetHostname(); + return nullptr; } -bool -PlatformWindows::IsConnected () const -{ - if (IsHost()) - return true; - else if (m_remote_platform_sp) - return m_remote_platform_sp->IsConnected(); - return false; +bool PlatformWindows::IsConnected() const { + if (IsHost()) + return true; + else if (m_remote_platform_sp) + return m_remote_platform_sp->IsConnected(); + return false; } -Error -PlatformWindows::ConnectRemote (Args& args) -{ - Error error; - if (IsHost()) - { - error.SetErrorStringWithFormat ("can't connect to the host platform '%s', always connected", GetPluginName().AsCString() ); - } - else - { - if (!m_remote_platform_sp) - m_remote_platform_sp = Platform::Create (ConstString("remote-gdb-server"), error); - - if (m_remote_platform_sp) - { - if (error.Success()) - { - if (m_remote_platform_sp) - { - error = m_remote_platform_sp->ConnectRemote (args); - } - else - { - error.SetErrorString ("\"platform connect\" takes a single argument: <connect-url>"); - } - } +Error PlatformWindows::ConnectRemote(Args &args) { + Error error; + if (IsHost()) { + error.SetErrorStringWithFormat( + "can't connect to the host platform '%s', always connected", + GetPluginName().AsCString()); + } else { + if (!m_remote_platform_sp) + m_remote_platform_sp = + Platform::Create(ConstString("remote-gdb-server"), error); + + if (m_remote_platform_sp) { + if (error.Success()) { + if (m_remote_platform_sp) { + error = m_remote_platform_sp->ConnectRemote(args); + } else { + error.SetErrorString( + "\"platform connect\" takes a single argument: <connect-url>"); } - else - error.SetErrorString ("failed to create a 'remote-gdb-server' platform"); + } + } else + error.SetErrorString("failed to create a 'remote-gdb-server' platform"); - if (error.Fail()) - m_remote_platform_sp.reset(); - } + if (error.Fail()) + m_remote_platform_sp.reset(); + } - return error; + return error; } -Error -PlatformWindows::DisconnectRemote () -{ - Error error; +Error PlatformWindows::DisconnectRemote() { + Error error; - if (IsHost()) - { - error.SetErrorStringWithFormat ("can't disconnect from the host platform '%s', always connected", GetPluginName().AsCString() ); - } + if (IsHost()) { + error.SetErrorStringWithFormat( + "can't disconnect from the host platform '%s', always connected", + GetPluginName().AsCString()); + } else { + if (m_remote_platform_sp) + error = m_remote_platform_sp->DisconnectRemote(); else - { - if (m_remote_platform_sp) - error = m_remote_platform_sp->DisconnectRemote (); - else - error.SetErrorString ("the platform is not currently connected"); - } - return error; + error.SetErrorString("the platform is not currently connected"); + } + return error; } -bool -PlatformWindows::GetProcessInfo (lldb::pid_t pid, ProcessInstanceInfo &process_info) -{ - bool success = false; - if (IsHost()) - { - success = Platform::GetProcessInfo (pid, process_info); - } - else if (m_remote_platform_sp) - { - success = m_remote_platform_sp->GetProcessInfo (pid, process_info); - } - return success; +bool PlatformWindows::GetProcessInfo(lldb::pid_t pid, + ProcessInstanceInfo &process_info) { + bool success = false; + if (IsHost()) { + success = Platform::GetProcessInfo(pid, process_info); + } else if (m_remote_platform_sp) { + success = m_remote_platform_sp->GetProcessInfo(pid, process_info); + } + return success; } uint32_t -PlatformWindows::FindProcesses (const ProcessInstanceInfoMatch &match_info, - ProcessInstanceInfoList &process_infos) -{ - uint32_t match_count = 0; - if (IsHost()) - { - // Let the base class figure out the host details - match_count = Platform::FindProcesses (match_info, process_infos); - } - else - { - // If we are remote, we can only return results if we are connected - if (m_remote_platform_sp) - match_count = m_remote_platform_sp->FindProcesses (match_info, process_infos); - } - return match_count; +PlatformWindows::FindProcesses(const ProcessInstanceInfoMatch &match_info, + ProcessInstanceInfoList &process_infos) { + uint32_t match_count = 0; + if (IsHost()) { + // Let the base class figure out the host details + match_count = Platform::FindProcesses(match_info, process_infos); + } else { + // If we are remote, we can only return results if we are connected + if (m_remote_platform_sp) + match_count = + m_remote_platform_sp->FindProcesses(match_info, process_infos); + } + return match_count; } -Error -PlatformWindows::LaunchProcess (ProcessLaunchInfo &launch_info) -{ - Error error; - if (IsHost()) - { - error = Platform::LaunchProcess (launch_info); - } +Error PlatformWindows::LaunchProcess(ProcessLaunchInfo &launch_info) { + Error error; + if (IsHost()) { + error = Platform::LaunchProcess(launch_info); + } else { + if (m_remote_platform_sp) + error = m_remote_platform_sp->LaunchProcess(launch_info); else - { - if (m_remote_platform_sp) - error = m_remote_platform_sp->LaunchProcess (launch_info); - else - error.SetErrorString ("the platform is not currently connected"); - } - return error; + error.SetErrorString("the platform is not currently connected"); + } + return error; } -ProcessSP -PlatformWindows::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target *target, Error &error) -{ - // Windows has special considerations that must be followed when launching or attaching to a process. The - // key requirement is that when launching or attaching to a process, you must do it from the same the thread - // that will go into a permanent loop which will then receive debug events from the process. In particular, - // this means we can't use any of LLDB's generic mechanisms to do it for us, because it doesn't have the - // special knowledge required for setting up the background thread or passing the right flags. - // - // Another problem is that that LLDB's standard model for debugging a process is to first launch it, have - // it stop at the entry point, and then attach to it. In Windows this doesn't quite work, you have to - // specify as an argument to CreateProcess() that you're going to debug the process. So we override DebugProcess - // here to handle this. Launch operations go directly to the process plugin, and attach operations almost go - // directly to the process plugin (but we hijack the events first). In essence, we encapsulate all the logic - // of Launching and Attaching in the process plugin, and PlatformWindows::DebugProcess is just a pass-through - // to get to the process plugin. - - if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) - { - // This is a process attach. Don't need to launch anything. - ProcessAttachInfo attach_info(launch_info); - return Attach(attach_info, debugger, target, error); - } - else - { - ProcessSP process_sp = target->CreateProcess(launch_info.GetListenerForProcess(debugger), - launch_info.GetProcessPluginName(), - nullptr); - - // We need to launch and attach to the process. - launch_info.GetFlags().Set(eLaunchFlagDebug); - if (process_sp) - error = process_sp->Launch(launch_info); +ProcessSP PlatformWindows::DebugProcess(ProcessLaunchInfo &launch_info, + Debugger &debugger, Target *target, + Error &error) { + // Windows has special considerations that must be followed when launching or + // attaching to a process. The + // key requirement is that when launching or attaching to a process, you must + // do it from the same the thread + // that will go into a permanent loop which will then receive debug events + // from the process. In particular, + // this means we can't use any of LLDB's generic mechanisms to do it for us, + // because it doesn't have the + // special knowledge required for setting up the background thread or passing + // the right flags. + // + // Another problem is that that LLDB's standard model for debugging a process + // is to first launch it, have + // it stop at the entry point, and then attach to it. In Windows this doesn't + // quite work, you have to + // specify as an argument to CreateProcess() that you're going to debug the + // process. So we override DebugProcess + // here to handle this. Launch operations go directly to the process plugin, + // and attach operations almost go + // directly to the process plugin (but we hijack the events first). In + // essence, we encapsulate all the logic + // of Launching and Attaching in the process plugin, and + // PlatformWindows::DebugProcess is just a pass-through + // to get to the process plugin. + + if (launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) { + // This is a process attach. Don't need to launch anything. + ProcessAttachInfo attach_info(launch_info); + return Attach(attach_info, debugger, target, error); + } else { + ProcessSP process_sp = + target->CreateProcess(launch_info.GetListenerForProcess(debugger), + launch_info.GetProcessPluginName(), nullptr); + + // We need to launch and attach to the process. + launch_info.GetFlags().Set(eLaunchFlagDebug); + if (process_sp) + error = process_sp->Launch(launch_info); - return process_sp; - } + return process_sp; + } } -lldb::ProcessSP -PlatformWindows::Attach(ProcessAttachInfo &attach_info, - Debugger &debugger, - Target *target, - Error &error) -{ - error.Clear(); - lldb::ProcessSP process_sp; - if (!IsHost()) - { - if (m_remote_platform_sp) - process_sp = m_remote_platform_sp->Attach (attach_info, debugger, target, error); - else - error.SetErrorString ("the platform is not currently connected"); - return process_sp; - } +lldb::ProcessSP PlatformWindows::Attach(ProcessAttachInfo &attach_info, + Debugger &debugger, Target *target, + Error &error) { + error.Clear(); + lldb::ProcessSP process_sp; + if (!IsHost()) { + if (m_remote_platform_sp) + process_sp = + m_remote_platform_sp->Attach(attach_info, debugger, target, error); + else + error.SetErrorString("the platform is not currently connected"); + return process_sp; + } - if (target == nullptr) - { - TargetSP new_target_sp; - FileSpec emptyFileSpec; - ArchSpec emptyArchSpec; - - error = debugger.GetTargetList().CreateTarget(debugger, - nullptr, - nullptr, - false, - nullptr, - new_target_sp); - target = new_target_sp.get(); - } + if (target == nullptr) { + TargetSP new_target_sp; + FileSpec emptyFileSpec; + ArchSpec emptyArchSpec; - if (!target || error.Fail()) - return process_sp; + error = debugger.GetTargetList().CreateTarget(debugger, "", "", false, + nullptr, new_target_sp); + target = new_target_sp.get(); + } - debugger.GetTargetList().SetSelectedTarget(target); + if (!target || error.Fail()) + return process_sp; - const char *plugin_name = attach_info.GetProcessPluginName(); - process_sp = target->CreateProcess(attach_info.GetListenerForProcess(debugger), plugin_name, nullptr); + debugger.GetTargetList().SetSelectedTarget(target); - process_sp->HijackProcessEvents(attach_info.GetHijackListener()); - if (process_sp) - error = process_sp->Attach (attach_info); + const char *plugin_name = attach_info.GetProcessPluginName(); + process_sp = target->CreateProcess( + attach_info.GetListenerForProcess(debugger), plugin_name, nullptr); - return process_sp; -} + process_sp->HijackProcessEvents(attach_info.GetHijackListener()); + if (process_sp) + error = process_sp->Attach(attach_info); -const char * -PlatformWindows::GetUserName (uint32_t uid) -{ - // Check the cache in Platform in case we have already looked this uid up - const char *user_name = Platform::GetUserName(uid); - if (user_name) - return user_name; - - if (IsRemote() && m_remote_platform_sp) - return m_remote_platform_sp->GetUserName(uid); - return nullptr; + return process_sp; } -const char * -PlatformWindows::GetGroupName (uint32_t gid) -{ - const char *group_name = Platform::GetGroupName(gid); - if (group_name) - return group_name; +const char *PlatformWindows::GetUserName(uint32_t uid) { + // Check the cache in Platform in case we have already looked this uid up + const char *user_name = Platform::GetUserName(uid); + if (user_name) + return user_name; - if (IsRemote() && m_remote_platform_sp) - return m_remote_platform_sp->GetGroupName(gid); - return nullptr; + if (IsRemote() && m_remote_platform_sp) + return m_remote_platform_sp->GetUserName(uid); + return nullptr; } -Error -PlatformWindows::GetFileWithUUID (const FileSpec &platform_file, - const UUID *uuid_ptr, - FileSpec &local_file) -{ - if (IsRemote()) - { - if (m_remote_platform_sp) - return m_remote_platform_sp->GetFileWithUUID (platform_file, uuid_ptr, local_file); - } +const char *PlatformWindows::GetGroupName(uint32_t gid) { + const char *group_name = Platform::GetGroupName(gid); + if (group_name) + return group_name; - // Default to the local case - local_file = platform_file; - return Error(); + if (IsRemote() && m_remote_platform_sp) + return m_remote_platform_sp->GetGroupName(gid); + return nullptr; } -Error -PlatformWindows::GetSharedModule (const ModuleSpec &module_spec, - Process* process, - ModuleSP &module_sp, - const FileSpecList *module_search_paths_ptr, - ModuleSP *old_module_sp_ptr, - bool *did_create_ptr) -{ - Error error; - module_sp.reset(); - - if (IsRemote()) - { - // If we have a remote platform always, let it try and locate - // the shared module first. - if (m_remote_platform_sp) - { - error = m_remote_platform_sp->GetSharedModule (module_spec, - process, - module_sp, - module_search_paths_ptr, - old_module_sp_ptr, - did_create_ptr); - } - } +Error PlatformWindows::GetFileWithUUID(const FileSpec &platform_file, + const UUID *uuid_ptr, + FileSpec &local_file) { + if (IsRemote()) { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetFileWithUUID(platform_file, uuid_ptr, + local_file); + } - if (!module_sp) - { - // Fall back to the local platform and find the file locally - error = Platform::GetSharedModule (module_spec, - process, - module_sp, - module_search_paths_ptr, - old_module_sp_ptr, - did_create_ptr); + // Default to the local case + local_file = platform_file; + return Error(); +} + +Error PlatformWindows::GetSharedModule( + const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp, + const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr, + bool *did_create_ptr) { + Error error; + module_sp.reset(); + + if (IsRemote()) { + // If we have a remote platform always, let it try and locate + // the shared module first. + if (m_remote_platform_sp) { + error = m_remote_platform_sp->GetSharedModule( + module_spec, process, module_sp, module_search_paths_ptr, + old_module_sp_ptr, did_create_ptr); } - if (module_sp) - module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); - return error; + } + + if (!module_sp) { + // Fall back to the local platform and find the file locally + error = Platform::GetSharedModule(module_spec, process, module_sp, + module_search_paths_ptr, + old_module_sp_ptr, did_create_ptr); + } + if (module_sp) + module_sp->SetPlatformFileSpec(module_spec.GetFileSpec()); + return error; } -bool -PlatformWindows::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch) -{ - static SupportedArchList architectures; +bool PlatformWindows::GetSupportedArchitectureAtIndex(uint32_t idx, + ArchSpec &arch) { + static SupportedArchList architectures; - if (idx >= architectures.Count()) - return false; - arch = architectures[idx]; - return true; + if (idx >= architectures.Count()) + return false; + arch = architectures[idx]; + return true; } -void -PlatformWindows::GetStatus (Stream &strm) -{ - Platform::GetStatus(strm); +void PlatformWindows::GetStatus(Stream &strm) { + Platform::GetStatus(strm); #ifdef _WIN32 - uint32_t major; - uint32_t minor; - uint32_t update; - if (!HostInfo::GetOSVersion(major, minor, update)) - { - strm << "Windows"; - return; - } - - strm << "Host: Windows " << major - << '.' << minor - << " Build: " << update << '\n'; + uint32_t major; + uint32_t minor; + uint32_t update; + if (!HostInfo::GetOSVersion(major, minor, update)) { + strm << "Windows"; + return; + } + + strm << "Host: Windows " << major << '.' << minor << " Build: " << update + << '\n'; #endif } -bool -PlatformWindows::CanDebugProcess() -{ - return true; -} +bool PlatformWindows::CanDebugProcess() { return true; } -size_t -PlatformWindows::GetEnvironment(StringList &env) -{ - if (IsRemote()) - { - if (m_remote_platform_sp) - return m_remote_platform_sp->GetEnvironment(env); - return 0; - } +size_t PlatformWindows::GetEnvironment(StringList &env) { + if (IsRemote()) { + if (m_remote_platform_sp) + return m_remote_platform_sp->GetEnvironment(env); + return 0; + } - return Host::GetEnvironment(env); + return Host::GetEnvironment(env); } -ConstString -PlatformWindows::GetFullNameForDylib (ConstString basename) -{ - if (basename.IsEmpty()) - return basename; - - StreamString stream; - stream.Printf("%s.dll", basename.GetCString()); - return ConstString(stream.GetData()); +ConstString PlatformWindows::GetFullNameForDylib(ConstString basename) { + if (basename.IsEmpty()) + return basename; + + StreamString stream; + stream.Printf("%s.dll", basename.GetCString()); + return ConstString(stream.GetString()); } |