labath updated this revision to Diff 33689.
labath added a comment.
I've found another source or racyness in the test. The test verified that the
process resumes and
stops after a "continue". However, if these two events happened two fast, the
initial start event
would be lost, and the test would end up confused. I have implemented this in a
safer manner and
made a utility function out of it, as I know of a couple of other tests which
need the same
functionality.
http://reviews.llvm.org/D12527
Files:
test/functionalities/attach_resume/TestAttachResume.py
test/functionalities/attach_resume/main.cpp
test/lldbutil.py
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
# ===================================
Index: test/functionalities/attach_resume/main.cpp
===================================================================
--- test/functionalities/attach_resume/main.cpp
+++ test/functionalities/attach_resume/main.cpp
@@ -8,15 +8,17 @@
#include <sys/prctl.h>
#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/functionalities/attach_resume/TestAttachResume.py
===================================================================
--- test/functionalities/attach_resume/TestAttachResume.py
+++ test/functionalities/attach_resume/TestAttachResume.py
@@ -14,16 +14,14 @@
mydir = TestBase.compute_mydir(__file__)
- @expectedFlakeyLinux('llvm.org/pr19310')
@expectedFailureFreeBSD('llvm.org/pr19310')
@skipIfRemote
@dwarf_test
def test_attach_continue_interrupt_detach(self):
"""Test attach/continue/interrupt/detach"""
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
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits