Index: test/functionalities/attach_resume/TestAttachResume.py =================================================================== --- test/functionalities/attach_resume/TestAttachResume.py +++ test/functionalities/attach_resume/TestAttachResume.py @@ -14,7 +14,6 @@ mydir = TestBase.compute_mydir(__file__) - @expectedFlakeyLinux('llvm.org/pr19310') @expectedFailureFreeBSD('llvm.org/pr19310') @skipIfRemote @dwarf_test @@ -23,7 +22,6 @@ self.buildDwarf() self.process_attach_continue_interrupt_detach() - @expectedFlakeyLinux('llvm.org/pr19478') # intermittent ~2/14 runs @skipIfRemote def process_attach_continue_interrupt_detach(self): """Test attach/continue/interrupt/detach""" @@ -35,67 +33,39 @@ self.runCmd("process attach -p " + str(popen.pid)) - self._state = 0 - def process_events(): - event = lldb.SBEvent() - while self.dbg.GetListener().GetNextEvent(event): - self._state = lldb.SBProcess.GetStateFromEvent(event) - - # using process.GetState() does not work: llvm.org/pr16172 - def wait_for_state(s, timeout=5): - t = 0 - period = 0.1 - while self._state != s: - process_events() - time.sleep(period) - t += period - if t > timeout: - return False - return True - self.setAsync(True) + listener = self.dbg.GetListener() self.runCmd("c") - self.assertTrue(wait_for_state(lldb.eStateRunning), - 'Process not running after continue') + lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning]) self.runCmd("process interrupt") - self.assertTrue(wait_for_state(lldb.eStateStopped), - 'Process not stopped after interrupt') + lldbutil.expect_state_changes(self, listener, [lldb.eStateStopped]) # be sure to continue/interrupt/continue (r204504) self.runCmd("c") - self.assertTrue(wait_for_state(lldb.eStateRunning), - 'Process not running after continue') + lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning]) self.runCmd("process interrupt") - self.assertTrue(wait_for_state(lldb.eStateStopped), - 'Process not stopped after interrupt') + lldbutil.expect_state_changes(self, listener, [lldb.eStateStopped]) # check that this breakpoint is auto-cleared on detach (r204752) self.runCmd("br set -f main.cpp -l %u" % (line_number('main.cpp', '// Set breakpoint here'))) self.runCmd("c") - self.assertTrue(wait_for_state(lldb.eStateRunning), - 'Process not running after continue') - - self.assertTrue(wait_for_state(lldb.eStateStopped), - 'Process not stopped after breakpoint') - # This test runs a bunch of threads in the same little function with this - # breakpoint. We want to make sure the breakpoint got hit at least once, - # but more than one thread may hit it at a time. So we really only care - # that is isn't 0 times, not how many times it is. + lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning, lldb.eStateStopped]) self.expect('br list', 'Breakpoint not hit', - patterns = ['hit count = [1-9]']) + substrs = ['hit count = 1']) + + # Make sure the breakpoint is not hit again. + self.expect("expr debugger_flag = false", substrs=[" = false"]); self.runCmd("c") - self.assertTrue(wait_for_state(lldb.eStateRunning), - 'Process not running after continue') + lldbutil.expect_state_changes(self, listener, [lldb.eStateRunning]) # make sure to detach while in running state (r204759) self.runCmd("detach") - self.assertTrue(wait_for_state(lldb.eStateDetached), - 'Process not detached after detach') + lldbutil.expect_state_changes(self, listener, [lldb.eStateDetached]) if __name__ == '__main__': import atexit Index: test/functionalities/attach_resume/main.cpp =================================================================== --- test/functionalities/attach_resume/main.cpp +++ test/functionalities/attach_resume/main.cpp @@ -8,15 +8,17 @@ #include #endif +volatile bool debugger_flag = true; // The debugger will flip this to false + void *start(void *data) { int i; size_t idx = (size_t)data; for (i=0; i<30; i++) { - if ( idx == 0 ) - std::this_thread::sleep_for(std::chrono::microseconds(1)); - std::this_thread::sleep_for(std::chrono::seconds(1)); // Set breakpoint here + if ( idx == 0 && debugger_flag) + std::this_thread::sleep_for(std::chrono::microseconds(1)); // Set breakpoint here + std::this_thread::sleep_for(std::chrono::seconds(1)); } return 0; } Index: test/lldbutil.py =================================================================== --- test/lldbutil.py +++ test/lldbutil.py @@ -721,6 +721,21 @@ if string_buffer: return output.getvalue() +def expect_state_changes(test, listener, states, timeout = 5): + """Listens for state changed events on the listener and makes sure they match what we + expect. Stop-and-restart events (where GetRestartedFromEvent() returns true) are ignored.""" + event = lldb.SBEvent() + for expected_state in states: + if not listener.WaitForEvent(timeout, event): + test.Fail("Timed out while waiting for a transition to state %s" % + lldb.SBDebugger.StateAsCString(expected_state)) + + got_state = lldb.SBProcess.GetStateFromEvent(event) + if got_state == lldb.eStateStopped and lldb.SBProcess.GetRestartedFromEvent(event): + continue + + test.assertEqual(expected_state, got_state) + # =================================== # Utility functions related to Frames # ===================================