1 # This test makes sure that lldb-server supports and properly handles
2 # QPassSignals GDB protocol package.
4 import gdbremote_testcase
5 from lldbsuite.test.decorators import *
6 from lldbsuite.test.lldbtest import *
7 from lldbsuite.test import lldbutil
9 class TestGdbRemote_QPassSignals(gdbremote_testcase.GdbRemoteTestCaseBase):
11 mydir = TestBase.compute_mydir(__file__)
13 def expect_signal(self, expected_signo):
14 self.test_sequence.add_log_lines(["read packet: $vCont;c#a8",
16 "regex": r"^\$T([0-9a-fA-F]{2}).*#[0-9a-fA-F]{2}$",
17 "capture": {1: "hex_exit_code"}},
21 context = self.expect_gdbremote_sequence()
22 self.assertIsNotNone(context)
24 hex_exit_code = context.get("hex_exit_code")
25 self.assertIsNotNone(hex_exit_code)
26 self.assertEqual(int(hex_exit_code, 16), expected_signo)
28 def expect_exit_code(self, exit_code):
29 self.test_sequence.add_log_lines(
30 ["read packet: $vCont;c#a8",
31 "send packet: $W{0:02x}#00".format(exit_code)],
33 self.expect_gdbremote_sequence()
36 def ignore_signals(self, signals):
37 def signal_name_to_hex(signame):
38 return format(lldbutil.get_signal_number(signame), 'x')
39 signals_str = ";".join(map(signal_name_to_hex, signals))
41 self.test_sequence.add_log_lines(["read packet: $QPassSignals:"
42 + signals_str + " #00",
43 "send packet: $OK#00"],
46 context = self.expect_gdbremote_sequence()
47 self.assertIsNotNone(context)
50 @skipUnlessPlatform(["linux", "android"])
51 def test_q_pass_signals(self):
54 self.set_inferior_startup_launch()
55 procs = self.prep_debug_monitor_and_inferior()
56 expected_signals = ["SIGSEGV",
57 "SIGALRM", "SIGFPE", "SIGBUS", "SIGINT", "SIGHUP"]
58 signals_to_ignore = ["SIGUSR1", "SIGUSR2"]
59 self.ignore_signals(signals_to_ignore)
60 for signal_name in expected_signals:
61 signo = lldbutil.get_signal_number(signal_name)
62 self.expect_signal(signo)
63 self.expect_exit_code(len(signals_to_ignore))
66 @skipUnlessPlatform(["linux", "android"])
67 def test_change_signals_at_runtime(self):
70 self.set_inferior_startup_launch()
71 procs = self.prep_debug_monitor_and_inferior()
72 expected_signals = ["SIGSEGV", "SIGUSR1", "SIGUSR2",
74 signals_to_ignore = ["SIGFPE", "SIGBUS", "SIGINT"]
76 for signal_name in expected_signals:
77 signo = lldbutil.get_signal_number(signal_name)
78 self.expect_signal(signo)
79 if signal_name == "SIGALRM":
80 self.ignore_signals(signals_to_ignore)
81 self.expect_exit_code(len(signals_to_ignore))
83 @skipIfWindows # no signal support
84 @expectedFailureNetBSD
86 def test_default_signals_behavior(self):
89 self.set_inferior_startup_launch()
90 procs = self.prep_debug_monitor_and_inferior()
91 expected_signals = ["SIGSEGV", "SIGUSR1", "SIGUSR2",
92 "SIGALRM", "SIGFPE", "SIGBUS", "SIGINT", "SIGHUP"]
93 for signal_name in expected_signals:
94 signo = lldbutil.get_signal_number(signal_name)
95 self.expect_signal(signo)
96 self.expect_exit_code(0)
100 @skipUnlessPlatform(["linux", "android"])
101 def test_support_q_pass_signals(self):
102 self.init_llgs_test()
105 # Start up the stub and start/prep the inferior.
106 self.set_inferior_startup_launch()
107 procs = self.prep_debug_monitor_and_inferior()
108 self.add_qSupported_packets()
110 # Run the packet stream.
111 context = self.expect_gdbremote_sequence()
112 self.assertIsNotNone(context)
114 # Retrieve the qSupported features and check QPassSignals+
115 supported_dict = self.parse_qSupported_response(context)
116 self.assertEqual(supported_dict["QPassSignals"], "+")