blob: 651921128c9a8c2ed893a25d4c1554ff12544794 [file] [log] [blame]
Johnny Chend5f66fc2010-12-23 01:12:19 +00001"""
2Use lldb Python SBFrame API to get the argument values of the call stacks.
Johnny Chen35e2ab62012-03-05 19:53:24 +00003And other SBFrame API tests.
Johnny Chend5f66fc2010-12-23 01:12:19 +00004"""
5
6import os, time
7import re
8import unittest2
9import lldb, lldbutil
10from lldbtest import *
11
12class FrameAPITestCase(TestBase):
13
Greg Clayton4570d3e2013-12-10 23:19:29 +000014 mydir = TestBase.compute_mydir(__file__)
Johnny Chend5f66fc2010-12-23 01:12:19 +000015
Johnny Chend5f66fc2010-12-23 01:12:19 +000016 @python_api_test
Zachary Turner9c7b08e2015-09-11 20:01:24 +000017 @expectedFailureWindows("llvm.org/pr24778")
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000018 def test_get_arg_vals_for_call_stack(self):
Johnny Chend5f66fc2010-12-23 01:12:19 +000019 """Exercise SBFrame.GetVariables() API to get argument vals."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +000020 self.build()
Johnny Chend5f66fc2010-12-23 01:12:19 +000021 exe = os.path.join(os.getcwd(), "a.out")
22
23 # Create a target by the debugger.
24 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +000025 self.assertTrue(target, VALID_TARGET)
Johnny Chend5f66fc2010-12-23 01:12:19 +000026
27 # Now create a breakpoint on main.c by name 'c'.
28 breakpoint = target.BreakpointCreateByName('c', 'a.out')
29 #print "breakpoint:", breakpoint
Johnny Chen4ebd0192011-05-24 18:22:45 +000030 self.assertTrue(breakpoint and
Johnny Chend5f66fc2010-12-23 01:12:19 +000031 breakpoint.GetNumLocations() == 1,
32 VALID_BREAKPOINT)
33
34 # Now launch the process, and do not stop at the entry point.
Greg Claytonc6947512013-12-13 19:18:59 +000035 process = target.LaunchSimple (None, None, self.get_process_working_directory())
Johnny Chend5f66fc2010-12-23 01:12:19 +000036
37 process = target.GetProcess()
38 self.assertTrue(process.GetState() == lldb.eStateStopped,
39 PROCESS_STOPPED)
40
41 # Keeps track of the number of times 'a' is called where it is within a
42 # depth of 3 of the 'c' leaf function.
43 callsOfA = 0
44
45 import StringIO
46 session = StringIO.StringIO()
47 while process.GetState() == lldb.eStateStopped:
48 thread = process.GetThreadAtIndex(0)
49 # Inspect at most 3 frames.
50 numFrames = min(3, thread.GetNumFrames())
51 for i in range(numFrames):
52 frame = thread.GetFrameAtIndex(i)
Johnny Chenfbf1cfe2011-04-19 19:34:41 +000053 if self.TraceOn():
54 print "frame:", frame
Johnny Chenc8134ce2011-05-13 23:42:44 +000055
Johnny Chend5f66fc2010-12-23 01:12:19 +000056 name = frame.GetFunction().GetName()
57 if name == 'a':
58 callsOfA = callsOfA + 1
59
60 # We'll inspect only the arguments for the current frame:
61 #
62 # arguments => True
63 # locals => False
64 # statics => False
65 # in_scope_only => True
66 valList = frame.GetVariables(True, False, False, True)
67 argList = []
Johnny Chene69c7482011-04-28 22:57:01 +000068 for val in valList:
Johnny Chend5f66fc2010-12-23 01:12:19 +000069 argList.append("(%s)%s=%s" % (val.GetTypeName(),
70 val.GetName(),
Greg Claytonfe42ac42011-08-03 22:57:10 +000071 val.GetValue()))
Johnny Chend5f66fc2010-12-23 01:12:19 +000072 print >> session, "%s(%s)" % (name, ", ".join(argList))
Jim Ingham8d543de2011-03-31 23:01:21 +000073
74 # Also check the generic pc & stack pointer. We can't test their absolute values,
Johnny Chenc8134ce2011-05-13 23:42:44 +000075 # but they should be valid. Uses get_GPRs() from the lldbutil module.
76 gpr_reg_set = lldbutil.get_GPRs(frame)
Jim Ingham8d543de2011-03-31 23:01:21 +000077 pc_value = gpr_reg_set.GetChildMemberWithName("pc")
Johnny Chen4ebd0192011-05-24 18:22:45 +000078 self.assertTrue (pc_value, "We should have a valid PC.")
Matt Kopecee969f92013-09-26 23:30:59 +000079 pc_value_str = pc_value.GetValue()
80 self.assertTrue (pc_value_str, "We should have a valid PC string.")
81 self.assertTrue (int(pc_value_str, 0) == frame.GetPC(), "PC gotten as a value should equal frame's GetPC")
Jim Ingham8d543de2011-03-31 23:01:21 +000082 sp_value = gpr_reg_set.GetChildMemberWithName("sp")
Johnny Chen4ebd0192011-05-24 18:22:45 +000083 self.assertTrue (sp_value, "We should have a valid Stack Pointer.")
Greg Claytonfe42ac42011-08-03 22:57:10 +000084 self.assertTrue (int(sp_value.GetValue(), 0) == frame.GetSP(), "SP gotten as a value should equal frame's GetSP")
Johnny Chend5f66fc2010-12-23 01:12:19 +000085
86 print >> session, "---"
87 process.Continue()
88
89 # At this point, the inferior process should have exited.
90 self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
91
92 # Expect to find 'a' on the call stacks two times.
93 self.assertTrue(callsOfA == 2,
94 "Expect to find 'a' on the call stacks two times")
95 # By design, the 'a' call frame has the following arg vals:
96 # o a((int)val=1, (char)ch='A')
97 # o a((int)val=3, (char)ch='A')
Johnny Chenfbf1cfe2011-04-19 19:34:41 +000098 if self.TraceOn():
99 print "Full stack traces when stopped on the breakpoint 'c':"
100 print session.getvalue()
Johnny Chend5f66fc2010-12-23 01:12:19 +0000101 self.expect(session.getvalue(), "Argugment values displayed correctly",
102 exe=False,
103 substrs = ["a((int)val=1, (char)ch='A')",
104 "a((int)val=3, (char)ch='A')"])
105
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000106 @python_api_test
107 def test_frame_api_boundary_condition(self):
108 """Exercise SBFrame APIs with boundary condition inputs."""
109 self.build()
Johnny Chen1317b162011-12-19 23:41:29 +0000110 exe = os.path.join(os.getcwd(), "a.out")
111
112 # Create a target by the debugger.
113 target = self.dbg.CreateTarget(exe)
114 self.assertTrue(target, VALID_TARGET)
115
116 # Now create a breakpoint on main.c by name 'c'.
117 breakpoint = target.BreakpointCreateByName('c', 'a.out')
118 #print "breakpoint:", breakpoint
119 self.assertTrue(breakpoint and
120 breakpoint.GetNumLocations() == 1,
121 VALID_BREAKPOINT)
122
123 # Now launch the process, and do not stop at the entry point.
Greg Claytonc6947512013-12-13 19:18:59 +0000124 process = target.LaunchSimple (None, None, self.get_process_working_directory())
Johnny Chen1317b162011-12-19 23:41:29 +0000125
126 process = target.GetProcess()
127 self.assertTrue(process.GetState() == lldb.eStateStopped,
128 PROCESS_STOPPED)
129
130 thread = process.GetThreadAtIndex(0)
131 frame = thread.GetFrameAtIndex(0)
132 if self.TraceOn():
133 print "frame:", frame
134
135 # Boundary condition testings.
136 val1 = frame.FindVariable(None, True)
137 val2 = frame.FindVariable(None, False)
138 val3 = frame.FindValue(None, lldb.eValueTypeVariableGlobal)
139 if self.TraceOn():
140 print "val1:", val1
141 print "val2:", val2
142
143 frame.EvaluateExpression(None)
144
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000145 @python_api_test
146 def test_frame_api_IsEqual(self):
Johnny Chen35e2ab62012-03-05 19:53:24 +0000147 """Exercise SBFrame API IsEqual."""
Tamas Berghammerc8fd1302015-09-30 10:12:40 +0000148 self.build()
Johnny Chen35e2ab62012-03-05 19:53:24 +0000149 exe = os.path.join(os.getcwd(), "a.out")
150
151 # Create a target by the debugger.
152 target = self.dbg.CreateTarget(exe)
153 self.assertTrue(target, VALID_TARGET)
154
155 # Now create a breakpoint on main.c by name 'c'.
156 breakpoint = target.BreakpointCreateByName('c', 'a.out')
157 #print "breakpoint:", breakpoint
158 self.assertTrue(breakpoint and
159 breakpoint.GetNumLocations() == 1,
160 VALID_BREAKPOINT)
161
162 # Now launch the process, and do not stop at the entry point.
Greg Claytonc6947512013-12-13 19:18:59 +0000163 process = target.LaunchSimple (None, None, self.get_process_working_directory())
Johnny Chen35e2ab62012-03-05 19:53:24 +0000164
165 process = target.GetProcess()
166 self.assertTrue(process.GetState() == lldb.eStateStopped,
167 PROCESS_STOPPED)
168
169 thread = process.GetThreadAtIndex(0)
170 self.assertTrue(thread)
171
172 frameEntered = thread.GetFrameAtIndex(0)
173 if self.TraceOn():
174 print frameEntered
175 lldbutil.print_stacktrace(thread)
176 self.assertTrue(frameEntered)
177
178 # Doing two step overs while still inside c().
179 thread.StepOver()
180 thread.StepOver()
181 self.assertTrue(thread)
182 frameNow = thread.GetFrameAtIndex(0)
183 if self.TraceOn():
184 print frameNow
185 lldbutil.print_stacktrace(thread)
186 self.assertTrue(frameNow)
187
188 # The latest two frames are considered equal.
189 self.assertTrue(frameEntered.IsEqual(frameNow))
190
191 # Now let's step out of frame c().
192 thread.StepOutOfFrame(frameNow)
193 frameOutOfC = thread.GetFrameAtIndex(0)
194 if self.TraceOn():
195 print frameOutOfC
196 lldbutil.print_stacktrace(thread)
197 self.assertTrue(frameOutOfC)
198
199 # The latest two frames should not be equal.
Greg Clayton7fdf9ef2012-04-05 16:12:35 +0000200 self.assertFalse(frameOutOfC.IsEqual(frameNow))
Johnny Chen35e2ab62012-03-05 19:53:24 +0000201
Johnny Chend5f66fc2010-12-23 01:12:19 +0000202
203if __name__ == '__main__':
204 import atexit
205 lldb.SBDebugger.Initialize()
206 atexit.register(lambda: lldb.SBDebugger.Terminate())
207 unittest2.main()