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