diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py @@ -858,6 +858,7 @@ "vfork-events", "memory-tagging", "qSaveCore", + "native-signals", ] def parse_qSupported_response(self, context): diff --git a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h --- a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h +++ b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h @@ -13,7 +13,8 @@ namespace lldb_private { -/// Empty set of Unix signals to be filled by PlatformRemoteGDBServer +/// Initially carries signals defined by the GDB Remote Serial Protocol. +/// Can be filled with platform's signals through PlatformRemoteGDBServer. class GDBRemoteSignals : public UnixSignals { public: GDBRemoteSignals(); diff --git a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp --- a/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp @@ -15,4 +15,167 @@ GDBRemoteSignals::GDBRemoteSignals(const lldb::UnixSignalsSP &rhs) : UnixSignals(*rhs) {} -void GDBRemoteSignals::Reset() { m_signals.clear(); } +void GDBRemoteSignals::Reset() { + m_signals.clear(); + // clang-format off + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION + // ====== ============== ======== ====== ====== =================================================== + AddSignal(1, "SIGHUP", false, true, true, "hangup"); + AddSignal(2, "SIGINT", true, true, true, "interrupt"); + AddSignal(3, "SIGQUIT", false, true, true, "quit"); + AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); + AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)"); + AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT"); + AddSignal(7, "SIGEMT", false, true, true, "emulation trap"); + AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); + AddSignal(9, "SIGKILL", false, true, true, "kill"); + AddSignal(10, "SIGBUS", false, true, true, "bus error"); + AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); + AddSignal(12, "SIGSYS", false, true, true, "invalid system call"); + AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed"); + AddSignal(14, "SIGALRM", false, false, false, "alarm"); + AddSignal(15, "SIGTERM", false, true, true, "termination requested"); + AddSignal(16, "SIGURG", false, true, true, "urgent data on socket"); + AddSignal(17, "SIGSTOP", true, true, true, "process stop"); + AddSignal(18, "SIGTSTP", false, true, true, "tty stop"); + AddSignal(19, "SIGCONT", false, false, true, "process continue"); + AddSignal(20, "SIGCHLD", false, false, true, "child status has changed", "SIGCLD"); + AddSignal(21, "SIGTTIN", false, true, true, "background tty read"); + AddSignal(22, "SIGTTOU", false, true, true, "background tty write"); + AddSignal(23, "SIGIO", false, true, true, "input/output ready/Pollable event"); + AddSignal(24, "SIGXCPU", false, true, true, "CPU resource exceeded"); + AddSignal(25, "SIGXFSZ", false, true, true, "file size limit exceeded"); + AddSignal(26, "SIGVTALRM", false, true, true, "virtual time alarm"); + AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm"); + AddSignal(28, "SIGWINCH", false, true, true, "window size changes"); + AddSignal(29, "SIGLOST", false, true, true, "resource lost"); + AddSignal(30, "SIGUSR1", false, true, true, "user defined signal 1"); + AddSignal(31, "SIGUSR2", false, true, true, "user defined signal 2"); + AddSignal(32, "SIGPWR", false, true, true, "power failure"); + AddSignal(33, "SIGPOLL", false, true, true, "pollable event"); + AddSignal(34, "SIGWIND", false, true, true, "SIGWIND"); + AddSignal(35, "SIGPHONE", false, true, true, "SIGPHONE"); + AddSignal(36, "SIGWAITING", false, true, true, "process's LWPs are blocked"); + AddSignal(37, "SIGLWP", false, true, true, "signal LWP"); + AddSignal(38, "SIGDANGER", false, true, true, "swap space dangerously low"); + AddSignal(39, "SIGGRANT", false, true, true, "monitor mode granted"); + AddSignal(40, "SIGRETRACT", false, true, true, "need to relinquish monitor mode"); + AddSignal(41, "SIGMSG", false, true, true, "monitor mode data available"); + AddSignal(42, "SIGSOUND", false, true, true, "sound completed"); + AddSignal(43, "SIGSAK", false, true, true, "secure attention"); + AddSignal(44, "SIGPRIO", false, true, true, "SIGPRIO"); + + AddSignal(45, "SIG33", false, false, false, "real-time event 33"); + AddSignal(46, "SIG34", false, false, false, "real-time event 34"); + AddSignal(47, "SIG35", false, false, false, "real-time event 35"); + AddSignal(48, "SIG36", false, false, false, "real-time event 36"); + AddSignal(49, "SIG37", false, false, false, "real-time event 37"); + AddSignal(50, "SIG38", false, false, false, "real-time event 38"); + AddSignal(51, "SIG39", false, false, false, "real-time event 39"); + AddSignal(52, "SIG40", false, false, false, "real-time event 40"); + AddSignal(53, "SIG41", false, false, false, "real-time event 41"); + AddSignal(54, "SIG42", false, false, false, "real-time event 42"); + AddSignal(55, "SIG43", false, false, false, "real-time event 43"); + AddSignal(56, "SIG44", false, false, false, "real-time event 44"); + AddSignal(57, "SIG45", false, false, false, "real-time event 45"); + AddSignal(58, "SIG46", false, false, false, "real-time event 46"); + AddSignal(59, "SIG47", false, false, false, "real-time event 47"); + AddSignal(60, "SIG48", false, false, false, "real-time event 48"); + AddSignal(61, "SIG49", false, false, false, "real-time event 49"); + AddSignal(62, "SIG50", false, false, false, "real-time event 50"); + AddSignal(63, "SIG51", false, false, false, "real-time event 51"); + AddSignal(64, "SIG52", false, false, false, "real-time event 52"); + AddSignal(65, "SIG53", false, false, false, "real-time event 53"); + AddSignal(66, "SIG54", false, false, false, "real-time event 54"); + AddSignal(67, "SIG55", false, false, false, "real-time event 55"); + AddSignal(68, "SIG56", false, false, false, "real-time event 56"); + AddSignal(69, "SIG57", false, false, false, "real-time event 57"); + AddSignal(70, "SIG58", false, false, false, "real-time event 58"); + AddSignal(71, "SIG59", false, false, false, "real-time event 59"); + AddSignal(72, "SIG60", false, false, false, "real-time event 60"); + AddSignal(73, "SIG61", false, false, false, "real-time event 61"); + AddSignal(74, "SIG62", false, false, false, "real-time event 62"); + AddSignal(75, "SIG63", false, false, false, "real-time event 63"); + + AddSignal(76, "SIGCANCEL", false, true, true, "LWP internal signal"); + + AddSignal(77, "SIG32", false, false, false, "real-time event 32"); + AddSignal(78, "SIG64", false, false, false, "real-time event 64"); + AddSignal(79, "SIG65", false, false, false, "real-time event 65"); + AddSignal(80, "SIG66", false, false, false, "real-time event 66"); + AddSignal(81, "SIG67", false, false, false, "real-time event 67"); + AddSignal(82, "SIG68", false, false, false, "real-time event 68"); + AddSignal(83, "SIG69", false, false, false, "real-time event 69"); + AddSignal(84, "SIG70", false, false, false, "real-time event 70"); + AddSignal(85, "SIG71", false, false, false, "real-time event 71"); + AddSignal(86, "SIG72", false, false, false, "real-time event 72"); + AddSignal(87, "SIG73", false, false, false, "real-time event 73"); + AddSignal(88, "SIG74", false, false, false, "real-time event 74"); + AddSignal(89, "SIG75", false, false, false, "real-time event 75"); + AddSignal(90, "SIG76", false, false, false, "real-time event 76"); + AddSignal(91, "SIG77", false, false, false, "real-time event 77"); + AddSignal(92, "SIG78", false, false, false, "real-time event 78"); + AddSignal(93, "SIG79", false, false, false, "real-time event 79"); + AddSignal(94, "SIG80", false, false, false, "real-time event 80"); + AddSignal(95, "SIG81", false, false, false, "real-time event 81"); + AddSignal(96, "SIG82", false, false, false, "real-time event 82"); + AddSignal(97, "SIG83", false, false, false, "real-time event 83"); + AddSignal(98, "SIG84", false, false, false, "real-time event 84"); + AddSignal(99, "SIG85", false, false, false, "real-time event 85"); + AddSignal(100, "SIG86", false, false, false, "real-time event 86"); + AddSignal(101, "SIG87", false, false, false, "real-time event 87"); + AddSignal(102, "SIG88", false, false, false, "real-time event 88"); + AddSignal(103, "SIG89", false, false, false, "real-time event 89"); + AddSignal(104, "SIG90", false, false, false, "real-time event 90"); + AddSignal(105, "SIG91", false, false, false, "real-time event 91"); + AddSignal(106, "SIG92", false, false, false, "real-time event 92"); + AddSignal(107, "SIG93", false, false, false, "real-time event 93"); + AddSignal(108, "SIG94", false, false, false, "real-time event 94"); + AddSignal(109, "SIG95", false, false, false, "real-time event 95"); + AddSignal(110, "SIG96", false, false, false, "real-time event 96"); + AddSignal(111, "SIG97", false, false, false, "real-time event 97"); + AddSignal(112, "SIG98", false, false, false, "real-time event 98"); + AddSignal(113, "SIG99", false, false, false, "real-time event 99"); + AddSignal(114, "SIG100", false, false, false, "real-time event 100"); + AddSignal(115, "SIG101", false, false, false, "real-time event 101"); + AddSignal(116, "SIG102", false, false, false, "real-time event 102"); + AddSignal(117, "SIG103", false, false, false, "real-time event 103"); + AddSignal(118, "SIG104", false, false, false, "real-time event 104"); + AddSignal(119, "SIG105", false, false, false, "real-time event 105"); + AddSignal(120, "SIG106", false, false, false, "real-time event 106"); + AddSignal(121, "SIG107", false, false, false, "real-time event 107"); + AddSignal(122, "SIG108", false, false, false, "real-time event 108"); + AddSignal(123, "SIG109", false, false, false, "real-time event 109"); + AddSignal(124, "SIG110", false, false, false, "real-time event 110"); + AddSignal(125, "SIG111", false, false, false, "real-time event 111"); + AddSignal(126, "SIG112", false, false, false, "real-time event 112"); + AddSignal(127, "SIG113", false, false, false, "real-time event 113"); + AddSignal(128, "SIG114", false, false, false, "real-time event 114"); + AddSignal(129, "SIG115", false, false, false, "real-time event 115"); + AddSignal(130, "SIG116", false, false, false, "real-time event 116"); + AddSignal(131, "SIG117", false, false, false, "real-time event 117"); + AddSignal(132, "SIG118", false, false, false, "real-time event 118"); + AddSignal(133, "SIG119", false, false, false, "real-time event 119"); + AddSignal(134, "SIG120", false, false, false, "real-time event 120"); + AddSignal(135, "SIG121", false, false, false, "real-time event 121"); + AddSignal(136, "SIG122", false, false, false, "real-time event 122"); + AddSignal(137, "SIG123", false, false, false, "real-time event 123"); + AddSignal(138, "SIG124", false, false, false, "real-time event 124"); + AddSignal(139, "SIG125", false, false, false, "real-time event 125"); + AddSignal(140, "SIG126", false, false, false, "real-time event 126"); + AddSignal(141, "SIG127", false, false, false, "real-time event 127"); + + AddSignal(142, "SIGINFO", false, true, true, "information request"); + AddSignal(143, "unknown", false, true, true, "unknown signal"); + + AddSignal(145, "EXC_BAD_ACCESS", false, true, true, "could not access memory"); + AddSignal(146, "EXC_BAD_INSTRUCTION", false, true, true, "illegal instruction/operand"); + AddSignal(147, "EXC_ARITHMETIC", false, true, true, "arithmetic exception"); + AddSignal(148, "EXC_EMULATION", false, true, true, "emulation instruction"); + AddSignal(149, "EXC_SOFTWARE", false, true, true, "software generated exception"); + AddSignal(150, "EXC_BREAKPOINT", false, true, true, "breakpoint"); + + AddSignal(151, "SIGLIBRT", false, true, true, "librt internal signal"); + + // clang-format on +} diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -433,6 +433,8 @@ bool GetMemoryTaggingSupported(); + bool UsesNativeSignals(); + lldb::DataBufferSP ReadMemoryTags(lldb::addr_t addr, size_t len, int32_t type); @@ -555,6 +557,7 @@ LazyBool m_supports_multiprocess = eLazyBoolCalculate; LazyBool m_supports_memory_tagging = eLazyBoolCalculate; LazyBool m_supports_qSaveCore = eLazyBoolCalculate; + LazyBool m_uses_native_signals = eLazyBoolCalculate; bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1, m_supports_qUserName : 1, m_supports_qGroupName : 1, diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -283,6 +283,7 @@ m_supports_qXfer_features_read = eLazyBoolCalculate; m_supports_qXfer_memory_map_read = eLazyBoolCalculate; m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate; + m_uses_native_signals = eLazyBoolCalculate; m_supports_qProcessInfoPID = true; m_supports_qfProcessInfo = true; m_supports_qUserName = true; @@ -333,6 +334,7 @@ m_supports_QPassSignals = eLazyBoolNo; m_supports_memory_tagging = eLazyBoolNo; m_supports_qSaveCore = eLazyBoolNo; + m_uses_native_signals = eLazyBoolNo; m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if // not, we assume no limit @@ -379,6 +381,8 @@ m_supports_memory_tagging = eLazyBoolYes; else if (x == "qSaveCore+") m_supports_qSaveCore = eLazyBoolYes; + else if (x == "native-signals+") + m_uses_native_signals = eLazyBoolYes; // Look for a list of compressions in the features list e.g. // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib- // deflate,lzma @@ -4220,3 +4224,14 @@ GDBRemoteClientBase::OnRunPacketSent(first); m_curr_tid = LLDB_INVALID_THREAD_ID; } + +bool GDBRemoteCommunicationClient::UsesNativeSignals() { + if (m_uses_native_signals == eLazyBoolCalculate) + GetRemoteQSupported(); + if (m_uses_native_signals == eLazyBoolYes) + return true; + + // If the remote didn't indicate native-signal support explicitly, + // check whether it is an old version of lldb-server. + return GetThreadSuffixSupported(); +} diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -1346,5 +1346,6 @@ llvm::formatv("PacketSize={0}", max_packet_size), "QStartNoAckMode+", "qEcho+", + "native-signals+", }; } diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -607,14 +607,6 @@ __FUNCTION__, GetID(), GetTarget().GetArchitecture().GetTriple().getTriple().c_str()); - if (error.Success()) { - PlatformSP platform_sp = GetTarget().GetPlatform(); - if (platform_sp && platform_sp->IsConnected()) - SetUnixSignals(platform_sp->GetUnixSignals()); - else - SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture())); - } - return error; } @@ -980,6 +972,18 @@ if (StructuredData::Array *supported_packets = m_gdb_comm.GetSupportedStructuredDataPlugins()) MapSupportedStructuredDataPlugins(*supported_packets); + + // If connected to LLDB ("native-signals+"), use signal defs for + // the remote platform. If connected to GDB, just use the standard set. + if (!m_gdb_comm.UsesNativeSignals()) { + SetUnixSignals(std::make_shared()); + } else { + PlatformSP platform_sp = GetTarget().GetPlatform(); + if (platform_sp && platform_sp->IsConnected()) + SetUnixSignals(platform_sp->GetUnixSignals()); + else + SetUnixSignals(UnixSignals::Create(GetTarget().GetArchitecture())); + } } void ProcessGDBRemote::MaybeLoadExecutableModule() { diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py --- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py +++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py @@ -412,3 +412,75 @@ process = self.connect(target) process.Detach() self.assertRegex(self.server.responder.detached, r"D;0*400") + + def test_signal_gdb(self): + class MyResponder(MockGDBServerResponder): + def qSupported(self, client_supported): + return "PacketSize=3fff;QStartNoAckMode+" + + def haltReason(self): + return "S0a" + + def cont(self): + return self.haltReason() + + self.server.responder = MyResponder() + + target = self.createTarget("a.yaml") + process = self.connect(target) + + self.assertEqual(process.threads[0].GetStopReason(), + lldb.eStopReasonSignal) + self.assertEqual(process.threads[0].GetStopDescription(100), + 'signal SIGBUS') + + def test_signal_lldb_old(self): + class MyResponder(MockGDBServerResponder): + def qSupported(self, client_supported): + return "PacketSize=3fff;QStartNoAckMode+" + + def qHostInfo(self): + return "triple:61726d76372d756e6b6e6f776e2d6c696e75782d676e75;" + + def QThreadSuffixSupported(self): + return "OK" + + def haltReason(self): + return "S0a" + + def cont(self): + return self.haltReason() + + self.server.responder = MyResponder() + + target = self.createTarget("a.yaml") + process = self.connect(target) + + self.assertEqual(process.threads[0].GetStopReason(), + lldb.eStopReasonSignal) + self.assertEqual(process.threads[0].GetStopDescription(100), + 'signal SIGUSR1') + + def test_signal_lldb(self): + class MyResponder(MockGDBServerResponder): + def qSupported(self, client_supported): + return "PacketSize=3fff;QStartNoAckMode+;native-signals+" + + def qHostInfo(self): + return "triple:61726d76372d756e6b6e6f776e2d6c696e75782d676e75;" + + def haltReason(self): + return "S0a" + + def cont(self): + return self.haltReason() + + self.server.responder = MyResponder() + + target = self.createTarget("a.yaml") + process = self.connect(target) + + self.assertEqual(process.threads[0].GetStopReason(), + lldb.eStopReasonSignal) + self.assertEqual(process.threads[0].GetStopDescription(100), + 'signal SIGUSR1') diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp --- a/lldb/tools/debugserver/source/RNBRemote.cpp +++ b/lldb/tools/debugserver/source/RNBRemote.cpp @@ -3462,7 +3462,8 @@ uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet // size--debugger can always use less char buf[256]; - snprintf(buf, sizeof(buf), "qXfer:features:read+;PacketSize=%x;qEcho+", + snprintf(buf, sizeof(buf), + "qXfer:features:read+;PacketSize=%x;qEcho+;native-signals+", max_packet_size); bool enable_compression = false;