1"""Test that we handle inferiors that send signals to themselves""" 2 3 4 5import lldb 6import re 7from lldbsuite.test.lldbplatformutil import getDarwinOSTriples 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbutil 11 12 13@skipIfWindows # signals do not exist on Windows 14class RaiseTestCase(TestBase): 15 16 mydir = TestBase.compute_mydir(__file__) 17 NO_DEBUG_INFO_TESTCASE = True 18 19 @skipIfNetBSD # Hangs on NetBSD 20 def test_sigstop(self): 21 self.build() 22 self.signal_test('SIGSTOP', False) 23 # passing of SIGSTOP is not correctly handled, so not testing that 24 # scenario: https://llvm.org/bugs/show_bug.cgi?id=23574 25 26 @skipIfDarwin # darwin does not support real time signals 27 @skipIfTargetAndroid() 28 def test_sigsigrtmin(self): 29 self.build() 30 self.signal_test('SIGRTMIN', True) 31 32 @skipIfNetBSD # Hangs on NetBSD 33 def test_sigtrap(self): 34 self.build() 35 self.signal_test('SIGTRAP', True) 36 37 def launch(self, target, signal): 38 # launch the process, do not stop at entry point. 39 process = target.LaunchSimple( 40 [signal], None, self.get_process_working_directory()) 41 self.assertTrue(process, PROCESS_IS_VALID) 42 self.assertEqual(process.GetState(), lldb.eStateStopped) 43 thread = lldbutil.get_stopped_thread( 44 process, lldb.eStopReasonBreakpoint) 45 self.assertTrue( 46 thread.IsValid(), 47 "Thread should be stopped due to a breakpoint") 48 return process 49 50 def set_handle(self, signal, pass_signal, stop_at_signal, notify_signal): 51 return_obj = lldb.SBCommandReturnObject() 52 self.dbg.GetCommandInterpreter().HandleCommand( 53 "process handle %s -p %s -s %s -n %s" % 54 (signal, pass_signal, stop_at_signal, notify_signal), return_obj) 55 self.assertTrue( 56 return_obj.Succeeded(), 57 "Setting signal handling failed") 58 59 def signal_test(self, signal, test_passing): 60 """Test that we handle inferior raising signals""" 61 exe = self.getBuildArtifact("a.out") 62 63 # Create a target by the debugger. 64 target = self.dbg.CreateTarget(exe) 65 self.assertTrue(target, VALID_TARGET) 66 lldbutil.run_break_set_by_symbol(self, "main") 67 68 # launch 69 process = self.launch(target, signal) 70 signo = process.GetUnixSignals().GetSignalNumberFromName(signal) 71 72 # retrieve default signal disposition 73 return_obj = lldb.SBCommandReturnObject() 74 self.dbg.GetCommandInterpreter().HandleCommand( 75 "process handle %s " % signal, return_obj) 76 match = re.match( 77 'NAME *PASS *STOP *NOTIFY.*(false|true) *(false|true) *(false|true)', 78 return_obj.GetOutput(), 79 re.IGNORECASE | re.DOTALL) 80 if not match: 81 self.fail('Unable to retrieve default signal disposition.') 82 default_pass = match.group(1) 83 default_stop = match.group(2) 84 default_notify = match.group(3) 85 86 # Make sure we stop at the signal 87 self.set_handle(signal, "false", "true", "true") 88 process.Continue() 89 self.assertEqual(process.GetState(), lldb.eStateStopped) 90 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal) 91 self.assertTrue( 92 thread.IsValid(), 93 "Thread should be stopped due to a signal") 94 self.assertTrue( 95 thread.GetStopReasonDataCount() >= 1, 96 "There was data in the event.") 97 self.assertEqual(thread.GetStopReasonDataAtIndex(0), signo, 98 "The stop signal was %s" % signal) 99 100 # Continue until we exit. 101 process.Continue() 102 self.assertEqual(process.GetState(), lldb.eStateExited) 103 self.assertEqual(process.GetExitStatus(), 0) 104 105 # launch again 106 process = self.launch(target, signal) 107 108 # Make sure we do not stop at the signal. We should still get the 109 # notification. 110 self.set_handle(signal, "false", "false", "true") 111 self.expect( 112 "process continue", 113 substrs=[ 114 "stopped and restarted", 115 signal]) 116 self.assertEqual(process.GetState(), lldb.eStateExited) 117 self.assertEqual(process.GetExitStatus(), 0) 118 119 # launch again 120 process = self.launch(target, signal) 121 122 # Make sure we do not stop at the signal, and we do not get the 123 # notification. 124 self.set_handle(signal, "false", "false", "false") 125 self.expect( 126 "process continue", 127 substrs=["stopped and restarted"], 128 matching=False) 129 self.assertEqual(process.GetState(), lldb.eStateExited) 130 self.assertEqual(process.GetExitStatus(), 0) 131 132 if not test_passing: 133 # reset signal handling to default 134 self.set_handle(signal, default_pass, default_stop, default_notify) 135 return 136 137 # launch again 138 process = self.launch(target, signal) 139 140 # Make sure we stop at the signal 141 self.set_handle(signal, "true", "true", "true") 142 process.Continue() 143 self.assertEqual(process.GetState(), lldb.eStateStopped) 144 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonSignal) 145 self.assertTrue( 146 thread.IsValid(), 147 "Thread should be stopped due to a signal") 148 self.assertTrue( 149 thread.GetStopReasonDataCount() >= 1, 150 "There was data in the event.") 151 self.assertEqual( 152 thread.GetStopReasonDataAtIndex(0), 153 process.GetUnixSignals().GetSignalNumberFromName(signal), 154 "The stop signal was %s" % 155 signal) 156 157 # Continue until we exit. The process should receive the signal. 158 process.Continue() 159 self.assertEqual(process.GetState(), lldb.eStateExited) 160 self.assertEqual(process.GetExitStatus(), signo) 161 162 # launch again 163 process = self.launch(target, signal) 164 165 # Make sure we do not stop at the signal. We should still get the notification. Process 166 # should receive the signal. 167 self.set_handle(signal, "true", "false", "true") 168 self.expect( 169 "process continue", 170 substrs=[ 171 "stopped and restarted", 172 signal]) 173 self.assertEqual(process.GetState(), lldb.eStateExited) 174 self.assertEqual(process.GetExitStatus(), signo) 175 176 # launch again 177 process = self.launch(target, signal) 178 179 # Make sure we do not stop at the signal, and we do not get the notification. Process 180 # should receive the signal. 181 self.set_handle(signal, "true", "false", "false") 182 self.expect( 183 "process continue", 184 substrs=["stopped and restarted"], 185 matching=False) 186 self.assertEqual(process.GetState(), lldb.eStateExited) 187 self.assertEqual(process.GetExitStatus(), signo) 188 189 # reset signal handling to default 190 self.set_handle(signal, default_pass, default_stop, default_notify) 191