diff options
Diffstat (limited to 'source/Plugins')
42 files changed, 856 insertions, 285 deletions
diff --git a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index 0853fe286963..4204d18769b8 100644 --- a/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -236,7 +236,8 @@ ABISP ABIMacOSX_i386::CreateInstance (const ArchSpec &arch) { static ABISP g_abi_sp; - if (arch.GetTriple().getArch() == llvm::Triple::x86) + if ((arch.GetTriple().getArch() == llvm::Triple::x86) && + (arch.GetTriple().isMacOSX() || arch.GetTriple().isiOS())) { if (!g_abi_sp) g_abi_sp.reset (new ABIMacOSX_i386); diff --git a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp index e9e68bc0e949..69129df1f16b 100644 --- a/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp +++ b/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp @@ -257,7 +257,7 @@ ABISysV_hexagon::PrepareTrivialCall ( Thread &thread, sp -= argSize; // write this argument onto the stack of the host process - proc.get( )->WriteMemory( sp, arg.data, arg.size, error ); + proc.get( )->WriteMemory( sp, arg.data_ap.get(), arg.size, error ); if ( error.Fail( ) ) return false; diff --git a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp index bbafcf73fa16..2308129b8cab 100644 --- a/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp +++ b/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp @@ -168,6 +168,9 @@ DynamicLoaderHexagonDYLD::DidAttach() // Disable JIT for hexagon targets because its not supported m_process->SetCanJIT(false); + // Enable Interpreting of function call expressions + m_process->SetCanInterpretFunctionCalls(true); + // Add the current executable to the module list ModuleList module_list; module_list.Append(executable); @@ -500,7 +503,7 @@ DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop if (sym == NULL || !sym->IsTrampoline()) return thread_plan_sp; - const ConstString &sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled); + const ConstString sym_name = sym->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled); if (!sym_name) return thread_plan_sp; diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 6330b42ca14a..8724fc039cb9 100644 --- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -458,7 +458,7 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop) if (sym == NULL || !sym->IsTrampoline()) return thread_plan_sp; - const ConstString &sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled); + ConstString sym_name = sym->GetName(); if (!sym_name) return thread_plan_sp; @@ -667,7 +667,9 @@ DynamicLoaderPOSIXDYLD::ResolveExecutableModule (lldb::ModuleSP &module_sp) if (module_sp && module_sp->MatchesModuleSpec (module_spec)) return; - auto error = platform_sp->ResolveExecutable (module_spec, module_sp, nullptr); + const auto executable_search_paths (Target::GetDefaultExecutableSearchPaths()); + auto error = platform_sp->ResolveExecutable ( + module_spec, module_sp, !executable_search_paths.IsEmpty() ? &executable_search_paths : nullptr); if (error.Fail ()) { StreamString stream; diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp new file mode 100644 index 000000000000..56b56ab3a194 --- /dev/null +++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp @@ -0,0 +1,102 @@ +//===-- DynamicLoaderWindowsDYLD.cpp --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DynamicLoaderWindowsDYLD.h" + +#include "lldb/Core/PluginManager.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" + +#include "llvm/ADT/Triple.h" + +using namespace lldb; +using namespace lldb_private; + +DynamicLoaderWindowsDYLD::DynamicLoaderWindowsDYLD(Process *process) + : DynamicLoader(process) +{ + +} + +DynamicLoaderWindowsDYLD::~DynamicLoaderWindowsDYLD() +{ + +} + +void DynamicLoaderWindowsDYLD::Initialize() +{ + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), + CreateInstance); +} + +void DynamicLoaderWindowsDYLD::Terminate() +{ + +} + +ConstString DynamicLoaderWindowsDYLD::GetPluginNameStatic() +{ + static ConstString g_plugin_name("windows-dyld"); + return g_plugin_name; +} + +const char *DynamicLoaderWindowsDYLD::GetPluginDescriptionStatic() +{ + return "Dynamic loader plug-in that watches for shared library " + "loads/unloads in Windows processes."; +} + + +DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process, bool force) +{ + bool should_create = force; + if (!should_create) + { + const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple(); + if (triple_ref.getOS() == llvm::Triple::Win32) + should_create = true; + } + + if (should_create) + return new DynamicLoaderWindowsDYLD (process); + + return nullptr; +} + +void DynamicLoaderWindowsDYLD::DidAttach() +{ + +} + +void DynamicLoaderWindowsDYLD::DidLaunch() +{ + +} + +Error DynamicLoaderWindowsDYLD::CanLoadImage() +{ + return Error(); +} + +ConstString DynamicLoaderWindowsDYLD::GetPluginName() +{ + return GetPluginNameStatic(); +} + +uint32_t DynamicLoaderWindowsDYLD::GetPluginVersion() +{ + return 1; +} + +ThreadPlanSP +DynamicLoaderWindowsDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop) +{ + return ThreadPlanSP(); +} diff --git a/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h new file mode 100644 index 000000000000..d12b999f4627 --- /dev/null +++ b/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h @@ -0,0 +1,43 @@ +//===-- DynamicLoaderWindowsDYLDh ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_H_ +#define liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_H_ + +#include "lldb/lldb-forward.h" +#include "lldb/Target/DynamicLoader.h" + +namespace lldb_private +{ + +class DynamicLoaderWindowsDYLD : public DynamicLoader +{ + public: + DynamicLoaderWindowsDYLD(Process *process); + virtual ~DynamicLoaderWindowsDYLD(); + + static void Initialize(); + static void Terminate(); + static ConstString GetPluginNameStatic(); + static const char *GetPluginDescriptionStatic(); + + static DynamicLoader *CreateInstance(Process *process, bool force); + + void DidAttach () override; + void DidLaunch () override; + Error CanLoadImage () override; + lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, bool stop) override; + + ConstString GetPluginName() override; + uint32_t GetPluginVersion() override; +}; + +} + +#endif diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index 7d21b779ebd2..3a3878ef09a1 100644 --- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -106,7 +106,7 @@ ItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, Symbol *symbol = sc.symbol; if (symbol != NULL) { - const char *name = symbol->GetMangled().GetDemangledName().AsCString(); + const char *name = symbol->GetMangled().GetDemangledName(lldb::eLanguageTypeC_plus_plus).AsCString(); if (name && strstr(name, vtable_demangled_prefix) == name) { Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index f9cec2415382..5fc83f06157c 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1558,7 +1558,7 @@ ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id) std::string ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const { - size_t pos = symbol_name.find("@"); + size_t pos = symbol_name.find('@'); return symbol_name.substr(0, pos).str(); } @@ -1795,7 +1795,16 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, static ConstString bss_section_name(".bss"); static ConstString opd_section_name(".opd"); // For ppc64 - //StreamFile strm(stdout, false); + // On Android the oatdata and the oatexec symbols in system@framework@boot.oat covers the full + // .text section what causes issues with displaying unusable symbol name to the user and very + // slow unwinding speed because the instruction emulation based unwind plans try to emulate all + // instructions in these symbols. Don't add these symbols to the symbol list as they have no + // use for the debugger and they are causing a lot of trouble. + // Filtering can't be restricted to Android because this special object file don't contain the + // note section specifying the environment to Android but the custom extension and file name + // makes it highly unlikely that this will collide with anything else. + bool skip_oatdata_oatexec = m_file.GetFilename() == ConstString("system@framework@boot.oat"); + unsigned i; for (i = 0; i < num_symbols; ++i) { @@ -1809,7 +1818,10 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, (symbol_name == NULL || symbol_name[0] == '\0')) continue; - //symbol.Dump (&strm, i, &strtab_data, section_list); + // Skipping oatdata and oatexec sections if it is requested. See details above the + // definition of skip_oatdata_oatexec for the reasons. + if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 || ::strcmp(symbol_name, "oatexec") == 0)) + continue; SectionSP symbol_section_sp; SymbolType symbol_type = eSymbolTypeInvalid; @@ -2031,8 +2043,9 @@ ObjectFileELF::ParseSymbols (Symtab *symtab, if (! mangled_name.empty()) mangled.SetMangledName( ConstString((mangled_name + suffix).str()) ); - llvm::StringRef demangled_name = mangled.GetDemangledName().GetStringRef(); - if (! demangled_name.empty()) + ConstString demangled = mangled.GetDemangledName(lldb::eLanguageTypeUnknown); + llvm::StringRef demangled_name = demangled.GetStringRef(); + if (!demangled_name.empty()) mangled.SetDemangledName( ConstString((demangled_name + suffix).str()) ); } diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp index fe425e02103b..b4f841a16dec 100644 --- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -535,6 +535,14 @@ PlatformPOSIX::CalculateMD5 (const FileSpec& file_spec, return false; } +const lldb::UnixSignalsSP & +PlatformPOSIX::GetRemoteUnixSignals() { + if (IsRemote() && m_remote_platform_sp) + return m_remote_platform_sp->GetRemoteUnixSignals(); + return Platform::GetRemoteUnixSignals(); +} + + FileSpec PlatformPOSIX::GetRemoteWorkingDirectory() { @@ -785,9 +793,6 @@ PlatformPOSIX::Attach (ProcessAttachInfo &attach_info, if (process_sp) { - // Set UnixSignals appropriately. - process_sp->SetUnixSignals (Host::GetUnixSignals ()); - auto listener_sp = attach_info.GetHijackListener(); if (listener_sp == nullptr) { diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/source/Plugins/Platform/POSIX/PlatformPOSIX.h index 19a3f0c4eef1..82686dcef6b0 100644 --- a/source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.h @@ -109,6 +109,9 @@ public: lldb_private::ArchSpec GetRemoteSystemArchitecture () override; + const lldb::UnixSignalsSP & + GetRemoteUnixSignals() override; + size_t GetEnvironment (lldb_private::StringList &environment) override; diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index df0484c4e69b..b0e75d4f3457 100644 --- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -32,6 +32,8 @@ #include "Utility/UriParser.h" +#include "Plugins/Process/Utility/GDBRemoteSignals.h" + using namespace lldb; using namespace lldb_private; using namespace lldb_private::platform_gdb_server; @@ -139,13 +141,14 @@ PlatformRemoteGDBServer::ResolveExecutable (const ModuleSpec &module_spec, // Resolve any executable within an apk on Android? //Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); - if (resolved_module_spec.GetFileSpec().Exists()) + if (resolved_module_spec.GetFileSpec().Exists() || + module_spec.GetUUID().IsValid()) { if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) { error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, - NULL, + module_search_paths_ptr, NULL, NULL); @@ -161,7 +164,7 @@ PlatformRemoteGDBServer::ResolveExecutable (const ModuleSpec &module_spec, { error = ModuleList::GetSharedModule (resolved_module_spec, exe_module_sp, - NULL, + module_search_paths_ptr, NULL, NULL); // Did we find an executable using one of the @@ -413,6 +416,7 @@ PlatformRemoteGDBServer::DisconnectRemote () { Error error; m_gdb_client.Disconnect(&error); + m_remote_signals_sp.reset(); return error; } @@ -871,6 +875,97 @@ PlatformRemoteGDBServer::RunShellCommand(const char *command, // Shoul void PlatformRemoteGDBServer::CalculateTrapHandlerSymbolNames () -{ +{ m_trap_handlers.push_back (ConstString ("_sigtramp")); } + +const UnixSignalsSP & +PlatformRemoteGDBServer::GetRemoteUnixSignals() +{ + if (!IsConnected()) + return Platform::GetRemoteUnixSignals(); + + if (m_remote_signals_sp) + return m_remote_signals_sp; + + // If packet not implemented or JSON failed to parse, + // we'll guess the signal set based on the remote architecture. + m_remote_signals_sp = UnixSignals::Create(GetRemoteSystemArchitecture()); + + const char packet[] = "jSignalsInfo"; + StringExtractorGDBRemote response; + auto result = m_gdb_client.SendPacketAndWaitForResponse( + packet, strlen(packet), response, false); + + if (result != decltype(result)::Success || + response.GetResponseType() != response.eResponse) + return m_remote_signals_sp; + + auto object_sp = StructuredData::ParseJSON(response.GetStringRef()); + if (!object_sp || !object_sp->IsValid()) + return m_remote_signals_sp; + + auto array_sp = object_sp->GetAsArray(); + if (!array_sp || !array_sp->IsValid()) + return m_remote_signals_sp; + + auto remote_signals_sp = std::make_shared<lldb_private::GDBRemoteSignals>(); + + bool done = array_sp->ForEach( + [&remote_signals_sp](StructuredData::Object *object) -> bool + { + if (!object || !object->IsValid()) + return false; + + auto dict = object->GetAsDictionary(); + if (!dict || !dict->IsValid()) + return false; + + // Signal number and signal name are required. + int signo; + if (!dict->GetValueForKeyAsInteger("signo", signo)) + return false; + + std::string name; + if (!dict->GetValueForKeyAsString("name", name)) + return false; + + // We can live without short_name, description, etc. + std::string short_name{""}; + auto object_sp = dict->GetValueForKey("short_name"); + if (object_sp && object_sp->IsValid()) + short_name = object_sp->GetStringValue(); + + bool suppress{false}; + object_sp = dict->GetValueForKey("suppress"); + if (object_sp && object_sp->IsValid()) + suppress = object_sp->GetBooleanValue(); + + bool stop{false}; + object_sp = dict->GetValueForKey("stop"); + if (object_sp && object_sp->IsValid()) + stop = object_sp->GetBooleanValue(); + + bool notify{false}; + object_sp = dict->GetValueForKey("notify"); + if (object_sp && object_sp->IsValid()) + notify = object_sp->GetBooleanValue(); + + std::string description{""}; + object_sp = dict->GetValueForKey("description"); + if (object_sp && object_sp->IsValid()) + description = object_sp->GetStringValue(); + + remote_signals_sp->AddSignal(signo, + name.c_str(), + short_name.c_str(), + suppress, stop, notify, + description.c_str()); + return true; + }); + + if (done) + m_remote_signals_sp = std::move(remote_signals_sp); + + return m_remote_signals_sp; +} diff --git a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h index 1d97b4dbc683..0bf013fdfb68 100644 --- a/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ b/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -18,6 +18,7 @@ // Project includes #include "lldb/Target/Platform.h" #include "../../Process/gdb-remote/GDBRemoteCommunicationClient.h" +#include "Plugins/Process/Utility/GDBRemoteSignals.h" namespace lldb_private { namespace platform_gdb_server { @@ -213,12 +214,17 @@ public: void CalculateTrapHandlerSymbolNames () override; + const lldb::UnixSignalsSP & + GetRemoteUnixSignals() override; + protected: process_gdb_remote::GDBRemoteCommunicationClient m_gdb_client; std::string m_platform_description; // After we connect we can get a more complete description of what we are connected to std::string m_platform_scheme; std::string m_platform_hostname; + lldb::UnixSignalsSP m_remote_signals_sp; + // Launch the lldb-gdbserver on the remote host and return the port it is listening on or 0 on // failure. Subclasses should override this method if they want to do extra actions before or // after launching the lldb-gdbserver. diff --git a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp index cce7a1ef28c1..5e46c836beac 100644 --- a/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp +++ b/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp @@ -46,7 +46,7 @@ FreeBSDThread::WillResume(lldb::StateType resume_state) ProcessSP process_sp(GetProcess()); ProcessFreeBSD *process = static_cast<ProcessFreeBSD *>(process_sp.get()); int signo = GetResumeSignal(); - bool signo_valid = process->GetUnixSignals().SignalIsValid(signo); + bool signo_valid = process->GetUnixSignals()->SignalIsValid(signo); switch (resume_state) { diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index 28bca0916148..427c66ce3e6b 100644 --- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -1297,7 +1297,7 @@ ProcessMonitor::MonitorSignal(ProcessMonitor *monitor, if (log) log->Printf ("ProcessMonitor::%s() received signal %s with code %s, pid = %d", __FUNCTION__, - monitor->m_process->GetUnixSignals().GetSignalAsCString (signo), + monitor->m_process->GetUnixSignals()->GetSignalAsCString (signo), "SI_USER", info->si_pid); if (info->si_pid == getpid()) @@ -1307,7 +1307,7 @@ ProcessMonitor::MonitorSignal(ProcessMonitor *monitor, } if (log) - log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals().GetSignalAsCString (signo)); + log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals()->GetSignalAsCString (signo)); switch (signo) { @@ -1483,7 +1483,7 @@ ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo) Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS)); if (log) { - const char *signame = m_process->GetUnixSignals().GetSignalAsCString (signo); + const char *signame = m_process->GetUnixSignals()->GetSignalAsCString (signo); if (signame == nullptr) signame = "<none>"; log->Printf("ProcessMonitor::%s() resuming pid %" PRIu64 " with signal %s", diff --git a/source/Plugins/Process/FreeBSD/ProcessPOSIX.h b/source/Plugins/Process/FreeBSD/ProcessPOSIX.h index 70694cb9b193..627017c547dc 100644 --- a/source/Plugins/Process/FreeBSD/ProcessPOSIX.h +++ b/source/Plugins/Process/FreeBSD/ProcessPOSIX.h @@ -33,7 +33,7 @@ public: //------------------------------------------------------------------ ProcessPOSIX(lldb_private::Target& target, lldb_private::Listener &listener, - lldb_private::UnixSignalsSP &unix_signals_sp); + lldb::UnixSignalsSP &unix_signals_sp); virtual ~ProcessPOSIX(); diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/source/Plugins/Process/Utility/FreeBSDSignals.cpp index f082e143059c..c143d36e87c7 100644 --- a/source/Plugins/Process/Utility/FreeBSDSignals.cpp +++ b/source/Plugins/Process/Utility/FreeBSDSignals.cpp @@ -13,6 +13,8 @@ // Project includes #include "FreeBSDSignals.h" +using namespace lldb_private; + FreeBSDSignals::FreeBSDSignals() : UnixSignals() { diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.h b/source/Plugins/Process/Utility/FreeBSDSignals.h index 1e14ccb9fc4d..b715c62c81e9 100644 --- a/source/Plugins/Process/Utility/FreeBSDSignals.h +++ b/source/Plugins/Process/Utility/FreeBSDSignals.h @@ -13,16 +13,19 @@ // Project includes #include "lldb/Target/UnixSignals.h" +namespace lldb_private { + /// FreeBSD specific set of Unix signals. -class FreeBSDSignals - : public lldb_private::UnixSignals +class FreeBSDSignals : public UnixSignals { public: FreeBSDSignals(); private: void - Reset(); + Reset() override; }; +} // namespace lldb_private + #endif // liblldb_FreeBSDSignals_H_ diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp new file mode 100644 index 000000000000..4e355c63b3aa --- /dev/null +++ b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp @@ -0,0 +1,32 @@ +//===-- GDBRemoteSignals.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "GDBRemoteSignals.h" + +using namespace lldb_private; + +GDBRemoteSignals::GDBRemoteSignals() + : UnixSignals() +{ + Reset(); +} + +GDBRemoteSignals::GDBRemoteSignals(const lldb::UnixSignalsSP &rhs) + : UnixSignals(*rhs) +{ +} + +void +GDBRemoteSignals::Reset() +{ + m_signals.clear(); +} diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.h b/source/Plugins/Process/Utility/GDBRemoteSignals.h new file mode 100644 index 000000000000..bbb631a14090 --- /dev/null +++ b/source/Plugins/Process/Utility/GDBRemoteSignals.h @@ -0,0 +1,36 @@ +//===-- GDBRemoteSignals.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_GDBRemoteSignals_H_ +#define liblldb_GDBRemoteSignals_H_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Target/UnixSignals.h" + +namespace lldb_private { + +/// Empty set of Unix signals to be filled by PlatformRemoteGDBServer +class GDBRemoteSignals : public UnixSignals +{ +public: + GDBRemoteSignals(); + + GDBRemoteSignals(const lldb::UnixSignalsSP &rhs); + +private: + void + Reset() override; +}; + +} // namespace lldb_private + +#endif // liblldb_GDBRemoteSignals_H_ diff --git a/source/Plugins/Process/Utility/LinuxSignals.cpp b/source/Plugins/Process/Utility/LinuxSignals.cpp index 0680d268233c..cd1fc8165eb9 100644 --- a/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -12,7 +12,7 @@ // Project includes #include "LinuxSignals.h" -using namespace lldb_private::process_linux; +using namespace lldb_private; LinuxSignals::LinuxSignals() : UnixSignals() diff --git a/source/Plugins/Process/Utility/LinuxSignals.h b/source/Plugins/Process/Utility/LinuxSignals.h index 5102bcb95e74..dd9062f040a2 100644 --- a/source/Plugins/Process/Utility/LinuxSignals.h +++ b/source/Plugins/Process/Utility/LinuxSignals.h @@ -17,21 +17,18 @@ #include "lldb/Target/UnixSignals.h" namespace lldb_private { -namespace process_linux { - /// Linux specific set of Unix signals. - class LinuxSignals - : public lldb_private::UnixSignals - { - public: - LinuxSignals(); +/// Linux specific set of Unix signals. +class LinuxSignals : public UnixSignals +{ +public: + LinuxSignals(); - private: - void - Reset(); - }; +private: + void + Reset() override; +}; } // namespace lldb_private -} // namespace process_linux -#endif +#endif // liblldb_LinuxSignals_H_ diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp index e4e654626eaa..1dc0be81c0ae 100644 --- a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp +++ b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp @@ -12,7 +12,7 @@ // Project includes #include "MipsLinuxSignals.h" -using namespace lldb_private::process_linux; +using namespace lldb_private; MipsLinuxSignals::MipsLinuxSignals() : UnixSignals() diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.h b/source/Plugins/Process/Utility/MipsLinuxSignals.h index 2e603fbbdf3c..a5041b50eea3 100644 --- a/source/Plugins/Process/Utility/MipsLinuxSignals.h +++ b/source/Plugins/Process/Utility/MipsLinuxSignals.h @@ -17,21 +17,18 @@ #include "lldb/Target/UnixSignals.h" namespace lldb_private { -namespace process_linux { - /// Linux specific set of Unix signals. - class MipsLinuxSignals - : public lldb_private::UnixSignals - { - public: - MipsLinuxSignals(); +/// Linux specific set of Unix signals. +class MipsLinuxSignals : public UnixSignals +{ +public: + MipsLinuxSignals(); - private: - void - Reset(); - }; +private: + void + Reset() override; +}; } // namespace lldb_private -} // namespace process_linux -#endif +#endif // liblldb_MipsLinuxSignals_H_ diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp index 02d3ecd7b3c5..1cdae9011673 100644 --- a/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -120,29 +120,28 @@ unwind_done: return false; } -// For adding a non-zero stack frame to m_frames. -bool -UnwindLLDB::AddOneMoreFrame (ABI *abi) +UnwindLLDB::CursorSP +UnwindLLDB::GetOneMoreFrame (ABI* abi) { + assert (m_frames.size() != 0 && "Get one more frame called with empty frame list"); + // If we've already gotten to the end of the stack, don't bother to try again... if (m_unwind_complete) - return false; + return nullptr; Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - CursorSP cursor_sp(new Cursor ()); - // Frame zero is a little different - if (m_frames.size() == 0) - return false; + CursorSP prev_frame = m_frames.back(); + uint32_t cur_idx = m_frames.size(); - uint32_t cur_idx = m_frames.size (); + CursorSP cursor_sp(new Cursor ()); RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB (m_thread, - m_frames[cur_idx - 1]->reg_ctx_lldb_sp, + prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this)); - // We want to detect an unwind that cycles erronously and stop backtracing. + // We want to detect an unwind that cycles erroneously and stop backtracing. // Don't want this maximum unwind limit to be too low -- if you have a backtrace // with an "infinitely recursing" bug, it will crash when the stack blows out // and the first 35,000 frames are uninteresting - it's the top most 5 frames that @@ -154,21 +153,20 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) if (log) log->Printf ("%*sFrame %d unwound too many frames, assuming unwind has gone astray, stopping.", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - goto unwind_done; + return nullptr; } if (reg_ctx_sp.get() == NULL) { // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) log->Printf ("%*sFrame %d did not get a RegisterContext, stopping.", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - goto unwind_done; + return nullptr; } if (!reg_ctx_sp->IsValid()) @@ -176,31 +174,25 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) // We failed to get a valid RegisterContext. // See if the regctx below this on the stack has a fallback unwind plan it can use. // Subsequent calls to TryFallbackUnwindPlan() will return false. - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) - { log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; + return nullptr; } if (!reg_ctx_sp->GetCFA (cursor_sp->cfa)) { // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) - { log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; + return nullptr; } if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { @@ -219,24 +211,19 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) || reg_ctx_sp->GetCFA (cursor_sp->cfa) == false || abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) { - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) - { log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; + return nullptr; } else { if (log) - { log->Printf("%*sFrame %d had a bad CFA value but we switched the UnwindPlan being used and got one that looks more realistic.", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } } } } @@ -244,54 +231,103 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi) { // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) - { log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; + return nullptr; } if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc)) { // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return // true. Subsequent calls to TryFallbackUnwindPlan() will return false. - if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) - { - return AddOneMoreFrame (abi); - } + if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + return GetOneMoreFrame (abi); + if (log) - { log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk", cur_idx < 100 ? cur_idx : 100, "", cur_idx); - } - goto unwind_done; + return nullptr; } - if (!m_frames.empty()) + // Infinite loop where the current cursor is the same as the previous one... + if (prev_frame->start_pc == cursor_sp->start_pc && prev_frame->cfa == cursor_sp->cfa) { - // Infinite loop where the current cursor is the same as the previous one... - if (m_frames.back()->start_pc == cursor_sp->start_pc && m_frames.back()->cfa == cursor_sp->cfa) - { - if (log) - log->Printf ("th%d pc of this frame is the same as the previous frame and CFAs for both frames are identical -- stopping unwind", m_thread.GetIndexID()); - goto unwind_done; - } + if (log) + log->Printf ("th%d pc of this frame is the same as the previous frame and CFAs for both frames are identical -- stopping unwind", m_thread.GetIndexID()); + return nullptr; } cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; - m_frames.push_back (cursor_sp); - return true; - -unwind_done: - if (log) + return cursor_sp; +} + +bool +UnwindLLDB::AddOneMoreFrame (ABI *abi) +{ + Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); + + // Frame zero is a little different + if (m_frames.empty()) + return false; + + // If we've already gotten to the end of the stack, don't bother to try again... + if (m_unwind_complete) + return false; + + CursorSP new_frame = m_candidate_frame; + if (new_frame == nullptr) + new_frame = GetOneMoreFrame(abi); + + if (new_frame == nullptr) { - log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID()); + if (log) + log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID()); + m_unwind_complete = true; + return false; } - m_unwind_complete = true; - return false; + + m_frames.push_back(new_frame); + + // If we can get one more frame further then accept that we get back a correct frame. + m_candidate_frame = GetOneMoreFrame(abi); + if (m_candidate_frame) + return true; + + // We can't go further from the frame returned by GetOneMore frame. Lets try to get a + // different frame with using the fallback unwind plan. + if (!m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) + { + // We don't have a valid fallback unwind plan. Accept the frame as it is. This is a + // valid situation when we are at the bottom of the stack. + return true; + } + + // Remove the possibly incorrect frame from the frame list and try to add a different one with + // the newly selected fallback unwind plan. + m_frames.pop_back(); + CursorSP new_frame_v2 = GetOneMoreFrame(abi); + if (new_frame_v2 == nullptr) + { + // We haven't got a new frame from the fallback unwind plan. Accept the frame from the + // original unwind plan. This is a valid situation when we are at the bottom of the stack. + m_frames.push_back(new_frame); + return true; + } + + // Push the new frame to the list and try to continue from this frame. If we can get a new frame + // then accept it as the correct one. + m_frames.push_back(new_frame_v2); + m_candidate_frame = GetOneMoreFrame(abi); + if (m_candidate_frame) + return true; + + // The new frame isn't helped in unwinding. Fall back to the original one as the default unwind + // plan is usually more reliable then the fallback one. + m_frames.pop_back(); + m_frames.push_back(new_frame); + return true; } bool diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h index 35d85e2e3d26..ce897cd82423 100644 --- a/source/Plugins/Process/Utility/UnwindLLDB.h +++ b/source/Plugins/Process/Utility/UnwindLLDB.h @@ -65,6 +65,7 @@ protected: DoClear() { m_frames.clear(); + m_candidate_frame.reset(); m_unwind_complete = false; } @@ -126,14 +127,21 @@ private: typedef std::shared_ptr<Cursor> CursorSP; std::vector<CursorSP> m_frames; + CursorSP m_candidate_frame; bool m_unwind_complete; // If this is true, we've enumerated all the frames in the stack, and m_frames.size() is the // number of frames, etc. Otherwise we've only gone as far as directly asked, and m_frames.size() // is how far we've currently gone. std::vector<ConstString> m_user_supplied_trap_handler_functions; - bool AddOneMoreFrame (ABI *abi); - bool AddFirstFrame (); + CursorSP + GetOneMoreFrame (ABI* abi); + + bool + AddOneMoreFrame (ABI *abi); + + bool + AddFirstFrame (); //------------------------------------------------------------------ // For UnwindLLDB only diff --git a/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 2fff36dd4ee5..bf5cad8e39c5 100644 --- a/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -29,8 +29,6 @@ #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" #include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h" -#include "Plugins/Process/Utility/FreeBSDSignals.h" -#include "Plugins/Process/Utility/LinuxSignals.h" // Project includes #include "ProcessElfCore.h" @@ -237,23 +235,7 @@ ProcessElfCore::DoLoadCore () if (arch.IsValid()) m_target.SetArchitecture(arch); - switch (m_os) - { - case llvm::Triple::FreeBSD: - { - static UnixSignalsSP s_freebsd_signals_sp(new FreeBSDSignals ()); - SetUnixSignals(s_freebsd_signals_sp); - break; - } - case llvm::Triple::Linux: - { - static UnixSignalsSP s_linux_signals_sp(new process_linux::LinuxSignals ()); - SetUnixSignals(s_linux_signals_sp); - break; - } - default: - break; - } + SetUnixSignals(UnixSignals::Create(GetArchitecture())); return error; } @@ -370,7 +352,7 @@ ProcessElfCore::Clear() m_thread_list.Clear(); m_os = llvm::Triple::UnknownOS; - static UnixSignalsSP s_default_unix_signals_sp(new UnixSignals()); + static const auto s_default_unix_signals_sp = std::make_shared<UnixSignals>(); SetUnixSignals(s_default_unix_signals_sp); } diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 1af3947a75f3..9c263c8c4087 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -564,8 +564,12 @@ GDBRemoteCommunication::DecompressPacket () return true; size_t pkt_size = m_bytes.size(); - if (pkt_size < 6) + + // Smallest possible compressed packet is $N#00 - an uncompressed empty reply, most commonly indicating + // an unsupported packet. Anything less than 5 characters, it's definitely not a compressed packet. + if (pkt_size < 5) return true; + if (m_bytes[0] != '$' && m_bytes[0] != '%') return true; if (m_bytes[1] != 'C' && m_bytes[1] != 'N') diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index ae0a2f5e66c5..2a253c5a99e8 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -87,6 +87,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() : m_supports_qXfer_features_read (eLazyBoolCalculate), m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate), m_supports_jThreadExtendedInfo (eLazyBoolCalculate), + m_supports_jLoadedDynamicLibrariesInfos (eLazyBoolCalculate), m_supports_qProcessInfoPID (true), m_supports_qfProcessInfo (true), m_supports_qUserName (true), @@ -654,6 +655,24 @@ GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported () } bool +GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported () +{ + if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) + { + StringExtractorGDBRemote response; + m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolNo; + if (SendPacketAndWaitForResponse("jGetLoadedDynamicLibrariesInfos:", response, false) == PacketResult::Success) + { + if (response.IsOKResponse()) + { + m_supports_jLoadedDynamicLibrariesInfos = eLazyBoolYes; + } + } + } + return m_supports_jLoadedDynamicLibrariesInfos; +} + +bool GDBRemoteCommunicationClient::GetxPacketSupported () { if (m_supports_x == eLazyBoolCalculate) @@ -1037,8 +1056,8 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse // may change if we are interrupted and we continue after an async packet... std::string continue_packet(payload, packet_length); - const auto sigstop_signo = process->GetUnixSignals().GetSignalNumberFromName("SIGSTOP"); - const auto sigint_signo = process->GetUnixSignals().GetSignalNumberFromName("SIGINT"); + const auto sigstop_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGSTOP"); + const auto sigint_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGINT"); bool got_async_packet = false; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 65a2981018ea..deb41b066b45 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -550,6 +550,9 @@ public: GetThreadExtendedInfoSupported(); bool + GetLoadedDynamicLibrariesInfosSupported(); + + bool GetModuleInfo (const FileSpec& module_file_spec, const ArchSpec& arch_spec, ModuleSpec &module_spec); @@ -614,6 +617,7 @@ protected: LazyBool m_supports_qXfer_features_read; LazyBool m_supports_augmented_libraries_svr4_read; LazyBool m_supports_jThreadExtendedInfo; + LazyBool m_supports_jLoadedDynamicLibrariesInfos; bool m_supports_qProcessInfoPID:1, diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 13ce9b2dc5c3..4ee66b84d474 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -132,7 +132,7 @@ GDBRemoteCommunicationServer::SendOKResponse () } bool -GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr) +GDBRemoteCommunicationServer::HandshakeWithClient() { return GetAck() == PacketResult::Success; } diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index 992c6dffaf54..44c0f6a32f5b 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -54,7 +54,7 @@ public: // After connecting, do a little handshake with the client to make sure // we are at least communicating bool - HandshakeWithClient (Error *error_ptr); + HandshakeWithClient (); protected: std::map<StringExtractorGDBRemote::ServerPacketType, PacketHandler> m_packet_handlers; diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index e8955ddbd6e4..c4523252f190 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -75,10 +75,11 @@ namespace // GDBRemoteCommunicationServerLLGS constructor //---------------------------------------------------------------------- GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( - const lldb::PlatformSP& platform_sp) : + const lldb::PlatformSP& platform_sp, + MainLoop &mainloop) : GDBRemoteCommunicationServerCommon ("gdb-remote.server", "gdb-remote.server.rx_packet"), m_platform_sp (platform_sp), - m_async_thread (LLDB_INVALID_HOST_THREAD), + m_mainloop (mainloop), m_current_tid (LLDB_INVALID_THREAD_ID), m_continue_tid (LLDB_INVALID_THREAD_ID), m_debugged_process_mutex (Mutex::eMutexTypeRecursive), @@ -88,7 +89,8 @@ GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( m_active_auxv_buffer_sp (), m_saved_registers_mutex (), m_saved_registers_map (), - m_next_saved_registers_id (1) + m_next_saved_registers_id (1), + m_handshake_completed (false) { assert(platform_sp); RegisterPacketHandlers(); @@ -218,7 +220,7 @@ GDBRemoteCommunicationServerLLGS::LaunchProcess () { Mutex::Locker locker (m_debugged_process_mutex); assert (!m_debugged_process_sp && "lldb-gdbserver creating debugged process but one already exists"); - error = m_platform_sp->LaunchNativeProcess ( + error = NativeProcessProtocol::Launch( m_process_launch_info, *this, m_debugged_process_sp); @@ -306,7 +308,7 @@ GDBRemoteCommunicationServerLLGS::AttachToProcess (lldb::pid_t pid) } // Try to attach. - error = m_platform_sp->AttachNativeProcess (pid, *this, m_debugged_process_sp); + error = NativeProcessProtocol::Attach(pid, *this, m_debugged_process_sp); if (!error.Success ()) { fprintf (stderr, "%s: failed to attach to process %" PRIu64 ": %s", __FUNCTION__, pid, error.AsCString ()); @@ -782,6 +784,58 @@ GDBRemoteCommunicationServerLLGS::DidExec (NativeProcessProtocol *process) ClearProcessSpecificData (); } +void +GDBRemoteCommunicationServerLLGS::DataAvailableCallback () +{ + Log *log (GetLogIfAnyCategoriesSet(GDBR_LOG_COMM)); + + if (! m_handshake_completed) + { + if (! HandshakeWithClient()) + { + if(log) + log->Printf("GDBRemoteCommunicationServerLLGS::%s handshake with client failed, exiting", + __FUNCTION__); + m_read_handle_up.reset(); + m_mainloop.RequestTermination(); + return; + } + m_handshake_completed = true; + } + + bool interrupt = false; + bool done = false; + Error error; + while (true) + { + const PacketResult result = GetPacketAndSendResponse (0, error, interrupt, done); + if (result == PacketResult::ErrorReplyTimeout) + break; // No more packets in the queue + + if ((result != PacketResult::Success)) + { + if(log) + log->Printf("GDBRemoteCommunicationServerLLGS::%s processing a packet failed: %s", + __FUNCTION__, error.AsCString()); + m_read_handle_up.reset(); + m_mainloop.RequestTermination(); + break; + } + } +} + +Error +GDBRemoteCommunicationServerLLGS::InitializeConnection (std::unique_ptr<Connection> &&connection) +{ + IOObjectSP read_object_sp = connection->GetReadObject(); + GDBRemoteCommunicationServer::SetConnection(connection.release()); + + Error error; + m_read_handle_up = m_mainloop.RegisterReadObject(read_object_sp, + [this] (MainLoopBase &) { DataAvailableCallback(); }, error); + return error; +} + GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::SendONotification (const char *buffer, uint32_t len) { diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index 1eda0b052bb7..29f3fdebcfb0 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -19,6 +19,7 @@ #include "lldb/Core/Communication.h" #include "lldb/Host/Mutex.h" #include "lldb/Host/common/NativeProcessProtocol.h" +#include "lldb/Host/MainLoop.h" // Project includes #include "GDBRemoteCommunicationServerCommon.h" @@ -26,6 +27,7 @@ class StringExtractorGDBRemote; namespace lldb_private { + namespace process_gdb_remote { class ProcessGDBRemote; @@ -38,7 +40,7 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - GDBRemoteCommunicationServerLLGS(const lldb::PlatformSP& platform_sp); + GDBRemoteCommunicationServerLLGS(const lldb::PlatformSP& platform_sp, MainLoop &mainloop); virtual ~GDBRemoteCommunicationServerLLGS(); @@ -111,9 +113,13 @@ public: void DidExec (NativeProcessProtocol *process) override; + Error + InitializeConnection (std::unique_ptr<Connection> &&connection); + protected: lldb::PlatformSP m_platform_sp; - lldb::thread_t m_async_thread; + MainLoop &m_mainloop; + MainLoop::ReadHandleUP m_read_handle_up; lldb::tid_t m_current_tid; lldb::tid_t m_continue_tid; Mutex m_debugged_process_mutex; @@ -124,6 +130,7 @@ protected: Mutex m_saved_registers_mutex; std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map; uint32_t m_next_saved_registers_id; + bool m_handshake_completed : 1; PacketResult SendONotification (const char *buffer, uint32_t len); @@ -295,6 +302,9 @@ private: void RegisterPacketHandlers (); + void + DataAvailableCallback (); + //------------------------------------------------------------------ // For GDBRemoteCommunicationServerLLGS only //------------------------------------------------------------------ diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index f5e5d76f2e6f..1205049db3fb 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -19,6 +19,7 @@ // Other libraries and framework includes #include "lldb/Core/Log.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Host/Config.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Host.h" @@ -26,6 +27,7 @@ #include "lldb/Target/FileAction.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" +#include "lldb/Target/UnixSignals.h" // Project includes #include "Utility/StringExtractorGDBRemote.h" @@ -54,6 +56,8 @@ GDBRemoteCommunicationServerPlatform::GDBRemoteCommunicationServerPlatform() : &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo); RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir, &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir); + RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jSignalsInfo, + &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo); RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt, [this](StringExtractorGDBRemote packet, @@ -251,6 +255,35 @@ GDBRemoteCommunicationServerPlatform::Handle_qC (StringExtractorGDBRemote &packe return SendPacketNoLock (response.GetData(), response.GetSize()); } +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(StringExtractorGDBRemote &packet) +{ + StructuredData::Array signal_array; + + const auto &signals = Host::GetUnixSignals(); + for (auto signo = signals->GetFirstSignalNumber(); + signo != LLDB_INVALID_SIGNAL_NUMBER; + signo = signals->GetNextSignalNumber(signo)) + { + auto dictionary = std::make_shared<StructuredData::Dictionary>(); + + dictionary->AddIntegerItem("signo", signo); + dictionary->AddStringItem("name", signals->GetSignalAsCString(signo)); + + bool suppress, stop, notify; + signals->GetSignalInfo(signo, suppress, stop, notify); + dictionary->AddBooleanItem("suppress", suppress); + dictionary->AddBooleanItem("stop", stop); + dictionary->AddBooleanItem("notify", notify); + + signal_array.Push(dictionary); + } + + StreamString response; + signal_array.Dump(response); + return SendPacketNoLock(response.GetData(), response.GetSize()); +} + bool GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped (lldb::pid_t pid) { diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h index 4124b0424f5d..5c011371a3eb 100644 --- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h +++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h @@ -79,6 +79,9 @@ protected: PacketResult Handle_qC (StringExtractorGDBRemote &packet); + PacketResult + Handle_jSignalsInfo(StringExtractorGDBRemote &packet); + private: bool DebugserverProcessReaped (lldb::pid_t pid); diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 5cb4da514a7f..0bcc8ca4e5e3 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -65,10 +65,8 @@ // Project includes #include "lldb/Host/Host.h" -#include "Plugins/Process/Utility/FreeBSDSignals.h" +#include "Plugins/Process/Utility/GDBRemoteSignals.h" #include "Plugins/Process/Utility/InferiorCallPOSIX.h" -#include "Plugins/Process/Utility/LinuxSignals.h" -#include "Plugins/Process/Utility/MipsLinuxSignals.h" #include "Plugins/Process/Utility/StopInfoMachException.h" #include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h" #include "Utility/StringExtractorGDBRemote.h" @@ -823,41 +821,8 @@ ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url) if (log) log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalized target architecture triple: %s", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str ()); - // Set the Unix signals properly for the target. - // FIXME Add a gdb-remote packet to discover dynamically. - if (error.Success ()) - { - const ArchSpec arch_spec = m_gdb_comm.GetHostArchitecture(); - if (arch_spec.IsValid ()) - { - if (log) - log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": determining unix signals type based on architecture %s, triple %s", __FUNCTION__, GetID (), arch_spec.GetArchitectureName () ? arch_spec.GetArchitectureName () : "<null>", arch_spec.GetTriple ().getTriple ().c_str ()); - - switch (arch_spec.GetTriple ().getOS ()) - { - case llvm::Triple::Linux: - if (arch_spec.GetTriple ().getArch () == llvm::Triple::mips64 || arch_spec.GetTriple ().getArch () == llvm::Triple::mips64el) - SetUnixSignals (UnixSignalsSP (new process_linux::MipsLinuxSignals ())); - else - SetUnixSignals (UnixSignalsSP (new process_linux::LinuxSignals ())); - if (log) - log->Printf ("ProcessGDBRemote::%s using Linux unix signals type for pid %" PRIu64, __FUNCTION__, GetID ()); - break; - case llvm::Triple::OpenBSD: - case llvm::Triple::FreeBSD: - case llvm::Triple::NetBSD: - SetUnixSignals (UnixSignalsSP (new FreeBSDSignals ())); - if (log) - log->Printf ("ProcessGDBRemote::%s using *BSD unix signals type for pid %" PRIu64, __FUNCTION__, GetID ()); - break; - default: - SetUnixSignals (UnixSignalsSP (new UnixSignals ())); - if (log) - log->Printf ("ProcessGDBRemote::%s using generic unix signals type for pid %" PRIu64, __FUNCTION__, GetID ()); - break; - } - } - } + if (error.Success()) + SetUnixSignals(std::make_shared<GDBRemoteSignals>(GetTarget().GetPlatform()->GetUnixSignals())); return error; } @@ -3524,7 +3489,7 @@ ProcessGDBRemote::MonitorDebugserverProcess char error_str[1024]; if (signo) { - const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo); + const char *signal_cstr = process->GetUnixSignals()->GetSignalAsCString(signo); if (signal_cstr) ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr); else @@ -3985,6 +3950,44 @@ ProcessGDBRemote::GetExtendedInfoForThread (lldb::tid_t tid) { if (!response.Empty()) { + object_sp = StructuredData::ParseJSON (response.GetStringRef()); + } + } + } + } + return object_sp; +} + +StructuredData::ObjectSP +ProcessGDBRemote::GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) +{ + StructuredData::ObjectSP object_sp; + + if (m_gdb_comm.GetLoadedDynamicLibrariesInfosSupported()) + { + StructuredData::ObjectSP args_dict(new StructuredData::Dictionary()); + args_dict->GetAsDictionary()->AddIntegerItem ("image_list_address", image_list_address); + args_dict->GetAsDictionary()->AddIntegerItem ("image_count", image_count); + + StreamString packet; + packet << "jGetLoadedDynamicLibrariesInfos:"; + args_dict->Dump (packet); + + // FIXME the final character of a JSON dictionary, '}', is the escape + // character in gdb-remote binary mode. lldb currently doesn't escape + // these characters in its packet output -- so we add the quoted version + // of the } character here manually in case we talk to a debugserver which + // un-escapes the characters at packet read time. + packet << (char) (0x7d ^ 0x20); + + StringExtractorGDBRemote response; + if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, false) == GDBRemoteCommunication::PacketResult::Success) + { + StringExtractorGDBRemote::ResponseType response_type = response.GetResponseType(); + if (response_type == StringExtractorGDBRemote::eResponse) + { + if (!response.Empty()) + { // The packet has already had the 0x7d xor quoting stripped out at the // GDBRemoteCommunication packet receive level. object_sp = StructuredData::ParseJSON (response.GetStringRef()); @@ -3995,6 +3998,7 @@ ProcessGDBRemote::GetExtendedInfoForThread (lldb::tid_t tid) return object_sp; } + // Establish the largest memory read/write payloads we should use. // If the remote stub has a max packet size, stay under that size. // @@ -4418,83 +4422,135 @@ ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list) GDBRemoteCommunicationClient & comm = m_gdb_comm; // check that we have extended feature read support - if (!comm.GetQXferLibrariesSVR4ReadSupported ()) - return Error (0, ErrorType::eErrorTypeGeneric); + if (comm.GetQXferLibrariesSVR4ReadSupported ()) { + list.clear (); - list.clear (); + // request the loaded library list + std::string raw; + lldb_private::Error lldberr; - // request the loaded library list - std::string raw; - lldb_private::Error lldberr; - if (!comm.ReadExtFeature (ConstString ("libraries-svr4"), ConstString (""), raw, lldberr)) - return Error (0, ErrorType::eErrorTypeGeneric); + if (!comm.ReadExtFeature (ConstString ("libraries-svr4"), ConstString (""), raw, lldberr)) + return Error (0, ErrorType::eErrorTypeGeneric); - // parse the xml file in memory - if (log) - log->Printf ("parsing: %s", raw.c_str()); - XMLDocument doc; - - if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) - return Error (0, ErrorType::eErrorTypeGeneric); + // parse the xml file in memory + if (log) + log->Printf ("parsing: %s", raw.c_str()); + XMLDocument doc; + + if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) + return Error (0, ErrorType::eErrorTypeGeneric); - XMLNode root_element = doc.GetRootElement("library-list-svr4"); - if (!root_element) - return Error(); + XMLNode root_element = doc.GetRootElement("library-list-svr4"); + if (!root_element) + return Error(); - // main link map structure - llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm"); - if (!main_lm.empty()) - { - list.m_link_map = StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0); - } + // main link map structure + llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm"); + if (!main_lm.empty()) + { + list.m_link_map = StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0); + } - root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool { + root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool { - GDBLoadedModuleInfoList::LoadedModuleInfo module; + GDBLoadedModuleInfoList::LoadedModuleInfo module; - library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { - - if (name == "name") - module.set_name (value.str()); - else if (name == "lm") - { - // the address of the link_map struct. - module.set_link_map(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); - } - else if (name == "l_addr") - { - // the displacement as read from the field 'l_addr' of the link_map struct. - module.set_base(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool { - } - else if (name == "l_ld") + if (name == "name") + module.set_name (value.str()); + else if (name == "lm") + { + // the address of the link_map struct. + module.set_link_map(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + } + else if (name == "l_addr") + { + // the displacement as read from the field 'l_addr' of the link_map struct. + module.set_base(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + + } + else if (name == "l_ld") + { + // the memory address of the libraries PT_DYAMIC section. + module.set_dynamic(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + } + + return true; // Keep iterating over all properties of "library" + }); + + if (log) { - // the memory address of the libraries PT_DYAMIC section. - module.set_dynamic(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0)); + std::string name; + lldb::addr_t lm=0, base=0, ld=0; + + module.get_name (name); + module.get_link_map (lm); + module.get_base (base); + module.get_dynamic (ld); + + log->Printf ("found (link_map:0x08%" PRIx64 ", base:0x08%" PRIx64 ", ld:0x08%" PRIx64 ", name:'%s')", lm, base, ld, name.c_str()); } - - return true; // Keep iterating over all properties of "library" + + list.add (module); + return true; // Keep iterating over all "library" elements in the root node }); if (log) - { - std::string name; - lldb::addr_t lm=0, base=0, ld=0; + log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size()); + } else if (comm.GetQXferLibrariesReadSupported ()) { + list.clear (); - module.get_name (name); - module.get_link_map (lm); - module.get_base (base); - module.get_dynamic (ld); + // request the loaded library list + std::string raw; + lldb_private::Error lldberr; - log->Printf ("found (link_map:0x08%" PRIx64 ", base:0x08%" PRIx64 ", ld:0x08%" PRIx64 ", name:'%s')", lm, base, ld, name.c_str()); - } + if (!comm.ReadExtFeature (ConstString ("libraries"), ConstString (""), raw, lldberr)) + return Error (0, ErrorType::eErrorTypeGeneric); - list.add (module); - return true; // Keep iterating over all "library" elements in the root node - }); + if (log) + log->Printf ("parsing: %s", raw.c_str()); + XMLDocument doc; - if (log) - log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size()); + if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml")) + return Error (0, ErrorType::eErrorTypeGeneric); + + XMLNode root_element = doc.GetRootElement("library-list"); + if (!root_element) + return Error(); + + root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool { + GDBLoadedModuleInfoList::LoadedModuleInfo module; + + llvm::StringRef name = library.GetAttributeValue("name"); + module.set_name(name.str()); + + // The base address of a given library will be the address of its + // first section. Most remotes send only one section for Windows + // targets for example. + const XMLNode §ion = library.FindFirstChildElementWithName("section"); + llvm::StringRef address = section.GetAttributeValue("address"); + module.set_base(StringConvert::ToUInt64(address.data(), LLDB_INVALID_ADDRESS, 0)); + + if (log) + { + std::string name; + lldb::addr_t base = 0; + module.get_name (name); + module.get_base (base); + + log->Printf ("found (base:0x%" PRIx64 ", name:'%s')", base, name.c_str()); + } + + list.add (module); + return true; // Keep iterating over all "library" elements in the root node + }); + + if (log) + log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size()); + } else { + return Error (0, ErrorType::eErrorTypeGeneric); + } return Error(); } diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 0a5e4a8a41b4..45c74ea64ee5 100644 --- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -27,11 +27,11 @@ #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Host/HostThread.h" #include "lldb/lldb-private-forward.h" +#include "lldb/Utility/StringExtractor.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "GDBRemoteCommunicationClient.h" -#include "Utility/StringExtractor.h" #include "GDBRemoteRegisterContext.h" namespace lldb_private { @@ -247,6 +247,9 @@ public: void ModulesDidLoad (ModuleList &module_list) override; + StructuredData::ObjectSP + GetLoadedDynamicLibrariesInfos (lldb::addr_t image_list_address, lldb::addr_t image_count) override; + protected: friend class ThreadGDBRemote; friend class GDBRemoteCommunicationClient; diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 59c701d75a68..d2a6503caf8e 100644 --- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -215,14 +215,14 @@ ThreadGDBRemote::WillResume (StateType resume_state) break; case eStateRunning: - if (gdb_process->GetUnixSignals().SignalIsValid (signo)) + if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo)); else gdb_process->m_continue_c_tids.push_back(tid); break; case eStateStepping: - if (gdb_process->GetUnixSignals().SignalIsValid (signo)) + if (gdb_process->GetUnixSignals()->SignalIsValid(signo)) gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo)); else gdb_process->m_continue_s_tids.push_back(tid); diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index 75934f966bcd..60933108c97a 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -669,6 +669,7 @@ DWARFCompileUnit::Index (const uint32_t cu_idx, GetOffset()); } + const LanguageType cu_language = GetLanguageType(); DWARFDebugInfoEntry::const_iterator pos; DWARFDebugInfoEntry::const_iterator begin = m_die_array.begin(); DWARFDebugInfoEntry::const_iterator end = m_die_array.end(); @@ -882,8 +883,9 @@ DWARFCompileUnit::Index (const uint32_t cu_idx, { Mangled mangled (ConstString(mangled_cstr), true); func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); - if (mangled.GetDemangledName()) - func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); + ConstString demangled = mangled.GetDemangledName(cu_language); + if (demangled) + func_fullnames.Insert (demangled, die.GetOffset()); } } } @@ -904,8 +906,9 @@ DWARFCompileUnit::Index (const uint32_t cu_idx, { Mangled mangled (ConstString(mangled_cstr), true); func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset()); - if (mangled.GetDemangledName()) - func_fullnames.Insert (mangled.GetDemangledName(), die.GetOffset()); + ConstString demangled = mangled.GetDemangledName(cu_language); + if (demangled) + func_fullnames.Insert (demangled, die.GetOffset()); } } else @@ -951,8 +954,9 @@ DWARFCompileUnit::Index (const uint32_t cu_idx, { Mangled mangled (ConstString(mangled_cstr), true); globals.Insert (mangled.GetMangledName(), die.GetOffset()); - if (mangled.GetDemangledName()) - globals.Insert (mangled.GetDemangledName(), die.GetOffset()); + ConstString demangled = mangled.GetDemangledName(cu_language); + if (demangled) + globals.Insert (demangled, die.GetOffset()); } } break; diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index dafd389449a2..ea8aedcc2be0 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -988,24 +988,38 @@ SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) std::string remapped_file; if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file)) cu_file_spec.SetFile(remapped_file, false); + } - LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0)); + LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0)); - cu_sp.reset(new CompileUnit (module_sp, - dwarf_cu, - cu_file_spec, - MakeUserID(dwarf_cu->GetOffset()), - cu_language)); - if (cu_sp) + cu_sp.reset(new CompileUnit (module_sp, + dwarf_cu, + cu_file_spec, + MakeUserID(dwarf_cu->GetOffset()), + cu_language)); + if (cu_sp) + { + // If we just created a compile unit with an invalid file spec, try and get the + // first entry in the supports files from the line table as that should be the + // compile unit. + if (!cu_file_spec) { - dwarf_cu->SetUserData(cu_sp.get()); - - // Figure out the compile unit index if we weren't given one - if (cu_idx == UINT32_MAX) - DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx); - - m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp); + cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1); + if (cu_file_spec) + { + (FileSpec &)(*cu_sp) = cu_file_spec; + // Also fix the invalid file spec which was copied from the compile unit. + cu_sp->GetSupportFiles().Replace(0, cu_file_spec); + } } + + dwarf_cu->SetUserData(cu_sp.get()); + + // Figure out the compile unit index if we weren't given one + if (cu_idx == UINT32_MAX) + DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx); + + m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp); } } } @@ -2196,7 +2210,7 @@ SymbolFileDWARF::ParseChildMembers } } - if (prop_name != NULL) + if (prop_name != NULL && member_type) { clang::ObjCIvarDecl *ivar_decl = NULL; @@ -3761,9 +3775,10 @@ SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die, } } - if (best_name.GetDemangledName()) + const LanguageType cu_language = const_cast<DWARFCompileUnit *>(dwarf_cu)->GetLanguageType(); + if (best_name.GetDemangledName(cu_language)) { - const char *demangled = best_name.GetDemangledName().GetCString(); + const char *demangled = best_name.GetDemangledName(cu_language).GetCString(); if (demangled) { std::string name_no_parens(partial_name, base_name_end - partial_name); diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 5579a23ce716..de972acd7ed7 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -113,7 +113,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa // correctly to the new addresses in the main executable. // First we find the original symbol in the .o file's symbol table - Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), + Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny); @@ -145,7 +145,7 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa // sizes from the DWARF info as we are parsing. // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file - Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), + Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(lldb::eLanguageTypeUnknown, Mangled::ePreferMangled), eSymbolTypeData, Symtab::eDebugNo, Symtab::eVisibilityAny); diff --git a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index 64c88ab716bf..09b919782608 100644 --- a/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -161,7 +161,7 @@ SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) { const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]); if (cu_symbol) - cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetMangled().GetName().AsCString(), 0, eLanguageTypeUnknown)); + cu_sp.reset(new CompileUnit (m_obj_file->GetModule(), NULL, cu_symbol->GetName().AsCString(), 0, eLanguageTypeUnknown)); } return cu_sp; } |