1"""
2Test conditionally break on a function and inspect its variables.
3"""
4
5import os, time
6import re
7import unittest2
8import lldb, lldbutil
9from lldbtest import *
10
11# rdar://problem/8532131
12# lldb not able to digest the clang-generated debug info correctly with respect to function name
13#
14# This class currently fails for clang as well as llvm-gcc.
15
16class ConditionalBreakTestCase(TestBase):
17
18    mydir = os.path.join("functionalities", "conditional_break")
19
20    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
21    @python_api_test
22    @dsym_test
23    def test_with_dsym_python(self):
24        """Exercise some thread and frame APIs to break if c() is called by a()."""
25        self.buildDsym()
26        self.do_conditional_break()
27
28    @python_api_test
29    @dwarf_test
30    def test_with_dwarf_python(self):
31        """Exercise some thread and frame APIs to break if c() is called by a()."""
32        self.buildDwarf()
33        self.do_conditional_break()
34
35    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
36    @dsym_test
37    def test_with_dsym_command(self):
38        """Simulate a user using lldb commands to break on c() if called from a()."""
39        self.buildDsym()
40        self.simulate_conditional_break_by_user()
41
42    @dwarf_test
43    @skipIfLinux # due to two assertion failures introduced by r174793: ProcessPOSIX.cpp:223 (assertion 'state == eStateStopped || state == eStateCrashed') and POSIXThread.cpp:254 (assertion 'bp_site')
44    def test_with_dwarf_command(self):
45        """Simulate a user using lldb commands to break on c() if called from a()."""
46        self.buildDwarf()
47        self.simulate_conditional_break_by_user()
48
49    def do_conditional_break(self):
50        """Exercise some thread and frame APIs to break if c() is called by a()."""
51        exe = os.path.join(os.getcwd(), "a.out")
52
53        target = self.dbg.CreateTarget(exe)
54        self.assertTrue(target, VALID_TARGET)
55
56        breakpoint = target.BreakpointCreateByName("c", exe)
57        self.assertTrue(breakpoint, VALID_BREAKPOINT)
58
59        # Now launch the process, and do not stop at entry point.
60        process = target.LaunchSimple(None, None, os.getcwd())
61
62        self.assertTrue(process, PROCESS_IS_VALID)
63
64        # The stop reason of the thread should be breakpoint.
65        self.assertTrue(process.GetState() == lldb.eStateStopped,
66                        STOPPED_DUE_TO_BREAKPOINT)
67
68        # Find the line number where a's parent frame function is c.
69        line = line_number('main.c',
70            "// Find the line number where c's parent frame is a here.")
71
72        # Suppose we are only interested in the call scenario where c()'s
73        # immediate caller is a() and we want to find out the value passed from
74        # a().
75        #
76        # The 10 in range(10) is just an arbitrary number, which means we would
77        # like to try for at most 10 times.
78        for j in range(10):
79            if self.TraceOn():
80                print "j is: ", j
81            thread = process.GetThreadAtIndex(0)
82
83            if thread.GetNumFrames() >= 2:
84                frame0 = thread.GetFrameAtIndex(0)
85                name0 = frame0.GetFunction().GetName()
86                frame1 = thread.GetFrameAtIndex(1)
87                name1 = frame1.GetFunction().GetName()
88                #lldbutil.print_stacktrace(thread)
89                self.assertTrue(name0 == "c", "Break on function c()")
90                if (name1 == "a"):
91                    # By design, we know that a() calls c() only from main.c:27.
92                    # In reality, similar logic can be used to find out the call
93                    # site.
94                    self.assertTrue(frame1.GetLineEntry().GetLine() == line,
95                                    "Immediate caller a() at main.c:%d" % line)
96
97                    # And the local variable 'val' should have a value of (int) 3.
98                    val = frame1.FindVariable("val")
99                    self.assertTrue(val.GetTypeName() == "int", "'val' has int type")
100                    self.assertTrue(val.GetValue() == "3", "'val' has a value of 3")
101                    break
102
103            process.Continue()
104
105    def simulate_conditional_break_by_user(self):
106        """Simulate a user using lldb commands to break on c() if called from a()."""
107
108        # Sourcing .lldb in the current working directory, which sets the main
109        # executable, sets the breakpoint on c(), and adds the callback for the
110        # breakpoint such that lldb only stops when the caller of c() is a().
111        # the "my" package that defines the date() function.
112        if self.TraceOn():
113            print "About to source .lldb"
114
115        if not self.TraceOn():
116            self.HideStdout()
117        self.runCmd("command source .lldb")
118
119        self.runCmd ("break list")
120
121        if self.TraceOn():
122            print "About to run."
123        self.runCmd("run", RUN_SUCCEEDED)
124
125        self.runCmd ("break list")
126
127        if self.TraceOn():
128            print "Done running"
129
130        # The stop reason of the thread should be breakpoint.
131        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
132            substrs = ['stopped', 'stop reason = breakpoint'])
133
134        # The frame info for frame #0 points to a.out`c and its immediate caller
135        # (frame #1) points to a.out`a.
136
137        self.expect("frame info", "We should stop at c()",
138            substrs = ["a.out`c"])
139
140        # Select our parent frame as the current frame.
141        self.runCmd("frame select 1")
142        self.expect("frame info", "The immediate caller should be a()",
143            substrs = ["a.out`a"])
144
145
146
147if __name__ == '__main__':
148    import atexit
149    lldb.SBDebugger.Initialize()
150    atexit.register(lambda: lldb.SBDebugger.Terminate())
151    unittest2.main()
152