2 Test conditionally break on a function and inspect its variables.
5 from __future__ import print_function
12 from lldbsuite.test.decorators import *
13 from lldbsuite.test.lldbtest import *
14 from lldbsuite.test import lldbutil
16 # rdar://problem/8532131
17 # lldb not able to digest the clang-generated debug info correctly with respect to function name
19 # This class currently fails for clang as well as llvm-gcc.
22 class ConditionalBreakTestCase(TestBase):
24 mydir = TestBase.compute_mydir(__file__)
26 @add_test_categories(['pyapi'])
27 def test_with_python(self):
28 """Exercise some thread and frame APIs to break if c() is called by a()."""
30 self.do_conditional_break()
32 def test_with_command(self):
33 """Simulate a user using lldb commands to break on c() if called from a()."""
35 self.simulate_conditional_break_by_user()
39 bugnumber="llvm.org/pr26265: args in frames other than #0 are not evaluated correctly")
40 def do_conditional_break(self):
41 """Exercise some thread and frame APIs to break if c() is called by a()."""
42 exe = os.path.join(os.getcwd(), "a.out")
44 target = self.dbg.CreateTarget(exe)
45 self.assertTrue(target, VALID_TARGET)
47 breakpoint = target.BreakpointCreateByName("c", exe)
48 self.assertTrue(breakpoint, VALID_BREAKPOINT)
50 # Now launch the process, and do not stop at entry point.
51 process = target.LaunchSimple(
52 None, None, self.get_process_working_directory())
54 self.assertTrue(process, PROCESS_IS_VALID)
56 # The stop reason of the thread should be breakpoint.
57 self.assertTrue(process.GetState() == lldb.eStateStopped,
58 STOPPED_DUE_TO_BREAKPOINT)
60 # Find the line number where a's parent frame function is c.
63 "// Find the line number where c's parent frame is a here.")
65 # Suppose we are only interested in the call scenario where c()'s
66 # immediate caller is a() and we want to find out the value passed from
69 # The 10 in range(10) is just an arbitrary number, which means we would
70 # like to try for at most 10 times.
74 thread = lldbutil.get_one_thread_stopped_at_breakpoint(
77 thread, "Expected one thread to be stopped at the breakpoint")
79 if thread.GetNumFrames() >= 2:
80 frame0 = thread.GetFrameAtIndex(0)
81 name0 = frame0.GetFunction().GetName()
82 frame1 = thread.GetFrameAtIndex(1)
83 name1 = frame1.GetFunction().GetName()
84 # lldbutil.print_stacktrace(thread)
85 self.assertTrue(name0 == "c", "Break on function c()")
87 # By design, we know that a() calls c() only from main.c:27.
88 # In reality, similar logic can be used to find out the call
90 self.assertTrue(frame1.GetLineEntry().GetLine() == line,
91 "Immediate caller a() at main.c:%d" % line)
93 # And the local variable 'val' should have a value of (int)
95 val = frame1.FindVariable("val")
96 self.assertEqual("int", val.GetTypeName())
97 self.assertEqual("3", val.GetValue())
102 def simulate_conditional_break_by_user(self):
103 """Simulate a user using lldb commands to break on c() if called from a()."""
105 # Sourcing .lldb in the current working directory, which sets the main
106 # executable, sets the breakpoint on c(), and adds the callback for the
107 # breakpoint such that lldb only stops when the caller of c() is a().
108 # the "my" package that defines the date() function.
110 print("About to source .lldb")
112 if not self.TraceOn():
115 # Separate out the "file a.out" command from .lldb file, for the sake of
117 self.runCmd("file a.out")
118 self.runCmd("command source .lldb")
120 self.runCmd("break list")
123 print("About to run.")
124 self.runCmd("run", RUN_SUCCEEDED)
126 self.runCmd("break list")
129 print("Done running")
131 # The stop reason of the thread should be breakpoint.
132 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
133 substrs=['stopped', 'stop reason = breakpoint'])
135 # The frame info for frame #0 points to a.out`c and its immediate caller
136 # (frame #1) points to a.out`a.
138 self.expect("frame info", "We should stop at c()",
141 # Select our parent frame as the current frame.
142 self.runCmd("frame select 1")
143 self.expect("frame info", "The immediate caller should be a()",