blob: f8b80e629d991a4f29d9780c0dd8691b712651b4 [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.
3"""
4
5import os, time
6import re
7import unittest2
8import lldb, lldbutil
9from lldbtest import *
10
11class FrameAPITestCase(TestBase):
12
13 mydir = os.path.join("python_api", "frame")
14
15 @unittest2.expectedFailure
16 @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
17 @python_api_test
18 def test_get_arg_vals_for_call_stack_with_dsym(self):
19 """Exercise SBFrame.GetVariables() API to get argument vals."""
20 self.buildDsym()
21 self.do_get_arg_vals()
22
23 @unittest2.expectedFailure
24 @python_api_test
25 def test_get_arg_vals_for_call_stack_with_dwarf(self):
26 """Exercise SBFrame.GetVariables() API to get argument vals."""
27 self.buildDwarf()
28 self.do_get_arg_vals()
29
30 def do_get_arg_vals(self):
31 """Get argument vals for the call stack when stopped on a breakpoint."""
32 exe = os.path.join(os.getcwd(), "a.out")
33
34 # Create a target by the debugger.
35 target = self.dbg.CreateTarget(exe)
36 self.assertTrue(target.IsValid(), VALID_TARGET)
37
38 # Now create a breakpoint on main.c by name 'c'.
39 breakpoint = target.BreakpointCreateByName('c', 'a.out')
40 #print "breakpoint:", breakpoint
41 self.assertTrue(breakpoint.IsValid() and
42 breakpoint.GetNumLocations() == 1,
43 VALID_BREAKPOINT)
44
45 # Now launch the process, and do not stop at the entry point.
46 # Note that we don't assign the process to self.process as in other test
47 # cases. We want the inferior to run till it exits and there's no need
48 # for the testing framework to kill the inferior upon tearDown().
49 process = target.LaunchProcess([], [], os.ctermid(), 0, False)
50
51 process = target.GetProcess()
52 self.assertTrue(process.GetState() == lldb.eStateStopped,
53 PROCESS_STOPPED)
54
55 # Keeps track of the number of times 'a' is called where it is within a
56 # depth of 3 of the 'c' leaf function.
57 callsOfA = 0
58
59 import StringIO
60 session = StringIO.StringIO()
61 while process.GetState() == lldb.eStateStopped:
62 thread = process.GetThreadAtIndex(0)
63 # Inspect at most 3 frames.
64 numFrames = min(3, thread.GetNumFrames())
65 for i in range(numFrames):
66 frame = thread.GetFrameAtIndex(i)
67 print "frame:", frame
68 #print "frame.FindValue('val', lldb.eValueTypeVariableArgument)", frame.FindValue('val', lldb.eValueTypeVariableArgument).GetValue(frame)
69 #print "frame.FindValue('ch', lldb.eValueTypeVariableArgument)", frame.FindValue('ch', lldb.eValueTypeVariableArgument).GetValue(frame)
70 #print "frame.EvaluateExpression('val'):", frame.EvaluateExpression('val').GetValue(frame)
71 #print "frame.EvaluateExpression('ch'):", frame.EvaluateExpression('ch').GetValue(frame)
72 name = frame.GetFunction().GetName()
73 if name == 'a':
74 callsOfA = callsOfA + 1
75
76 # We'll inspect only the arguments for the current frame:
77 #
78 # arguments => True
79 # locals => False
80 # statics => False
81 # in_scope_only => True
82 valList = frame.GetVariables(True, False, False, True)
83 argList = []
84 from lldbutil import lldb_iter
85 for val in lldb_iter(valList, 'GetSize', 'GetValueAtIndex'):
86 #self.DebugSBValue(frame, val)
87 argList.append("(%s)%s=%s" % (val.GetTypeName(),
88 val.GetName(),
89 val.GetValue(frame)))
90 print >> session, "%s(%s)" % (name, ", ".join(argList))
91
92 print >> session, "---"
93 process.Continue()
94
95 # At this point, the inferior process should have exited.
96 self.assertTrue(process.GetState() == lldb.eStateExited, PROCESS_EXITED)
97
98 # Expect to find 'a' on the call stacks two times.
99 self.assertTrue(callsOfA == 2,
100 "Expect to find 'a' on the call stacks two times")
101 # By design, the 'a' call frame has the following arg vals:
102 # o a((int)val=1, (char)ch='A')
103 # o a((int)val=3, (char)ch='A')
104 print "Full stack traces when stopped on the breakpoint 'c':"
105 print session.getvalue()
106 # rdar://problem/8801262
107 # test failure: ./dotest.py -v -w -t -p TestFrames (argument values are wrong)
108 self.expect(session.getvalue(), "Argugment values displayed correctly",
109 exe=False,
110 substrs = ["a((int)val=1, (char)ch='A')",
111 "a((int)val=3, (char)ch='A')"])
112
113
114if __name__ == '__main__':
115 import atexit
116 lldb.SBDebugger.Initialize()
117 atexit.register(lambda: lldb.SBDebugger.Terminate())
118 unittest2.main()