1"""Test that lldb command 'process signal SIGUSR1' to send a signal to the inferior works.""" 2 3 4import lldb 5from lldbsuite.test.decorators import * 6from lldbsuite.test.lldbtest import * 7from lldbsuite.test import lldbutil 8 9 10class SendSignalTestCase(TestBase): 11 def setUp(self): 12 # Call super's setUp(). 13 TestBase.setUp(self) 14 # Find the line number to break inside main(). 15 self.line = line_number("main.c", "Put breakpoint here") 16 17 @expectedFailureNetBSD(bugnumber="llvm.org/pr43959") 18 @skipIfWindows # Windows does not support signals 19 def test_with_run_command(self): 20 """Test that lldb command 'process signal SIGUSR1' sends a signal to the inferior process.""" 21 self.build() 22 exe = self.getBuildArtifact("a.out") 23 24 # Create a target by the debugger. 25 target = self.dbg.CreateTarget(exe) 26 self.assertTrue(target, VALID_TARGET) 27 28 # Now create a breakpoint on main.c by name 'c'. 29 breakpoint = target.BreakpointCreateByLocation("main.c", self.line) 30 self.assertTrue( 31 breakpoint and breakpoint.GetNumLocations() == 1, VALID_BREAKPOINT 32 ) 33 34 # Get the breakpoint location from breakpoint after we verified that, 35 # indeed, it has one location. 36 location = breakpoint.GetLocationAtIndex(0) 37 self.assertTrue(location and location.IsEnabled(), VALID_BREAKPOINT_LOCATION) 38 39 # Now launch the process, no arguments & do not stop at entry point. 40 launch_info = target.GetLaunchInfo() 41 launch_info.SetWorkingDirectory(self.get_process_working_directory()) 42 43 process_listener = lldb.SBListener("signal_test_listener") 44 launch_info.SetListener(process_listener) 45 error = lldb.SBError() 46 process = target.Launch(launch_info, error) 47 self.assertTrue(process, PROCESS_IS_VALID) 48 49 self.runCmd("process handle -n False -p True -s True SIGUSR1") 50 51 thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint) 52 self.assertTrue(thread.IsValid(), "We hit the first breakpoint.") 53 54 # After resuming the process, send it a SIGUSR1 signal. 55 56 self.setAsync(True) 57 58 self.assertTrue(process_listener.IsValid(), "Got a good process listener") 59 60 # Disable our breakpoint, we don't want to hit it anymore... 61 breakpoint.SetEnabled(False) 62 63 # Now continue: 64 process.Continue() 65 66 self.match_state(process_listener, lldb.eStateRunning) 67 68 # Now signal the process, and make sure it stops: 69 process.Signal(lldbutil.get_signal_number("SIGUSR1")) 70 71 self.match_state(process_listener, lldb.eStateStopped) 72 73 # Now make sure the thread was stopped with a SIGUSR1: 74 threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonSignal) 75 self.assertEqual(len(threads), 1, "One thread stopped for a signal.") 76 thread = threads[0] 77 78 self.assertGreaterEqual( 79 thread.GetStopReasonDataCount(), 1, "There was data in the event." 80 ) 81 self.assertEqual( 82 thread.GetStopReasonDataAtIndex(0), 83 lldbutil.get_signal_number("SIGUSR1"), 84 "The stop signal was SIGUSR1", 85 ) 86 87 self.match("statistics dump", [r'"signals": \[', r'"SIGUSR1": 1']) 88 89 def match_state(self, process_listener, expected_state): 90 num_seconds = 5 91 broadcaster = self.process().GetBroadcaster() 92 event_type_mask = lldb.SBProcess.eBroadcastBitStateChanged 93 event = lldb.SBEvent() 94 got_event = process_listener.WaitForEventForBroadcasterWithType( 95 num_seconds, broadcaster, event_type_mask, event 96 ) 97 self.assertTrue(got_event, "Got an event") 98 state = lldb.SBProcess.GetStateFromEvent(event) 99 self.assertEqual( 100 state, 101 expected_state, 102 "It was the %s state." % lldb.SBDebugger.StateAsCString(expected_state), 103 ) 104