Files
clang-p2996/lldb/test/functionalities/conditional_break/TestConditionalBreak.py
Johnny Chen f1548d4f74 Add a new option to the test driver, -N dsym or -N dwarf, in order to exclude tests decorated with
either @dsym_test or @dwarf_test to be executed during the testsuite run.  There are still lots of
Test*.py files which have not been decorated with the new decorator.

An example:

# From TestMyFirstWatchpoint.py ->
class HelloWatchpointTestCase(TestBase):

    mydir = os.path.join("functionalities", "watchpoint", "hello_watchpoint")

    @dsym_test
    def test_hello_watchpoint_with_dsym_using_watchpoint_set(self):
        """Test a simple sequence of watchpoint creation and watchpoint hit."""
        self.buildDsym(dictionary=self.d)
        self.setTearDownCleanup(dictionary=self.d)
        self.hello_watchpoint()

    @dwarf_test
    def test_hello_watchpoint_with_dwarf_using_watchpoint_set(self):
        """Test a simple sequence of watchpoint creation and watchpoint hit."""
        self.buildDwarf(dictionary=self.d)
        self.setTearDownCleanup(dictionary=self.d)
        self.hello_watchpoint()


# Invocation ->
[17:50:14] johnny:/Volumes/data/lldb/svn/ToT/test $ ./dotest.py -N dsym -v -p TestMyFirstWatchpoint.py
LLDB build dir: /Volumes/data/lldb/svn/ToT/build/Debug
LLDB-137
Path: /Volumes/data/lldb/svn/ToT
URL: https://johnny@llvm.org/svn/llvm-project/lldb/trunk
Repository Root: https://johnny@llvm.org/svn/llvm-project
Repository UUID: 91177308-0d34-0410-b5e6-96231b3b80d8
Revision: 154133
Node Kind: directory
Schedule: normal
Last Changed Author: gclayton
Last Changed Rev: 154109
Last Changed Date: 2012-04-05 10:43:02 -0700 (Thu, 05 Apr 2012)



Session logs for test failures/errors/unexpected successes will go into directory '2012-04-05-17_50_49'
Command invoked: python ./dotest.py -N dsym -v -p TestMyFirstWatchpoint.py
compilers=['clang']

Configuration: arch=x86_64 compiler=clang
----------------------------------------------------------------------
Collected 2 tests

1: test_hello_watchpoint_with_dsym_using_watchpoint_set (TestMyFirstWatchpoint.HelloWatchpointTestCase)
   Test a simple sequence of watchpoint creation and watchpoint hit. ... skipped 'dsym tests'
2: test_hello_watchpoint_with_dwarf_using_watchpoint_set (TestMyFirstWatchpoint.HelloWatchpointTestCase)
   Test a simple sequence of watchpoint creation and watchpoint hit. ... ok

----------------------------------------------------------------------
Ran 2 tests in 1.138s

OK (skipped=1)
Session logs for test failures/errors/unexpected successes can be found in directory '2012-04-05-17_50_49'
[17:50:50] johnny:/Volumes/data/lldb/svn/ToT/test $ 

llvm-svn: 154154
2012-04-06 00:56:05 +00:00

146 lines
5.4 KiB
Python

"""
Test conditionally break on a function and inspect its variables.
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
# rdar://problem/8532131
# lldb not able to digest the clang-generated debug info correctly with respect to function name
#
# This class currently fails for clang as well as llvm-gcc.
class ConditionalBreakTestCase(TestBase):
mydir = os.path.join("functionalities", "conditional_break")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_with_dsym_python(self):
"""Exercise some thread and frame APIs to break if c() is called by a()."""
self.buildDsym()
self.do_conditional_break()
@python_api_test
@dwarf_test
def test_with_dwarf_python(self):
"""Exercise some thread and frame APIs to break if c() is called by a()."""
self.buildDwarf()
self.do_conditional_break()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym_command(self):
"""Simulate a user using lldb commands to break on c() if called from a()."""
self.buildDsym()
self.simulate_conditional_break_by_user()
@dwarf_test
def test_with_dwarf_command(self):
"""Simulate a user using lldb commands to break on c() if called from a()."""
self.buildDwarf()
self.simulate_conditional_break_by_user()
def do_conditional_break(self):
"""Exercise some thread and frame APIs to break if c() is called by a()."""
exe = os.path.join(os.getcwd(), "a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
breakpoint = target.BreakpointCreateByName("c", exe)
self.assertTrue(breakpoint, VALID_BREAKPOINT)
# Now launch the process, and do not stop at entry point.
process = target.LaunchSimple(None, None, os.getcwd())
self.assertTrue(process, PROCESS_IS_VALID)
# The stop reason of the thread should be breakpoint.
self.assertTrue(process.GetState() == lldb.eStateStopped,
STOPPED_DUE_TO_BREAKPOINT)
# Find the line number where a's parent frame function is c.
line = line_number('main.c',
"// Find the line number where c's parent frame is a here.")
# Suppose we are only interested in the call scenario where c()'s
# immediate caller is a() and we want to find out the value passed from
# a().
#
# The 10 in range(10) is just an arbitrary number, which means we would
# like to try for at most 10 times.
for j in range(10):
if self.TraceOn():
print "j is: ", j
thread = process.GetThreadAtIndex(0)
if thread.GetNumFrames() >= 2:
frame0 = thread.GetFrameAtIndex(0)
name0 = frame0.GetFunction().GetName()
frame1 = thread.GetFrameAtIndex(1)
name1 = frame1.GetFunction().GetName()
#lldbutil.print_stacktrace(thread)
self.assertTrue(name0 == "c", "Break on function c()")
if (name1 == "a"):
# By design, we know that a() calls c() only from main.c:27.
# In reality, similar logic can be used to find out the call
# site.
self.assertTrue(frame1.GetLineEntry().GetLine() == line,
"Immediate caller a() at main.c:%d" % line)
# And the local variable 'val' should have a value of (int) 3.
val = frame1.FindVariable("val")
self.assertTrue(val.GetTypeName() == "int", "'val' has int type")
self.assertTrue(val.GetValue() == "3", "'val' has a value of 3")
break
process.Continue()
def simulate_conditional_break_by_user(self):
"""Simulate a user using lldb commands to break on c() if called from a()."""
# Sourcing .lldb in the current working directory, which sets the main
# executable, sets the breakpoint on c(), and adds the callback for the
# breakpoint such that lldb only stops when the caller of c() is a().
# the "my" package that defines the date() function.
if self.TraceOn():
print "About to source .lldb"
if not self.TraceOn():
self.HideStdout()
self.runCmd("command source .lldb")
if self.TraceOn():
print "About to run."
self.runCmd("run", RUN_SUCCEEDED)
if self.TraceOn():
print "Done running"
# The stop reason of the thread should be breakpoint.
self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
substrs = ['stopped', 'stop reason = breakpoint'])
# The frame info for frame #0 points to a.out`c and its immediate caller
# (frame #1) points to a.out`a.
self.expect("frame info", "We should stop at c()",
substrs = ["a.out`c"])
# Select our parent frame as the current frame.
self.runCmd("frame select 1")
self.expect("frame info", "The immediate caller should be a()",
substrs = ["a.out`a"])
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()