1""" 2Test some lldb command abbreviations. 3""" 4 5import lldb 6from lldbsuite.test.decorators import * 7from lldbsuite.test.lldbtest import * 8from lldbsuite.test import lldbutil 9 10 11class ExecTestCase(TestBase): 12 NO_DEBUG_INFO_TESTCASE = True 13 14 @expectedFailureAll( 15 archs=["i386"], oslist=no_match(["freebsd"]), bugnumber="rdar://28656532" 16 ) 17 @expectedFailureAll( 18 oslist=["ios", "tvos", "watchos", "bridgeos"], 19 bugnumber="rdar://problem/34559552", 20 ) # this exec test has problems on ios systems 21 @expectedFailureNetBSD 22 @skipIfAsan # rdar://problem/43756823 23 @skipIfWindows 24 def test_hitting_exec(self): 25 self.do_test(False) 26 27 @expectedFailureAll( 28 archs=["i386"], oslist=no_match(["freebsd"]), bugnumber="rdar://28656532" 29 ) 30 @expectedFailureAll( 31 oslist=["ios", "tvos", "watchos", "bridgeos"], 32 bugnumber="rdar://problem/34559552", 33 ) # this exec test has problems on ios systems 34 @expectedFailureNetBSD 35 @skipIfAsan # rdar://problem/43756823 36 @skipIfWindows 37 def test_skipping_exec(self): 38 self.do_test(True) 39 40 def do_test(self, skip_exec): 41 self.build() 42 exe = self.getBuildArtifact("a.out") 43 secondprog = self.getBuildArtifact("secondprog") 44 45 # Create the target 46 target = self.dbg.CreateTarget(exe) 47 48 lldbutil.install_to_target(self, secondprog) 49 50 # Create any breakpoints we need 51 breakpoint1 = target.BreakpointCreateBySourceRegex( 52 "Set breakpoint 1 here", lldb.SBFileSpec("main.c", False) 53 ) 54 self.assertTrue(breakpoint1, VALID_BREAKPOINT) 55 breakpoint2 = target.BreakpointCreateBySourceRegex( 56 "Set breakpoint 2 here", lldb.SBFileSpec("secondprog.cpp", False) 57 ) 58 self.assertTrue(breakpoint2, VALID_BREAKPOINT) 59 60 # Launch the process 61 process = target.LaunchSimple(None, None, self.get_process_working_directory()) 62 self.assertTrue(process, PROCESS_IS_VALID) 63 64 if self.TraceOn(): 65 self.runCmd("settings show target.process.stop-on-exec", check=False) 66 if skip_exec: 67 self.dbg.HandleCommand("settings set target.process.stop-on-exec false") 68 69 def cleanup(): 70 self.runCmd( 71 "settings set target.process.stop-on-exec false", check=False 72 ) 73 74 # Execute the cleanup function during test case tear down. 75 self.addTearDownHook(cleanup) 76 77 # The stop reason of the thread should be breakpoint. 78 self.assertState( 79 process.GetState(), lldb.eStateStopped, STOPPED_DUE_TO_BREAKPOINT 80 ) 81 82 threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint1) 83 self.assertEqual(len(threads), 1) 84 85 # We had a deadlock tearing down the TypeSystemMap on exec, but only if some 86 # expression had been evaluated. So make sure we do that here so the teardown 87 # is not trivial. 88 89 thread = threads[0] 90 value = thread.frames[0].EvaluateExpression("1 + 2") 91 self.assertTrue(value.IsValid(), "Expression evaluated successfully") 92 int_value = value.GetValueAsSigned() 93 self.assertEqual(int_value, 3, "Expression got the right result.") 94 95 # Run and we should stop due to exec 96 process.Continue() 97 98 if not skip_exec: 99 self.assertNotEqual( 100 process.GetState(), lldb.eStateExited, "Process should not have exited!" 101 ) 102 self.assertState( 103 process.GetState(), 104 lldb.eStateStopped, 105 "Process should be stopped at __dyld_start", 106 ) 107 108 threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonExec) 109 self.assertEqual(len(threads), 1, "We got a thread stopped for exec.") 110 111 # Run and we should stop at breakpoint in main after exec 112 process.Continue() 113 114 self.assertState(process.GetState(), lldb.eStateStopped) 115 for t in process.threads: 116 if t.stop_reason != lldb.eStopReasonNone: 117 self.assertStopReason( 118 t.stop_reason, lldb.eStopReasonBreakpoint, "Unexpected stop reason" 119 ) 120 if self.TraceOn(): 121 print(t) 122 if t.stop_reason != lldb.eStopReasonBreakpoint: 123 self.runCmd("bt") 124 125 threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint2) 126 self.assertEqual(len(threads), 1, "Stopped at breakpoint in exec'ed process.") 127 128 @expectedFailureAll( 129 archs=["i386"], oslist=no_match(["freebsd"]), bugnumber="rdar://28656532" 130 ) 131 @expectedFailureAll( 132 oslist=["ios", "tvos", "watchos", "bridgeos"], 133 bugnumber="rdar://problem/34559552", 134 ) # this exec test has problems on ios systems 135 @expectedFailureNetBSD 136 @skipIfAsan # rdar://problem/43756823 137 @skipIfWindows 138 def test_correct_thread_plan_state_before_exec(self): 139 """ 140 In this test we make sure that the Thread* cache in the ThreadPlans 141 is cleared correctly when performing exec 142 """ 143 144 self.build() 145 exe = self.getBuildArtifact("a.out") 146 target = self.dbg.CreateTarget(exe) 147 148 lldbutil.install_to_target(self, self.getBuildArtifact("secondprog")) 149 150 (target, process, thread, breakpoint1) = lldbutil.run_to_source_breakpoint( 151 self, "Set breakpoint 1 here", lldb.SBFileSpec("main.c", False) 152 ) 153 154 # The stop reason of the thread should be breakpoint. 155 self.assertState( 156 process.GetState(), lldb.eStateStopped, STOPPED_DUE_TO_BREAKPOINT 157 ) 158 159 threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint1) 160 self.assertEqual(len(threads), 1) 161 162 # We perform an instruction step, which effectively sets the cache of the base 163 # thread plan, which should be cleared when a new thread list appears. 164 # 165 # Continuing after this instruction step will trigger a call to 166 # ThreadPlan::ShouldReportRun, which sets the ThreadPlan's Thread cache to 167 # the old Thread* value. In Process::UpdateThreadList we are clearing this 168 # cache in preparation for the new ThreadList. 169 # 170 # Not doing this stepping will cause LLDB to first execute a private single step 171 # past the current breakpoint, which eventually avoids the call to ShouldReportRun, 172 # thus not setting the cache to its invalid value. 173 thread.StepInstruction(False) 174 175 # Run and we should stop due to exec 176 breakpoint2 = target.BreakpointCreateBySourceRegex( 177 "Set breakpoint 2 here", lldb.SBFileSpec("secondprog.cpp", False) 178 ) 179 180 process.Continue() 181 182 self.assertNotEqual( 183 process.GetState(), lldb.eStateExited, "Process should not have exited!" 184 ) 185 self.assertState( 186 process.GetState(), 187 lldb.eStateStopped, 188 "Process should be stopped at __dyld_start", 189 ) 190 191 threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonExec) 192 self.assertEqual(len(threads), 1, "We got a thread stopped for exec.") 193 194 # Run and we should stop at breakpoint in main after exec 195 process.Continue() 196 197 threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint2) 198 self.assertEqual(len(threads), 1, "Stopped at breakpoint in exec'ed process.") 199