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