1# encoding: utf-8
2"""
3Test lldb's frame recognizers.
4"""
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11import recognizer
12
13class FrameRecognizerTestCase(TestBase):
14
15    mydir = TestBase.compute_mydir(__file__)
16    NO_DEBUG_INFO_TESTCASE = True
17
18    @skipUnlessDarwin
19    def test_frame_recognizer_1(self):
20        self.build()
21        exe = self.getBuildArtifact("a.out")
22
23        # Clear internal & plugins recognizers that get initialized at launch
24        self.runCmd("frame recognizer clear")
25
26        self.runCmd("command script import " + os.path.join(self.getSourceDir(), "recognizer.py"))
27
28        self.expect("frame recognizer list",
29                    substrs=['no matching results found.'])
30
31        self.runCmd("frame recognizer add -l recognizer.MyFrameRecognizer -s a.out -n foo")
32
33        self.expect("frame recognizer list",
34                    substrs=['0: recognizer.MyFrameRecognizer, module a.out, symbol foo'])
35
36        self.runCmd("frame recognizer add -l recognizer.MyOtherFrameRecognizer -s a.out -n bar -x")
37
38        self.expect(
39            "frame recognizer list",
40            substrs=[
41                '1: recognizer.MyOtherFrameRecognizer, module a.out, symbol bar (regexp)',
42                '0: recognizer.MyFrameRecognizer, module a.out, symbol foo'
43            ])
44
45        self.runCmd("frame recognizer delete 0")
46
47        self.expect("frame recognizer list",
48                    substrs=['1: recognizer.MyOtherFrameRecognizer, module a.out, symbol bar (regexp)'])
49
50        self.runCmd("frame recognizer clear")
51
52        self.expect("frame recognizer list",
53                    substrs=['no matching results found.'])
54
55        self.runCmd("frame recognizer add -l recognizer.MyFrameRecognizer -s a.out -n foo")
56
57        target, process, thread, _ = lldbutil.run_to_name_breakpoint(self, "foo",
58                                                                 exe_name = exe)
59        frame = thread.GetSelectedFrame()
60
61        self.expect("frame variable",
62                    substrs=['(int) a = 42', '(int) b = 56'])
63
64        # Recognized arguments don't show up by default...
65        variables = frame.GetVariables(lldb.SBVariablesOptions())
66        self.assertEqual(variables.GetSize(), 0)
67
68        # ...unless you set target.display-recognized-arguments to 1...
69        self.runCmd("settings set target.display-recognized-arguments 1")
70        variables = frame.GetVariables(lldb.SBVariablesOptions())
71        self.assertEqual(variables.GetSize(), 2)
72
73        # ...and you can reset it back to 0 to hide them again...
74        self.runCmd("settings set target.display-recognized-arguments 0")
75        variables = frame.GetVariables(lldb.SBVariablesOptions())
76        self.assertEqual(variables.GetSize(), 0)
77
78        # ... or explicitly ask for them with SetIncludeRecognizedArguments(True).
79        opts = lldb.SBVariablesOptions()
80        opts.SetIncludeRecognizedArguments(True)
81        variables = frame.GetVariables(opts)
82
83        self.assertEqual(variables.GetSize(), 2)
84        self.assertEqual(variables.GetValueAtIndex(0).name, "a")
85        self.assertEqual(variables.GetValueAtIndex(0).signed, 42)
86        self.assertEqual(variables.GetValueAtIndex(0).GetValueType(), lldb.eValueTypeVariableArgument)
87        self.assertEqual(variables.GetValueAtIndex(1).name, "b")
88        self.assertEqual(variables.GetValueAtIndex(1).signed, 56)
89        self.assertEqual(variables.GetValueAtIndex(1).GetValueType(), lldb.eValueTypeVariableArgument)
90
91        self.expect("frame recognizer info 0",
92                    substrs=['frame 0 is recognized by recognizer.MyFrameRecognizer'])
93
94        self.expect("frame recognizer info 999", error=True,
95                    substrs=['no frame with index 999'])
96
97        self.expect("frame recognizer info 1",
98                    substrs=['frame 1 not recognized by any recognizer'])
99
100        # FIXME: The following doesn't work yet, but should be fixed.
101        """
102        target, process, thread, _ = lldbutil.run_to_name_breakpoint(self, "bar",
103                                                                 exe_name = exe)
104        frame = thread.GetSelectedFrame()
105
106        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
107                    substrs=['stopped', 'stop reason = breakpoint'])
108
109        self.expect("frame variable -t",
110                    substrs=['(int *) a = '])
111
112        self.expect("frame variable -t *a",
113                    substrs=['*a = 78'])
114        """
115
116    @skipUnlessDarwin
117    def test_frame_recognizer_multi_symbol(self):
118        self.build()
119        exe = self.getBuildArtifact("a.out")
120
121        # Clear internal & plugins recognizers that get initialized at launch
122        self.runCmd("frame recognizer clear")
123
124        self.runCmd("command script import " + os.path.join(self.getSourceDir(), "recognizer.py"))
125
126        self.expect("frame recognizer list",
127                    substrs=['no matching results found.'])
128
129        self.runCmd("frame recognizer add -l recognizer.MyFrameRecognizer -s a.out -n foo -n bar")
130
131        self.expect("frame recognizer list",
132                    substrs=['recognizer.MyFrameRecognizer, module a.out, symbol foo, symbol bar'])
133
134        target, process, thread, _ = lldbutil.run_to_name_breakpoint(self, "foo",
135                                                                 exe_name = exe)
136        frame = thread.GetSelectedFrame()
137
138        self.expect("frame recognizer info 0",
139                    substrs=['frame 0 is recognized by recognizer.MyFrameRecognizer'])
140
141        target, process, thread, _ = lldbutil.run_to_name_breakpoint(self, "bar",
142                                                                 exe_name = exe)
143        frame = thread.GetSelectedFrame()
144
145        self.expect("frame recognizer info 0",
146                    substrs=['frame 0 is recognized by recognizer.MyFrameRecognizer'])
147