1import lldb 2from lldbsuite.test.lldbtest import * 3from lldbsuite.test import lldbutil 4from lldbsuite.test.decorators import * 5 6 7class TestProcessHandle(TestBase): 8 @no_debug_info_test 9 @skipIfWindows 10 def test_process_handle(self): 11 """Test that calling process handle before we have a target, and before we 12 have a process will affect the process. Also that the signal settings 13 are preserved on rerun.""" 14 self.build() 15 16 # Make sure we don't accept signal values by signo with no process - we don't know what the 17 # mapping will be so we can't do the right thing with bare numbers: 18 lldbutil.set_actions_for_signal( 19 self, "9", "true", None, None, expect_success=False 20 ) 21 22 # First, I need a reference value so I can see whether changes actually took: 23 (target, process, _, bkpt) = lldbutil.run_to_source_breakpoint( 24 self, "// break here", lldb.SBFileSpec("main.cpp") 25 ) 26 (default_pass, default_stop, default_notify) = lldbutil.get_actions_for_signal( 27 self, "SIGSEGV" 28 ) 29 30 # Let's change the value here, then exit and make sure the changed value sticks: 31 new_value = "false" 32 if default_pass == "true": 33 new_value = "false" 34 35 # First make sure we get an error for bogus values when running: 36 lldbutil.set_actions_for_signal( 37 self, "NOTSIGSEGV", new_value, None, None, expect_success=False 38 ) 39 40 # Then set the one we intend to change. 41 lldbutil.set_actions_for_signal(self, "SIGSEGV", new_value, None, None) 42 43 process.Continue() 44 45 self.assertState(process.GetState(), lldb.eStateExited) 46 self.assertEqual(process.GetExitStatus(), 0) 47 48 # Check that we preserved the setting: 49 (curr_pass, curr_stop, curr_notify) = lldbutil.get_actions_for_signal( 50 self, "SIGSEGV", from_target=True 51 ) 52 self.assertEqual(curr_pass, new_value, "Pass was set correctly") 53 self.assertEqual(curr_stop, "not set", "Stop was not set by us") 54 self.assertEqual(curr_notify, "not set", "Notify was not set by us") 55 56 # Run again and make sure that we prime the new process with these settings: 57 process = lldbutil.run_to_breakpoint_do_run(self, target, bkpt) 58 59 # We check the process settings now, to see what got copied into the process: 60 (curr_pass, curr_stop, curr_notify) = lldbutil.get_actions_for_signal( 61 self, "SIGSEGV" 62 ) 63 self.assertEqual(curr_pass, new_value, "Pass was set correctly") 64 self.assertEqual(curr_stop, default_stop, "Stop was its default value") 65 self.assertEqual(curr_notify, default_notify, "Notify was its default value") 66 67 # Now kill this target, set the handling and make sure the values get copied from the dummy into the new target. 68 success = self.dbg.DeleteTarget(target) 69 self.assertTrue(success, "Deleted the target") 70 self.assertEqual(self.dbg.GetNumTargets(), 0, "We did delete all the targets.") 71 72 # The signal settings should be back at their default - we were only setting this on the target: 73 lldbutil.get_actions_for_signal( 74 self, "SIGSEGV", from_target=True, expected_absent=True 75 ) 76 # Set a valid one: 77 lldbutil.set_actions_for_signal(self, "SIGSEGV", new_value, None, None) 78 # Set a bogus one - we don't have a way to check pre-run so this is allowed 79 # but we should get an error message when launching: 80 lldbutil.set_actions_for_signal(self, "SIGNOTSIG", new_value, None, None) 81 82 out_filename = self.getBuildArtifact("output") 83 success = True 84 try: 85 f = open(out_filename, "w") 86 except: 87 success = False 88 89 if not success: 90 self.fail("Couldn't open error output file for writing.") 91 92 self.dbg.SetErrorFileHandle(f, False) 93 # Now make a new process and make sure the right values got copied into the new target 94 (target, process, _, bkpt) = lldbutil.run_to_source_breakpoint( 95 self, "// break here", lldb.SBFileSpec("main.cpp") 96 ) 97 f.write("TESTPATTERN\n") 98 f.flush() 99 f.close() 100 101 try: 102 f = open(out_filename, "r") 103 except: 104 success = False 105 106 if not success: 107 self.fail("Couldn't open error output file for reading") 108 errors = f.read() 109 f.close() 110 111 self.assertIn("SIGNOTSIG", errors, "We warned about the unset signal") 112 # Also make sure we didn't accidentally add this bogus setting to the process. 113 lldbutil.set_actions_for_signal( 114 self, "SIGNOTSIG", "true", "true", "true", expect_success=False 115 ) 116 117 # Check that they went into the target: 118 (curr_pass, curr_stop, curr_notify) = lldbutil.get_actions_for_signal( 119 self, "SIGSEGV", from_target=True 120 ) 121 self.assertEqual(curr_pass, new_value, "Pass was set correctly") 122 self.assertEqual(curr_stop, "not set", "Stop was not set by us") 123 self.assertEqual(curr_notify, "not set", "Notify was not set by us") 124 125 # And the process: 126 # Check that they went into the target: 127 (curr_pass, curr_stop, curr_notify) = lldbutil.get_actions_for_signal( 128 self, "SIGSEGV" 129 ) 130 self.assertEqual(curr_pass, new_value, "Pass was set correctly") 131 self.assertEqual(curr_stop, default_stop, "Stop was its default value") 132 self.assertEqual(curr_notify, default_notify, "Notify was its default value") 133 134 # Now clear the handling, and make sure that we get the right signal values again: 135 self.runCmd("process handle -c SIGSEGV") 136 # Check that there is no longer configuration for SIGSEGV in the target: 137 lldbutil.get_actions_for_signal( 138 self, "SIGSEGV", from_target=True, expected_absent=True 139 ) 140 # Make a new process, to make sure we did indeed reset the values: 141 (target, process, _, bkpt) = lldbutil.run_to_source_breakpoint( 142 self, "// break here", lldb.SBFileSpec("main.cpp") 143 ) 144 (curr_pass, curr_stop, curr_notify) = lldbutil.get_actions_for_signal( 145 self, "SIGSEGV" 146 ) 147 self.assertEqual(curr_pass, new_value, "Pass was set correctly") 148 self.assertEqual(curr_stop, default_stop, "Stop was its default value") 149 self.assertEqual(curr_notify, default_notify, "Notify was its default value") 150 151 # Finally remove this from the dummy target as well, and make sure it was cleared from there: 152 self.runCmd("process handle -c -d SIGSEGV") 153 error = process.Kill() 154 self.assertSuccess(error, "Killed the process") 155 success = self.dbg.DeleteTarget(target) 156 self.assertTrue(success, "Destroyed the target.") 157 158 (target, process, _, bkpt) = lldbutil.run_to_source_breakpoint( 159 self, "// break here", lldb.SBFileSpec("main.cpp") 160 ) 161 (curr_pass, curr_stop, curr_notify) = lldbutil.get_actions_for_signal( 162 self, "SIGSEGV" 163 ) 164 self.assertEqual(curr_pass, default_pass, "Pass was set correctly") 165 self.assertEqual(curr_stop, default_stop, "Stop was its default value") 166 self.assertEqual(curr_notify, default_notify, "Notify was its default value") 167