1*317c8bf8SMichael Buch"""
2*317c8bf8SMichael BuchTest that if we hit a breakpoint on a lambda capture
3*317c8bf8SMichael Buchon two threads at the same time we stop only for
4*317c8bf8SMichael Buchthe correct one.
5*317c8bf8SMichael Buch"""
6*317c8bf8SMichael Buch
7*317c8bf8SMichael Buchimport lldb
8*317c8bf8SMichael Buchimport lldbsuite.test.lldbutil as lldbutil
9*317c8bf8SMichael Buchfrom lldbsuite.test.decorators import *
10*317c8bf8SMichael Buchfrom lldbsuite.test.lldbtest import *
11*317c8bf8SMichael Buch
12*317c8bf8SMichael Buch
13*317c8bf8SMichael Buchclass TestBreakOnLambdaCapture(TestBase):
14*317c8bf8SMichael Buch
15*317c8bf8SMichael Buch    NO_DEBUG_INFO_TESTCASE = True
16*317c8bf8SMichael Buch
17*317c8bf8SMichael Buch    def test_break_on_lambda_capture(self):
18*317c8bf8SMichael Buch        self.build()
19*317c8bf8SMichael Buch        self.main_source_file = lldb.SBFileSpec("main.cpp")
20*317c8bf8SMichael Buch
21*317c8bf8SMichael Buch        (target, process, main_thread, _) = lldbutil.run_to_source_breakpoint(self,
22*317c8bf8SMichael Buch                                                "First break", self.main_source_file)
23*317c8bf8SMichael Buch
24*317c8bf8SMichael Buch        # FIXME: This is working around a separate bug. If you hit a breakpoint and
25*317c8bf8SMichael Buch        # run an expression and it is the first expression you've ever run, on
26*317c8bf8SMichael Buch        # Darwin that will involve running the ObjC runtime parsing code, and we'll
27*317c8bf8SMichael Buch        # be in the middle of that when we do PerformAction on the other thread,
28*317c8bf8SMichael Buch        # which will cause the condition expression to fail.  Calling another
29*317c8bf8SMichael Buch        # expression first works around this.
30*317c8bf8SMichael Buch        val_obj = main_thread.frame[0].EvaluateExpression("true")
31*317c8bf8SMichael Buch        self.assertSuccess(val_obj.GetError(), "Ran our expression successfully")
32*317c8bf8SMichael Buch        self.assertEqual(val_obj.value, "true", "Value was true.")
33*317c8bf8SMichael Buch
34*317c8bf8SMichael Buch        bkpt = target.BreakpointCreateBySourceRegex("Break here in the helper",
35*317c8bf8SMichael Buch                                                    self.main_source_file);
36*317c8bf8SMichael Buch
37*317c8bf8SMichael Buch        bkpt.SetCondition("enable && usec == 1")
38*317c8bf8SMichael Buch        process.Continue()
39*317c8bf8SMichael Buch
40*317c8bf8SMichael Buch        # This is hard to test definitively, becuase it requires hitting
41*317c8bf8SMichael Buch        # a breakpoint on multiple threads at the same time.  On Darwin, this
42*317c8bf8SMichael Buch        # will happen pretty much ever time we continue.  What we are really
43*317c8bf8SMichael Buch        # asserting is that we only ever stop on one thread, so we approximate that
44*317c8bf8SMichael Buch        # by continuing 20 times and assert we only ever hit the first thread.  Either
45*317c8bf8SMichael Buch        # this is a platform that only reports one hit at a time, in which case all
46*317c8bf8SMichael Buch        # this code is unused, or we actually didn't hit the other thread.
47*317c8bf8SMichael Buch
48*317c8bf8SMichael Buch        for idx in range(0, 20):
49*317c8bf8SMichael Buch            process.Continue()
50*317c8bf8SMichael Buch            for thread in process.threads:
51*317c8bf8SMichael Buch                if thread.id == main_thread.id:
52*317c8bf8SMichael Buch                    self.assertEqual(thread.stop_reason, lldb.eStopReasonBreakpoint)
53*317c8bf8SMichael Buch                else:
54*317c8bf8SMichael Buch                    self.assertEqual(thread.stop_reason, lldb.eStopReasonNone)
55