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