TestExprs.py revision 3d8ae4681b81b42a404ad77a231c6f743040e644
1"""
2Test many basic expression commands and SBFrame.EvaluateExpression() API.
3
4Test cases:
5
6o test_many_expr_commands:
7  Test many basic expression commands.
8o test_evaluate_expression_python:
9  Use Python APIs (SBFrame.EvaluateExpression()) to evaluate expressions.
10o test_expr_commands_can_handle_quotes:
11  Throw some expression commands with quotes at lldb.
12"""
13
14import os, time
15import unittest2
16import lldb
17import lldbutil
18from lldbtest import *
19
20class BasicExprCommandsTestCase(TestBase):
21
22    mydir = os.path.join("expression_command", "test")
23
24    def setUp(self):
25        # Call super's setUp().
26        TestBase.setUp(self)
27        # Find the line number to break for main.c.
28        self.line = line_number('main.cpp',
29                                '// Please test many expressions while stopped at this line:')
30
31    def test_many_expr_commands(self):
32        """These basic expression commands should work as expected."""
33        self.buildDefault()
34
35        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
36
37        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
38                    BREAKPOINT_CREATED,
39            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
40                        self.line)
41
42        self.runCmd("run", RUN_SUCCEEDED)
43
44        self.expect("expression 2",
45            patterns = ["\(int\) \$.* = 2"])
46        # (int) $0 = 1
47
48        self.expect("expression 2ull",
49            patterns = ["\(unsigned long long\) \$.* = 2"])
50        # (unsigned long long) $1 = 2
51
52        self.expect("expression 2.234f",
53            patterns = ["\(float\) \$.* = 2\.234"])
54        # (float) $2 = 2.234
55
56        self.expect("expression 2.234",
57            patterns = ["\(double\) \$.* = 2\.234"])
58        # (double) $3 = 2.234
59
60        self.expect("expression 2+3",
61            patterns = ["\(int\) \$.* = 5"])
62        # (int) $4 = 5
63
64        self.expect("expression argc",
65            patterns = ["\(int\) \$.* = 1"])
66        # (int) $5 = 1
67
68        self.expect("expression argc + 22",
69            patterns = ["\(int\) \$.* = 23"])
70        # (int) $6 = 23
71
72        self.expect("expression argv",
73            patterns = ["\(const char \*\*\) \$.* = 0x"])
74        # (const char *) $7 = ...
75
76        self.expect("expression argv[0]",
77            substrs = ["(const char *)",
78                       os.path.join(self.mydir, "a.out")])
79        # (const char *) $8 = 0x... "/Volumes/data/lldb/svn/trunk/test/expression_command/test/a.out"
80
81    @python_api_test
82    def test_evaluate_expression_python(self):
83        """Test SBFrame.EvaluateExpression() API for evaluating an expression."""
84        self.buildDefault()
85
86        exe = os.path.join(os.getcwd(), "a.out")
87
88        target = self.dbg.CreateTarget(exe)
89        self.assertTrue(target, VALID_TARGET)
90
91        # Create the breakpoint.
92        filespec = lldb.SBFileSpec("main.cpp", False)
93        breakpoint = target.BreakpointCreateByLocation(filespec, self.line)
94        self.assertTrue(breakpoint, VALID_BREAKPOINT)
95
96        # Verify the breakpoint just created.
97        self.expect(repr(breakpoint), BREAKPOINT_CREATED, exe=False,
98            substrs = ['main.cpp',
99                       str(self.line)])
100
101        # Launch the process, and do not stop at the entry point.
102        # Pass 'X Y Z' as the args, which makes argc == 4.
103        error = lldb.SBError()
104        process = target.Launch(self.dbg.GetListener(), ['X', 'Y', 'Z'], None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error)
105
106        if not error.Success() or not process:
107            self.fail("SBTarget.LaunchProcess() failed")
108
109        if process.GetState() != lldb.eStateStopped:
110            self.fail("Process should be in the 'stopped' state, "
111                      "instead the actual state is: '%s'" %
112                      lldbutil.state_type_to_str(process.GetState()))
113
114        # The stop reason of the thread should be breakpoint.
115        thread = process.GetThreadAtIndex(0)
116        if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
117            from lldbutil import stop_reason_to_str
118            self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
119                      stop_reason_to_str(thread.GetStopReason()))
120
121        # The filename of frame #0 should be 'main.cpp' and function is main.
122        self.expect(lldbutil.get_filenames(thread)[0],
123                    "Break correctly at main.cpp", exe=False,
124            startstr = "main.cpp")
125        self.expect(lldbutil.get_function_names(thread)[0],
126                    "Break correctly at main()", exe=False,
127            startstr = "main")
128
129        # We should be stopped on the breakpoint with a hit count of 1.
130        self.assertTrue(breakpoint.GetHitCount() == 1, BREAKPOINT_HIT_ONCE)
131
132        #
133        # Use Python API to evaluate expressions while stopped in a stack frame.
134        #
135        frame = thread.GetFrameAtIndex(0)
136
137        val = frame.EvaluateExpression("2.234")
138        self.expect(val.GetValue(frame), "2.345 evaluated correctly", exe=False,
139            startstr = "2.234")
140        self.expect(val.GetTypeName(), "2.345 evaluated correctly", exe=False,
141            startstr = "double")
142        self.DebugSBValue(frame, val)
143
144        val = frame.EvaluateExpression("argc")
145        self.expect(val.GetValue(frame), "Argc evaluated correctly", exe=False,
146            startstr = "4")
147        self.DebugSBValue(frame, val)
148
149        val = frame.EvaluateExpression("*argv[1]")
150        self.expect(val.GetValue(frame), "Argv[1] evaluated correctly", exe=False,
151            startstr = "'X'")
152        self.DebugSBValue(frame, val)
153
154        val = frame.EvaluateExpression("*argv[2]")
155        self.expect(val.GetValue(frame), "Argv[2] evaluated correctly", exe=False,
156            startstr = "'Y'")
157        self.DebugSBValue(frame, val)
158
159        val = frame.EvaluateExpression("*argv[3]")
160        self.expect(val.GetValue(frame), "Argv[3] evaluated correctly", exe=False,
161            startstr = "'Z'")
162        self.DebugSBValue(frame, val)
163
164    # rdar://problem/8686536
165    # CommandInterpreter::HandleCommand is stripping \'s from input for WantsRawCommand commands
166    def test_expr_commands_can_handle_quotes(self):
167        """Throw some expression commands with quotes at lldb."""
168        self.buildDefault()
169
170        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
171
172        self.expect("breakpoint set -f main.cpp -l %d" % self.line,
173                    BREAKPOINT_CREATED,
174            startstr = "Breakpoint created: 1: file ='main.cpp', line = %d" %
175                        self.line)
176
177        self.runCmd("run", RUN_SUCCEEDED)
178
179        # runCmd: expression 'a'
180        # output: (char) $0 = 'a'
181        self.expect("expression 'a'",
182            substrs = ['(char) $',
183                       "'a'"])
184
185        # runCmd: expression (int) printf ("\n\n\tHello there!\n")
186        # output: (int) $1 = 16
187        self.expect(r'''expression (int) printf ("\n\n\tHello there!\n")''',
188            substrs = ['(int) $',
189                       '16'])
190
191        # runCmd: expression (int) printf("\t\x68\n")
192        # output: (int) $2 = 3
193        self.expect(r'''expression (int) printf("\t\x68\n")''',
194            substrs = ['(int) $',
195                       '3'])
196
197        # runCmd: expression (int) printf("\"\n")
198        # output: (int) $3 = 2
199        self.expect(r'''expression (int) printf("\"\n")''',
200            substrs = ['(int) $',
201                       '2'])
202
203        # runCmd: expression (int) printf("'\n")
204        # output: (int) $4 = 2
205        self.expect(r'''expression (int) printf("'\n")''',
206            substrs = ['(int) $',
207                       '2'])
208
209        # runCmd: command alias print_hi expression (int) printf ("\n\tHi!\n")
210        # output:
211        self.runCmd(r'''command alias print_hi expression (int) printf ("\n\tHi!\n")''')
212        # This fails currently.
213        self.expect('print_hi',
214            substrs = ['(int) $',
215                       '6'])
216
217
218if __name__ == '__main__':
219    import atexit
220    lldb.SBDebugger.Initialize()
221    atexit.register(lambda: lldb.SBDebugger.Terminate())
222    unittest2.main()
223