Index: lldb/trunk/include/lldb/API/SBPlatform.h =================================================================== --- lldb/trunk/include/lldb/API/SBPlatform.h +++ lldb/trunk/include/lldb/API/SBPlatform.h @@ -189,6 +189,9 @@ SBError SetFilePermissions (const char *path, uint32_t file_permissions); + SBUnixSignals + GetUnixSignals() const; + protected: friend class SBDebugger; Index: lldb/trunk/include/lldb/API/SBUnixSignals.h =================================================================== --- lldb/trunk/include/lldb/API/SBUnixSignals.h +++ lldb/trunk/include/lldb/API/SBUnixSignals.h @@ -65,17 +65,20 @@ protected: friend class SBProcess; + friend class SBPlatform; - SBUnixSignals (lldb::ProcessSP &process_sp); + SBUnixSignals(lldb::ProcessSP &process_sp); - lldb::ProcessSP + SBUnixSignals(lldb::PlatformSP &platform_sp); + + lldb::UnixSignalsSP GetSP() const; void - SetSP (const lldb::ProcessSP &process_sp); + SetSP(const lldb::UnixSignalsSP &signals_sp); private: - lldb::ProcessWP m_opaque_wp; + lldb::UnixSignalsWP m_opaque_wp; }; Index: lldb/trunk/include/lldb/Core/StructuredData.h =================================================================== --- lldb/trunk/include/lldb/Core/StructuredData.h +++ lldb/trunk/include/lldb/Core/StructuredData.h @@ -238,14 +238,15 @@ { } - void + bool ForEach (std::function const &foreach_callback) const { for (const auto &object_sp : m_items) { if (foreach_callback(object_sp.get()) == false) - break; + return false; } + return true; } Index: lldb/trunk/include/lldb/Host/Host.h =================================================================== --- lldb/trunk/include/lldb/Host/Host.h +++ lldb/trunk/include/lldb/Host/Host.h @@ -244,8 +244,8 @@ #endif // !defined(__ANDROID__) && !defined(__ANDROID_NDK__) #endif // defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__) - static const lldb_private::UnixSignalsSP& - GetUnixSignals (); + static const lldb::UnixSignalsSP & + GetUnixSignals(); static Error LaunchProcess (ProcessLaunchInfo &launch_info); Index: lldb/trunk/include/lldb/Target/Platform.h =================================================================== --- lldb/trunk/include/lldb/Target/Platform.h +++ lldb/trunk/include/lldb/Target/Platform.h @@ -863,6 +863,12 @@ return 1; } + virtual const lldb::UnixSignalsSP & + GetRemoteUnixSignals(); + + const lldb::UnixSignalsSP & + GetUnixSignals(); + //------------------------------------------------------------------ /// Locate a queue name given a thread's qaddr /// Index: lldb/trunk/include/lldb/Target/Process.h =================================================================== --- lldb/trunk/include/lldb/Target/Process.h +++ lldb/trunk/include/lldb/Target/Process.h @@ -950,7 +950,7 @@ /// Construct with a shared pointer to a target, the Process listener, /// and the appropriate UnixSignalsSP for the process. //------------------------------------------------------------------ - Process(Target &target, Listener &listener, const UnixSignalsSP &unix_signals_sp); + Process(Target &target, Listener &listener, const lldb::UnixSignalsSP &unix_signals_sp); //------------------------------------------------------------------ /// Destructor. @@ -1402,10 +1402,10 @@ Signal (int signal); void - SetUnixSignals (const UnixSignalsSP &signals_sp); + SetUnixSignals(const lldb::UnixSignalsSP &signals_sp); - UnixSignals & - GetUnixSignals (); + const lldb::UnixSignalsSP & + GetUnixSignals(); //================================================================== // Plug-in Process Control Overrides @@ -3237,7 +3237,7 @@ lldb::DynamicCheckerFunctionsUP m_dynamic_checkers_ap; ///< The functions used by the expression parser to validate data that expressions use. lldb::OperatingSystemUP m_os_ap; lldb::SystemRuntimeUP m_system_runtime_ap; - UnixSignalsSP m_unix_signals_sp; /// This is the current signal set for this process. + lldb::UnixSignalsSP m_unix_signals_sp; /// This is the current signal set for this process. lldb::ABISP m_abi_sp; lldb::IOHandlerSP m_process_input_reader; Communication m_stdio_communication; Index: lldb/trunk/include/lldb/Target/UnixSignals.h =================================================================== --- lldb/trunk/include/lldb/Target/UnixSignals.h +++ lldb/trunk/include/lldb/Target/UnixSignals.h @@ -26,6 +26,9 @@ class UnixSignals { public: + static lldb::UnixSignalsSP + Create(const ArchSpec &arch); + //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ @@ -89,6 +92,12 @@ int32_t GetNextSignalNumber (int32_t current_signal) const; + int32_t + GetNumSignals() const; + + int32_t + GetSignalAtIndex(int32_t index) const; + // We assume that the elements of this object are constant once it is constructed, // since a process should never need to add or remove symbols as it runs. So don't // call these functions anywhere but the constructor of your subclass of UnixSignals or in @@ -130,14 +139,18 @@ ~Signal () {} }; - void + virtual void Reset (); typedef std::map collection; collection m_signals; - DISALLOW_COPY_AND_ASSIGN (UnixSignals); + // GDBRemote signals need to be copyable. + UnixSignals(const UnixSignals &rhs); + + const UnixSignals & + operator=(const UnixSignals &rhs) = delete; }; } // Namespace lldb Index: lldb/trunk/include/lldb/lldb-forward.h =================================================================== --- lldb/trunk/include/lldb/lldb-forward.h +++ lldb/trunk/include/lldb/lldb-forward.h @@ -423,6 +423,8 @@ #ifndef LLDB_DISABLE_PYTHON typedef std::shared_ptr ScriptedSyntheticChildrenSP; #endif + typedef std::shared_ptr UnixSignalsSP; + typedef std::weak_ptr UnixSignalsWP; typedef std::shared_ptr UnwindAssemblySP; typedef std::shared_ptr UnwindPlanSP; typedef lldb_private::SharingPtr ValueObjectSP; Index: lldb/trunk/include/lldb/lldb-private-forward.h =================================================================== --- lldb/trunk/include/lldb/lldb-private-forward.h +++ lldb/trunk/include/lldb/lldb-private-forward.h @@ -34,7 +34,6 @@ typedef std::weak_ptr NativeProcessProtocolWP; typedef std::shared_ptr NativeRegisterContextSP; typedef std::shared_ptr NativeThreadProtocolSP; - typedef std::shared_ptr UnixSignalsSP; } #endif // #if defined(__cplusplus) Index: lldb/trunk/lldb.xcodeproj/project.pbxproj =================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj +++ lldb/trunk/lldb.xcodeproj/project.pbxproj @@ -860,6 +860,7 @@ E7723D481AC4A8C8002BA082 /* RegisterContextFreeBSD_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E7723D461AC4A8C8002BA082 /* RegisterContextFreeBSD_arm64.cpp */; }; E7723D4C1AC4A944002BA082 /* RegisterContextPOSIX_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E7723D4A1AC4A944002BA082 /* RegisterContextPOSIX_arm64.cpp */; }; E778E9A21B062D1700247609 /* EmulateInstructionMIPS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E778E99F1B062D1700247609 /* EmulateInstructionMIPS.cpp */; }; + E7E94ABC1B54961F00D0AE30 /* GDBRemoteSignals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E73A15A41B548EC500786197 /* GDBRemoteSignals.cpp */; }; ED88244E15114A9200BC98B9 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EDB919B414F6F10D008FF64B /* Security.framework */; }; ED88245015114CA200BC98B9 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED88244F15114CA200BC98B9 /* main.mm */; }; ED88245115114CA200BC98B9 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED88244F15114CA200BC98B9 /* main.mm */; }; @@ -2677,6 +2678,8 @@ B2D3033612EFA5C500F84EB3 /* InstructionUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InstructionUtils.h; path = Utility/InstructionUtils.h; sourceTree = ""; }; B5EFAE841AE53B1D007059F3 /* RegisterContextFreeBSD_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextFreeBSD_arm.cpp; path = Utility/RegisterContextFreeBSD_arm.cpp; sourceTree = ""; }; B5EFAE851AE53B1D007059F3 /* RegisterContextFreeBSD_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextFreeBSD_arm.h; path = Utility/RegisterContextFreeBSD_arm.h; sourceTree = ""; }; + E73A15A41B548EC500786197 /* GDBRemoteSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GDBRemoteSignals.cpp; path = Utility/GDBRemoteSignals.cpp; sourceTree = ""; }; + E73A15A51B548EC500786197 /* GDBRemoteSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GDBRemoteSignals.h; path = Utility/GDBRemoteSignals.h; sourceTree = ""; }; E769331D1A94D18100C73337 /* lldb-server.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lldb-server.cpp"; path = "tools/lldb-server/lldb-server.cpp"; sourceTree = ""; }; E7723D421AC4A7FB002BA082 /* RegisterContextPOSIXCore_arm64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextPOSIXCore_arm64.cpp; sourceTree = ""; }; E7723D431AC4A7FB002BA082 /* RegisterContextPOSIXCore_arm64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextPOSIXCore_arm64.h; sourceTree = ""; }; @@ -3811,6 +3814,8 @@ 26B4666E11A2080F00CF6220 /* Utility */ = { isa = PBXGroup; children = ( + E73A15A41B548EC500786197 /* GDBRemoteSignals.cpp */, + E73A15A51B548EC500786197 /* GDBRemoteSignals.h */, B5EFAE841AE53B1D007059F3 /* RegisterContextFreeBSD_arm.cpp */, B5EFAE851AE53B1D007059F3 /* RegisterContextFreeBSD_arm.h */, 256CBDBE1ADD11C000BC6CDC /* RegisterContextPOSIX_arm.cpp */, @@ -6448,6 +6453,7 @@ 94BA8B6D176F8C9B005A91B5 /* Range.cpp in Sources */, 26DAED6315D327C200E15819 /* OptionValuePathMappings.cpp in Sources */, B2B7CCEB15D1BD6700EEFB57 /* CommandObjectWatchpointCommand.cpp in Sources */, + E7E94ABC1B54961F00D0AE30 /* GDBRemoteSignals.cpp in Sources */, AF25AB26188F685C0030DEC3 /* AppleGetQueuesHandler.cpp in Sources */, B2B7CCF015D1C20F00EEFB57 /* WatchpointOptions.cpp in Sources */, 2640E19F15DC78FD00F23B50 /* Property.cpp in Sources */, Index: lldb/trunk/scripts/interface/SBPlatform.i =================================================================== --- lldb/trunk/scripts/interface/SBPlatform.i +++ lldb/trunk/scripts/interface/SBPlatform.i @@ -188,6 +188,9 @@ lldb::SBError SetFilePermissions (const char *path, uint32_t file_permissions); + lldb::SBUnixSignals + GetUnixSignals(); + }; } // namespace lldb Index: lldb/trunk/source/API/SBPlatform.cpp =================================================================== --- lldb/trunk/source/API/SBPlatform.cpp +++ lldb/trunk/source/API/SBPlatform.cpp @@ -11,6 +11,7 @@ #include "lldb/API/SBError.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBLaunchInfo.h" +#include "lldb/API/SBUnixSignals.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/Error.h" #include "lldb/Host/File.h" @@ -638,3 +639,11 @@ } +SBUnixSignals +SBPlatform::GetUnixSignals() const +{ + if (auto platform_sp = GetSP()) + return SBUnixSignals{platform_sp}; + + return {}; +} Index: lldb/trunk/source/API/SBProcess.cpp =================================================================== --- lldb/trunk/source/API/SBProcess.cpp +++ lldb/trunk/source/API/SBProcess.cpp @@ -912,14 +912,10 @@ SBUnixSignals SBProcess::GetUnixSignals() { - SBUnixSignals sb_unix_signals; - ProcessSP process_sp(GetSP()); - if (process_sp) - { - sb_unix_signals.SetSP(process_sp); - } + if (auto process_sp = GetSP()) + return SBUnixSignals{process_sp}; - return sb_unix_signals; + return {}; } void Index: lldb/trunk/source/API/SBThread.cpp =================================================================== --- lldb/trunk/source/API/SBThread.cpp +++ lldb/trunk/source/API/SBThread.cpp @@ -392,7 +392,7 @@ case eStopReasonSignal: { - stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); + stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(stop_info_sp->GetValue()); if (stop_desc == NULL || stop_desc[0] == '\0') { static char signal_desc[] = "signal"; Index: lldb/trunk/source/API/SBUnixSignals.cpp =================================================================== --- lldb/trunk/source/API/SBUnixSignals.cpp +++ lldb/trunk/source/API/SBUnixSignals.cpp @@ -9,6 +9,7 @@ #include "lldb/lldb-defines.h" #include "lldb/Target/Process.h" +#include "lldb/Target/Platform.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Core/Log.h" @@ -25,8 +26,13 @@ { } -SBUnixSignals::SBUnixSignals (ProcessSP &process_sp) : - m_opaque_wp(process_sp) +SBUnixSignals::SBUnixSignals(ProcessSP &process_sp) : + m_opaque_wp(process_sp ? process_sp->GetUnixSignals() : nullptr) +{ +} + +SBUnixSignals::SBUnixSignals(PlatformSP &platform_sp) : + m_opaque_wp(platform_sp ? platform_sp->GetUnixSignals() : nullptr) { } @@ -42,16 +48,16 @@ { } -ProcessSP +UnixSignalsSP SBUnixSignals::GetSP() const { return m_opaque_wp.lock(); } void -SBUnixSignals::SetSP (const ProcessSP &process_sp) +SBUnixSignals::SetSP(const UnixSignalsSP &signals_sp) { - m_opaque_wp = process_sp; + m_opaque_wp = signals_sp; } void @@ -63,30 +69,33 @@ bool SBUnixSignals::IsValid() const { - return (bool) GetSP(); + return static_cast(GetSP()); } const char * SBUnixSignals::GetSignalAsCString (int32_t signo) const { - ProcessSP process_sp(GetSP()); - if (process_sp) return process_sp->GetUnixSignals().GetSignalAsCString(signo); - return NULL; + if (auto signals_sp = GetSP()) + return signals_sp->GetSignalAsCString(signo); + + return nullptr; } int32_t SBUnixSignals::GetSignalNumberFromName (const char *name) const { - ProcessSP process_sp(GetSP()); - if (process_sp) return process_sp->GetUnixSignals().GetSignalNumberFromName(name); - return -1; + if (auto signals_sp = GetSP()) + return signals_sp->GetSignalNumberFromName(name); + + return LLDB_INVALID_SIGNAL_NUMBER; } bool SBUnixSignals::GetShouldSuppress (int32_t signo) const { - ProcessSP process_sp(GetSP()); - if (process_sp) return process_sp->GetUnixSignals().GetShouldSuppress(signo); + if (auto signals_sp = GetSP()) + return signals_sp->GetShouldSuppress(signo); + return false; } @@ -94,25 +103,28 @@ SBUnixSignals::SetShouldSuppress (int32_t signo, bool value) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ProcessSP process_sp(GetSP()); + auto signals_sp = GetSP(); if (log) { log->Printf ("SBUnixSignals(%p)::SetShouldSuppress (signo=%d, value=%d)", - static_cast(process_sp.get()), + static_cast(signals_sp.get()), signo, value); } - if (process_sp) return process_sp->GetUnixSignals().SetShouldSuppress(signo, value); + if (signals_sp) + return signals_sp->SetShouldSuppress(signo, value); + return false; } bool SBUnixSignals::GetShouldStop (int32_t signo) const { - ProcessSP process_sp(GetSP()); - if (process_sp) return process_sp->GetUnixSignals().GetShouldStop(signo); + if (auto signals_sp = GetSP()) + return signals_sp->GetShouldStop(signo); + return false; } @@ -120,25 +132,28 @@ SBUnixSignals::SetShouldStop (int32_t signo, bool value) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ProcessSP process_sp(GetSP()); + auto signals_sp = GetSP(); if (log) { log->Printf ("SBUnixSignals(%p)::SetShouldStop (signo=%d, value=%d)", - static_cast(process_sp.get()), + static_cast(signals_sp.get()), signo, value); } - if (process_sp) return process_sp->GetUnixSignals().SetShouldStop(signo, value); + if (signals_sp) + return signals_sp->SetShouldStop(signo, value); + return false; } bool SBUnixSignals::GetShouldNotify (int32_t signo) const { - ProcessSP process_sp(GetSP()); - if (process_sp) return process_sp->GetUnixSignals().GetShouldNotify(signo); + if (auto signals_sp = GetSP()) + return signals_sp->GetShouldNotify(signo); + return false; } @@ -146,54 +161,36 @@ SBUnixSignals::SetShouldNotify (int32_t signo, bool value) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ProcessSP process_sp(GetSP()); + auto signals_sp = GetSP(); if (log) { log->Printf ("SBUnixSignals(%p)::SetShouldNotify (signo=%d, value=%d)", - static_cast(process_sp.get()), + static_cast(signals_sp.get()), signo, value); } - if (process_sp) return process_sp->GetUnixSignals().SetShouldNotify(signo, value); + if (signals_sp) + return signals_sp->SetShouldNotify(signo, value); + return false; } int32_t SBUnixSignals::GetNumSignals () const { - if (auto process_sp = GetSP()) - { - // only valid while we hold process_sp - UnixSignals *unix_signals_ptr = &process_sp->GetUnixSignals(); - int32_t num_signals = 0; - for (int32_t signo = unix_signals_ptr->GetFirstSignalNumber(); - signo != LLDB_INVALID_SIGNAL_NUMBER; - signo = unix_signals_ptr->GetNextSignalNumber(signo)) - { - num_signals++; - } - return num_signals; - } - return LLDB_INVALID_SIGNAL_NUMBER; + if (auto signals_sp = GetSP()) + return signals_sp->GetNumSignals(); + + return -1; } int32_t SBUnixSignals::GetSignalAtIndex (int32_t index) const { - if (auto process_sp = GetSP()) - { - // only valid while we hold process_sp - UnixSignals *unix_signals_ptr = &process_sp->GetUnixSignals(); - int32_t idx = 0; - for (int32_t signo = unix_signals_ptr->GetFirstSignalNumber(); - signo != LLDB_INVALID_SIGNAL_NUMBER; - signo = unix_signals_ptr->GetNextSignalNumber(signo)) - { - if (index == idx) return signo; - idx++; - } - } + if (auto signals_sp = GetSP()) + return signals_sp->GetSignalAtIndex(index); + return LLDB_INVALID_SIGNAL_NUMBER; } Index: lldb/trunk/source/Commands/CommandObjectProcess.cpp =================================================================== --- lldb/trunk/source/Commands/CommandObjectProcess.cpp +++ lldb/trunk/source/Commands/CommandObjectProcess.cpp @@ -1337,7 +1337,7 @@ if (::isxdigit (signal_name[0])) signo = StringConvert::ToSInt32(signal_name, LLDB_INVALID_SIGNAL_NUMBER, 0); else - signo = process->GetUnixSignals().GetSignalNumberFromName (signal_name); + signo = process->GetUnixSignals()->GetSignalNumberFromName(signal_name); if (signo == LLDB_INVALID_SIGNAL_NUMBER) { @@ -1734,14 +1734,14 @@ } void - PrintSignal (Stream &str, int32_t signo, const char *sig_name, UnixSignals &signals) + PrintSignal(Stream &str, int32_t signo, const char *sig_name, const UnixSignalsSP &signals_sp) { bool stop; bool suppress; bool notify; str.Printf ("%-11s ", sig_name); - if (signals.GetSignalInfo (signo, suppress, stop, notify)) + if (signals_sp->GetSignalInfo(signo, suppress, stop, notify)) { bool pass = !suppress; str.Printf ("%s %s %s", @@ -1753,7 +1753,7 @@ } void - PrintSignalInformation (Stream &str, Args &signal_args, int num_valid_signals, UnixSignals &signals) + PrintSignalInformation(Stream &str, Args &signal_args, int num_valid_signals, const UnixSignalsSP &signals_sp) { PrintSignalHeader (str); @@ -1762,18 +1762,18 @@ size_t num_args = signal_args.GetArgumentCount(); for (size_t i = 0; i < num_args; ++i) { - int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); + int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); if (signo != LLDB_INVALID_SIGNAL_NUMBER) - PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals); + PrintSignal (str, signo, signal_args.GetArgumentAtIndex (i), signals_sp); } } else // Print info for ALL signals { - int32_t signo = signals.GetFirstSignalNumber(); + int32_t signo = signals_sp->GetFirstSignalNumber(); while (signo != LLDB_INVALID_SIGNAL_NUMBER) { - PrintSignal (str, signo, signals.GetSignalAsCString (signo), signals); - signo = signals.GetNextSignalNumber (signo); + PrintSignal(str, signo, signals_sp->GetSignalAsCString(signo), signals_sp); + signo = signals_sp->GetNextSignalNumber(signo); } } } @@ -1830,27 +1830,27 @@ } size_t num_args = signal_args.GetArgumentCount(); - UnixSignals &signals = process_sp->GetUnixSignals(); + UnixSignalsSP signals_sp = process_sp->GetUnixSignals(); int num_signals_set = 0; if (num_args > 0) { for (size_t i = 0; i < num_args; ++i) { - int32_t signo = signals.GetSignalNumberFromName (signal_args.GetArgumentAtIndex (i)); + int32_t signo = signals_sp->GetSignalNumberFromName(signal_args.GetArgumentAtIndex(i)); if (signo != LLDB_INVALID_SIGNAL_NUMBER) { // Casting the actions as bools here should be okay, because VerifyCommandOptionValue guarantees // the value is either 0 or 1. if (stop_action != -1) - signals.SetShouldStop (signo, (bool) stop_action); + signals_sp->SetShouldStop(signo, stop_action); if (pass_action != -1) { - bool suppress = ! ((bool) pass_action); - signals.SetShouldSuppress (signo, suppress); + bool suppress = !pass_action; + signals_sp->SetShouldSuppress(signo, suppress); } if (notify_action != -1) - signals.SetShouldNotify (signo, (bool) notify_action); + signals_sp->SetShouldNotify(signo, notify_action); ++num_signals_set; } else @@ -1866,25 +1866,25 @@ { if (m_interpreter.Confirm ("Do you really want to update all the signals?", false)) { - int32_t signo = signals.GetFirstSignalNumber(); + int32_t signo = signals_sp->GetFirstSignalNumber(); while (signo != LLDB_INVALID_SIGNAL_NUMBER) { if (notify_action != -1) - signals.SetShouldNotify (signo, (bool) notify_action); + signals_sp->SetShouldNotify(signo, notify_action); if (stop_action != -1) - signals.SetShouldStop (signo, (bool) stop_action); + signals_sp->SetShouldStop(signo, stop_action); if (pass_action != -1) { - bool suppress = ! ((bool) pass_action); - signals.SetShouldSuppress (signo, suppress); + bool suppress = !pass_action; + signals_sp->SetShouldSuppress(signo, suppress); } - signo = signals.GetNextSignalNumber (signo); + signo = signals_sp->GetNextSignalNumber(signo); } } } } - PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals); + PrintSignalInformation (result.GetOutputStream(), signal_args, num_signals_set, signals_sp); if (num_signals_set > 0) result.SetStatus (eReturnStatusSuccessFinishNoResult); Index: lldb/trunk/source/Host/common/Host.cpp =================================================================== --- lldb/trunk/source/Host/common/Host.cpp +++ lldb/trunk/source/Host/common/Host.cpp @@ -1070,13 +1070,9 @@ #endif -#if !defined (__linux__) && !defined (__FreeBSD__) && !defined(__FreeBSD_kernel__) && !defined (__NetBSD__) - -const lldb_private::UnixSignalsSP& -Host::GetUnixSignals () +const UnixSignalsSP & +Host::GetUnixSignals() { - static UnixSignalsSP s_unix_signals_sp (new UnixSignals ()); + static const auto s_unix_signals_sp = UnixSignals::Create(HostInfo::GetArchitecture()); return s_unix_signals_sp; } - -#endif Index: lldb/trunk/source/Host/freebsd/Host.cpp =================================================================== --- lldb/trunk/source/Host/freebsd/Host.cpp +++ lldb/trunk/source/Host/freebsd/Host.cpp @@ -40,8 +40,6 @@ #include "lldb/Utility/CleanUp.h" #include "lldb/Utility/NameMatches.h" -#include "Plugins/Process/Utility/FreeBSDSignals.h" - #include "llvm/Support/Host.h" extern "C" { @@ -277,13 +275,6 @@ return buf_sp; } -const UnixSignalsSP& -Host::GetUnixSignals () -{ - static const lldb_private::UnixSignalsSP s_unix_signals_sp (new FreeBSDSignals ()); - return s_unix_signals_sp; -} - Error Host::ShellExpandArguments (ProcessLaunchInfo &launch_info) { Index: lldb/trunk/source/Host/linux/Host.cpp =================================================================== --- lldb/trunk/source/Host/linux/Host.cpp +++ lldb/trunk/source/Host/linux/Host.cpp @@ -36,8 +36,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Symbol/ObjectFile.h" #include "Plugins/Process/Linux/ProcFileReader.h" -#include "Plugins/Process/Utility/LinuxSignals.h" -#include "Plugins/Process/Utility/MipsLinuxSignals.h" + using namespace lldb; using namespace lldb_private; @@ -390,26 +389,6 @@ return i; } -// TODO: Generalize this with a function Host::GetSignals() as discussed at http://reviews.llvm.org/D10180 -const lldb_private::UnixSignalsSP& -Host::GetUnixSignals () -{ - ArchSpec target_arch = HostInfoBase::GetArchitecture(); - if(target_arch.GetTriple ().getArch () == llvm::Triple::mips64 || - target_arch.GetTriple ().getArch () == llvm::Triple::mips64el || - target_arch.GetTriple ().getArch () == llvm::Triple::mips || - target_arch.GetTriple ().getArch () == llvm::Triple::mipsel) { - static const lldb_private::UnixSignalsSP s_unix_signals_sp (new process_linux::MipsLinuxSignals ()); - return s_unix_signals_sp; - } - else - { - static const lldb_private::UnixSignalsSP s_unix_signals_sp (new process_linux::LinuxSignals ()); - return s_unix_signals_sp; - } - -} - Error Host::ShellExpandArguments (ProcessLaunchInfo &launch_info) { Index: lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp +++ lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp @@ -754,9 +754,6 @@ log->Printf ("PlatformLinux::%s successfully created process", __FUNCTION__); } - // Set the unix signals properly. - process_sp->SetUnixSignals (Host::GetUnixSignals ()); - // Adjust launch for a hijacker. ListenerSP listener_sp; if (!launch_info.GetHijackListener ()) Index: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h =================================================================== --- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h @@ -109,6 +109,9 @@ lldb_private::ArchSpec GetRemoteSystemArchitecture () override; + const lldb::UnixSignalsSP & + GetRemoteUnixSignals() override; + size_t GetEnvironment (lldb_private::StringList &environment) override; Index: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -535,6 +535,14 @@ 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 @@ if (process_sp) { - // Set UnixSignals appropriately. - process_sp->SetUnixSignals (Host::GetUnixSignals ()); - auto listener_sp = attach_info.GetHijackListener(); if (listener_sp == nullptr) { Index: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h =================================================================== --- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ lldb/trunk/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 @@ 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. Index: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ lldb/trunk/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; @@ -413,6 +415,7 @@ { Error error; m_gdb_client.Disconnect(&error); + m_remote_signals_sp.reset(); return error; } @@ -871,6 +874,97 @@ 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(); + + 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; +} Index: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -43,7 +43,6 @@ #include "lldb/Utility/StringExtractor.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "Plugins/Process/Utility/LinuxSignals.h" #include "NativeThreadLinux.h" #include "ProcFileReader.h" #include "Procfs.h" @@ -113,13 +112,6 @@ namespace { - const UnixSignals& - GetUnixSignals () - { - static process_linux::LinuxSignals signals; - return signals; - } - Error ResolveProcessArchitecture (lldb::pid_t pid, Platform &platform, ArchSpec &arch) { @@ -1987,7 +1979,7 @@ if (log) log->Printf ("NativeProcessLinux::%s() received signal %s (%d) with code %s, (siginfo pid = %d (%s), waitpid pid = %" PRIu64 ")", __FUNCTION__, - GetUnixSignals ().GetSignalAsCString (signo), + Host::GetSignalAsCString(signo), signo, (info->si_code == SI_TKILL ? "SI_TKILL" : "SI_USER"), info->si_pid, @@ -2062,7 +2054,7 @@ // Retrieve the signal name if the thread was stopped by a signal. int stop_signo = 0; const bool stopped_by_signal = linux_thread_sp->IsStopped (&stop_signo); - const char *signal_name = stopped_by_signal ? GetUnixSignals ().GetSignalAsCString (stop_signo) : ""; + const char *signal_name = stopped_by_signal ? Host::GetSignalAsCString(stop_signo) : ""; if (!signal_name) signal_name = ""; @@ -2083,7 +2075,7 @@ } if (log) - log->Printf ("NativeProcessLinux::%s() received signal %s", __FUNCTION__, GetUnixSignals ().GetSignalAsCString (signo)); + log->Printf ("NativeProcessLinux::%s() received signal %s", __FUNCTION__, Host::GetSignalAsCString(signo)); // This thread is stopped. ThreadDidStop (pid, false); @@ -2428,8 +2420,8 @@ Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); if (log) - log->Printf ("NativeProcessLinux::%s: sending signal %d (%s) to pid %" PRIu64, - __FUNCTION__, signo, GetUnixSignals ().GetSignalAsCString (signo), GetID ()); + log->Printf ("NativeProcessLinux::%s: sending signal %d (%s) to pid %" PRIu64, + __FUNCTION__, signo, Host::GetSignalAsCString(signo), GetID()); if (kill(GetID(), signo)) error.SetErrorToErrno(); @@ -3176,7 +3168,7 @@ if (log) log->Printf ("NativeProcessLinux::%s() resuming thread = %" PRIu64 " with signal %s", __FUNCTION__, tid, - GetUnixSignals().GetSignalAsCString (signo)); + Host::GetSignalAsCString(signo)); Index: lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt +++ lldb/trunk/source/Plugins/Process/Utility/CMakeLists.txt @@ -5,6 +5,7 @@ add_lldb_library(lldbPluginProcessUtility DynamicRegisterInfo.cpp FreeBSDSignals.cpp + GDBRemoteSignals.cpp HistoryThread.cpp HistoryUnwind.cpp InferiorCallPOSIX.cpp Index: lldb/trunk/source/Plugins/Process/Utility/FreeBSDSignals.h =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/FreeBSDSignals.h +++ lldb/trunk/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_ Index: lldb/trunk/source/Plugins/Process/Utility/FreeBSDSignals.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/FreeBSDSignals.cpp +++ lldb/trunk/source/Plugins/Process/Utility/FreeBSDSignals.cpp @@ -13,6 +13,8 @@ // Project includes #include "FreeBSDSignals.h" +using namespace lldb_private; + FreeBSDSignals::FreeBSDSignals() : UnixSignals() { Index: lldb/trunk/source/Plugins/Process/Utility/GDBRemoteSignals.h =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/GDBRemoteSignals.h +++ lldb/trunk/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_ Index: lldb/trunk/source/Plugins/Process/Utility/GDBRemoteSignals.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/GDBRemoteSignals.cpp +++ lldb/trunk/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(); +} Index: lldb/trunk/source/Plugins/Process/Utility/LinuxSignals.h =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/LinuxSignals.h +++ lldb/trunk/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(); - - private: - void - Reset(); - }; +/// Linux specific set of Unix signals. +class LinuxSignals : public UnixSignals +{ +public: + LinuxSignals(); + +private: + void + Reset() override; +}; } // namespace lldb_private -} // namespace process_linux -#endif +#endif // liblldb_LinuxSignals_H_ Index: lldb/trunk/source/Plugins/Process/Utility/LinuxSignals.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/LinuxSignals.cpp +++ lldb/trunk/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() Index: lldb/trunk/source/Plugins/Process/Utility/MipsLinuxSignals.h =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/MipsLinuxSignals.h +++ lldb/trunk/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(); - - private: - void - Reset(); - }; +/// Linux specific set of Unix signals. +class MipsLinuxSignals : public UnixSignals +{ +public: + MipsLinuxSignals(); + +private: + void + Reset() override; +}; } // namespace lldb_private -} // namespace process_linux -#endif +#endif // liblldb_MipsLinuxSignals_H_ Index: lldb/trunk/source/Plugins/Process/Utility/MipsLinuxSignals.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/MipsLinuxSignals.cpp +++ lldb/trunk/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() Index: lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ lldb/trunk/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 @@ 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 @@ 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(); SetUnixSignals(s_default_unix_signals_sp); } Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1056,8 +1056,8 @@ // 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; Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h @@ -79,6 +79,9 @@ PacketResult Handle_qC (StringExtractorGDBRemote &packet); + PacketResult + Handle_jSignalsInfo(StringExtractorGDBRemote &packet); + private: bool DebugserverProcessReaped (lldb::pid_t pid); Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ lldb/trunk/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::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 @@ 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(); + + 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) { Index: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ lldb/trunk/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 @@ 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 () : "", 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(GetTarget().GetPlatform()->GetUnixSignals())); return error; } @@ -3524,7 +3489,7 @@ 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 Index: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -215,14 +215,14 @@ 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); Index: lldb/trunk/source/Target/Platform.cpp =================================================================== --- lldb/trunk/source/Target/Platform.cpp +++ lldb/trunk/source/Target/Platform.cpp @@ -36,6 +36,7 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Utils.h" #include "llvm/Support/FileSystem.h" @@ -1930,3 +1931,18 @@ { return GetHostname (); } + +const UnixSignalsSP & +Platform::GetRemoteUnixSignals() +{ + static const auto s_default_unix_signals_sp = std::make_shared(); + return s_default_unix_signals_sp; +} + +const UnixSignalsSP & +Platform::GetUnixSignals() +{ + if (IsHost()) + return Host::GetUnixSignals(); + return GetRemoteUnixSignals(); +} Index: lldb/trunk/source/Target/Process.cpp =================================================================== --- lldb/trunk/source/Target/Process.cpp +++ lldb/trunk/source/Target/Process.cpp @@ -693,7 +693,7 @@ // Process constructor //---------------------------------------------------------------------- Process::Process(Target &target, Listener &listener) : - Process(target, listener, Host::GetUnixSignals ()) + Process(target, listener, UnixSignals::Create(HostInfo::GetArchitecture())) { // This constructor just delegates to the full Process constructor, // defaulting to using the Host's UnixSignals. @@ -763,14 +763,14 @@ log->Printf ("%p Process::Process()", static_cast(this)); if (!m_unix_signals_sp) - m_unix_signals_sp.reset (new UnixSignals ()); + m_unix_signals_sp = std::make_shared(); SetEventName (eBroadcastBitStateChanged, "state-changed"); SetEventName (eBroadcastBitInterrupt, "interrupt"); SetEventName (eBroadcastBitSTDOUT, "stdout-available"); SetEventName (eBroadcastBitSTDERR, "stderr-available"); SetEventName (eBroadcastBitProfileData, "profile-data-available"); - + m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlStop , "control-stop" ); m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlPause , "control-pause" ); m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlResume, "control-resume"); @@ -1164,7 +1164,7 @@ // signal. We have to have had another reason for stopping here, and // the user doesn't want to see this thread. uint64_t signo = thread->GetStopInfo()->GetValue(); - if (process_sp->GetUnixSignals().GetShouldStop(signo)) + if (process_sp->GetUnixSignals()->GetShouldStop(signo)) { if (!other_thread) other_thread = thread; @@ -1523,7 +1523,7 @@ { const char *signal_cstr = NULL; if (signo) - signal_cstr = process_sp->GetUnixSignals().GetSignalAsCString (signo); + signal_cstr = process_sp->GetUnixSignals()->GetSignalAsCString(signo); process_sp->SetExitStatus (exit_status, signal_cstr); } @@ -4101,11 +4101,11 @@ m_unix_signals_sp = signals_sp; } -UnixSignals & +const lldb::UnixSignalsSP & Process::GetUnixSignals () { assert (m_unix_signals_sp && "null m_unix_signals_sp"); - return *m_unix_signals_sp; + return m_unix_signals_sp; } lldb::ByteOrder Index: lldb/trunk/source/Target/StopInfo.cpp =================================================================== --- lldb/trunk/source/Target/StopInfo.cpp +++ lldb/trunk/source/Target/StopInfo.cpp @@ -891,7 +891,7 @@ { ThreadSP thread_sp (m_thread_wp.lock()); if (thread_sp) - return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value); + return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value); return false; } @@ -900,7 +900,7 @@ { ThreadSP thread_sp (m_thread_wp.lock()); if (thread_sp) - return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value); + return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value); return false; } @@ -912,13 +912,13 @@ ThreadSP thread_sp (m_thread_wp.lock()); if (thread_sp) { - bool should_notify = thread_sp->GetProcess()->GetUnixSignals().GetShouldNotify (m_value); + bool should_notify = thread_sp->GetProcess()->GetUnixSignals()->GetShouldNotify(m_value); if (should_notify) { StreamString strm; strm.Printf ("thread %d received signal: %s", thread_sp->GetIndexID(), - thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value)); + thread_sp->GetProcess()->GetUnixSignals()->GetSignalAsCString(m_value)); Process::ProcessEventData::AddRestartedReason(event_ptr, strm.GetData()); } return should_notify; @@ -933,7 +933,7 @@ ThreadSP thread_sp (m_thread_wp.lock()); if (thread_sp) { - if (thread_sp->GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false) + if (thread_sp->GetProcess()->GetUnixSignals()->GetShouldSuppress(m_value) == false) thread_sp->SetResumeSignal(m_value); } } @@ -947,7 +947,7 @@ if (thread_sp) { StreamString strm; - const char *signal_name = thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value); + const char *signal_name = thread_sp->GetProcess()->GetUnixSignals()->GetSignalAsCString(m_value); if (signal_name) strm.Printf("signal %s", signal_name); else Index: lldb/trunk/source/Target/UnixSignals.cpp =================================================================== --- lldb/trunk/source/Target/UnixSignals.cpp +++ lldb/trunk/source/Target/UnixSignals.cpp @@ -13,16 +13,21 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Core/ArchSpec.h" #include "lldb/Host/StringConvert.h" +#include "Plugins/Process/Utility/FreeBSDSignals.h" +#include "Plugins/Process/Utility/LinuxSignals.h" +#include "Plugins/Process/Utility/MipsLinuxSignals.h" + using namespace lldb_private; -UnixSignals::Signal::Signal +UnixSignals::Signal::Signal ( - const char *name, - const char *short_name, - bool default_suppress, - bool default_stop, + const char *name, + const char *short_name, + bool default_suppress, + bool default_stop, bool default_notify, const char *description ) : @@ -37,6 +42,34 @@ m_description.assign (description); } +lldb::UnixSignalsSP +UnixSignals::Create(const ArchSpec &arch) +{ + const auto &triple = arch.GetTriple(); + switch (triple.getOS()) + { + case llvm::Triple::Linux: + { + switch (triple.getArch()) + { + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + return std::make_shared(); + default: + return std::make_shared(); + } + } + case llvm::Triple::FreeBSD: + case llvm::Triple::OpenBSD: + case llvm::Triple::NetBSD: + return std::make_shared(); + default: + return std::make_shared(); + } +} + //---------------------------------------------------------------------- // UnixSignals constructor //---------------------------------------------------------------------- @@ -45,6 +78,11 @@ Reset (); } +UnixSignals::UnixSignals(const UnixSignals &rhs) + : m_signals(rhs.m_signals) +{ +} + //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- @@ -291,3 +329,19 @@ return SetShouldNotify (signo, value); return false; } + +int32_t +UnixSignals::GetNumSignals() const +{ + return m_signals.size(); +} + +int32_t +UnixSignals::GetSignalAtIndex(int32_t index) const +{ + if (index < 0 || m_signals.size() <= static_cast(index)) + return LLDB_INVALID_SIGNAL_NUMBER; + auto it = m_signals.begin(); + std::advance(it, index); + return it->first; +} Index: lldb/trunk/source/Utility/StringExtractorGDBRemote.h =================================================================== --- lldb/trunk/source/Utility/StringExtractorGDBRemote.h +++ lldb/trunk/source/Utility/StringExtractorGDBRemote.h @@ -118,6 +118,8 @@ eServerPacketType_qWatchpointSupportInfoSupported, eServerPacketType_qXfer_auxv_read, + eServerPacketType_jSignalsInfo, + eServerPacketType_vAttach, eServerPacketType_vAttachWait, eServerPacketType_vAttachOrWait, Index: lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp =================================================================== --- lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp +++ lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp @@ -82,7 +82,7 @@ case 'A': return eServerPacketType_A; - + case 'Q': switch (packet_cstr[1]) @@ -122,7 +122,7 @@ break; } break; - + case 'q': switch (packet_cstr[1]) { @@ -219,6 +219,10 @@ break; } break; + + case 'j': + if (PACKET_MATCHES("jSignalInfo")) return eServerPacketType_jSignalsInfo; + case 'v': if (PACKET_STARTS_WITH("vFile:")) { Index: lldb/trunk/test/lldbutil.py =================================================================== --- lldb/trunk/test/lldbutil.py +++ lldb/trunk/test/lldbutil.py @@ -934,36 +934,11 @@ def get_signal_number(signal_name): platform = lldb.remote_platform - if platform: - if platform.GetName() == 'remote-linux': - command = lldb.SBPlatformShellCommand('kill -l %d' % signal_name) - if platform.Run(command).Success() and command.GetStatus() == 0: - try: - return int(command.GetOutput()) - except ValueError: - pass - elif platform.GetName() == 'remote-android': - for signal_number in range(1, 65): - command = lldb.SBPlatformShellCommand('kill -l %d' % signal_number) - if platform.Run(command).Fail() or command.GetStatus() != 0: - continue - output = command.GetOutput().strip().upper() - if not output.startswith('SIG'): - output = 'SIG' + output - if output == signal_name: - return signal_number - if lldb.debugger: - for target_index in range(lldb.debugger.GetNumTargets()): - target = lldb.debugger.GetTargetAtIndex(target_index) - if not target.IsValid(): - continue - process = target.GetProcess() - if not process.IsValid(): - continue - signals = process.GetUnixSignals() - if not signals.IsValid(): - continue + if platform and platform.IsValid(): + signals = platform.GetUnixSignals() + if signals.IsValid(): signal_number = signals.GetSignalNumberFromName(signal_name) if signal_number > 0: return signal_number + # No remote platform; fall back to using local python signals. return getattr(signal, signal_name)