Home | History | Annotate | Download | only in breakpoint_ignore_count
      1 """
      2 Test breakpoint ignore count features.
      3 """
      4 
      5 import os, time
      6 import re
      7 import unittest2
      8 import lldb, lldbutil
      9 from lldbtest import *
     10 
     11 class BreakpointIgnoreCountTestCase(TestBase):
     12 
     13     mydir = os.path.join("functionalities", "breakpoint", "breakpoint_ignore_count")
     14 
     15     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     16     @dsym_test
     17     def test_with_dsym_and_run_command(self):
     18         """Exercise breakpoint ignore count with 'breakpoint set -i <count>'."""
     19         self.buildDsym()
     20         self.breakpoint_ignore_count()
     21 
     22     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     23     @python_api_test
     24     @dsym_test
     25     def test_with_dsym_and_python_api(self):
     26         """Use Python APIs to set breakpoint ignore count."""
     27         self.buildDsym()
     28         self.breakpoint_ignore_count_python()
     29 
     30     @dwarf_test
     31     def test_with_dwarf_and_run_command(self):
     32         """Exercise breakpoint ignore count with 'breakpoint set -i <count>'."""
     33         self.buildDwarf()
     34         self.breakpoint_ignore_count()
     35 
     36     @python_api_test
     37     @dwarf_test
     38     def test_with_dwarf_and_python_api(self):
     39         """Use Python APIs to set breakpoint ignore count."""
     40         self.buildDwarf()
     41         self.breakpoint_ignore_count_python()
     42 
     43     def setUp(self):
     44         # Call super's setUp().
     45         TestBase.setUp(self)
     46         # Find the line number to of function 'c'.
     47         self.line1 = line_number('main.c', '// Find the line number of function "c" here.')
     48         self.line2 = line_number('main.c', '// b(2) -> c(2) Find the call site of b(2).')
     49         self.line3 = line_number('main.c', '// a(3) -> c(3) Find the call site of c(3).')
     50         self.line4 = line_number('main.c', '// a(3) -> c(3) Find the call site of a(3).')
     51         self.line5 = line_number('main.c', '// Find the call site of c in main.')
     52 
     53     def breakpoint_ignore_count(self):
     54         """Exercise breakpoint ignore count with 'breakpoint set -i <count>'."""
     55         exe = os.path.join(os.getcwd(), "a.out")
     56         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
     57 
     58         # Create a breakpoint in main.c at line1.
     59         lldbutil.run_break_set_by_file_and_line (self, 'main.c', self.line1, extra_options='-i 1', num_expected_locations=1, loc_exact=True)
     60 
     61         # Now run the program.
     62         self.runCmd("run", RUN_SUCCEEDED)
     63 
     64         # The process should be stopped at this point.
     65         self.expect("process status", PROCESS_STOPPED,
     66             patterns = ['Process .* stopped'])
     67 
     68         # Also check the hit count, which should be 2, due to ignore count of 1.
     69         self.expect("breakpoint list -f", BREAKPOINT_HIT_THRICE,
     70             substrs = ["resolved = 1",
     71                        "hit count = 2"])
     72 
     73         # The frame #0 should correspond to main.c:37, the executable statement
     74         # in function name 'c'.  And frame #2 should point to main.c:45.
     75         self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT,
     76             #substrs = ["stop reason = breakpoint"],
     77             patterns = ["frame #0.*main.c:%d" % self.line1,
     78                         "frame #2.*main.c:%d" % self.line2])
     79 
     80         # continue -i 1 is the same as setting the ignore count to 1 again, try that:
     81         # Now run the program.
     82         self.runCmd("process continue -i 1", RUN_SUCCEEDED)
     83 
     84         # The process should be stopped at this point.
     85         self.expect("process status", PROCESS_STOPPED,
     86             patterns = ['Process .* stopped'])
     87 
     88         # Also check the hit count, which should be 2, due to ignore count of 1.
     89         self.expect("breakpoint list -f", BREAKPOINT_HIT_THRICE,
     90             substrs = ["resolved = 1",
     91                        "hit count = 4"])
     92 
     93         # The frame #0 should correspond to main.c:37, the executable statement
     94         # in function name 'c'.  And frame #2 should point to main.c:45.
     95         self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT,
     96             #substrs = ["stop reason = breakpoint"],
     97             patterns = ["frame #0.*main.c:%d" % self.line1,
     98                         "frame #1.*main.c:%d" % self.line5])
     99 
    100         
    101 
    102     def breakpoint_ignore_count_python(self):
    103         """Use Python APIs to set breakpoint ignore count."""
    104         exe = os.path.join(os.getcwd(), "a.out")
    105 
    106         # Create a target by the debugger.
    107         target = self.dbg.CreateTarget(exe)
    108         self.assertTrue(target, VALID_TARGET)
    109 
    110         # Now create a breakpoint on main.c by name 'c'.
    111         breakpoint = target.BreakpointCreateByName('c', 'a.out')
    112         self.assertTrue(breakpoint and
    113                         breakpoint.GetNumLocations() == 1,
    114                         VALID_BREAKPOINT)
    115 
    116         # Get the breakpoint location from breakpoint after we verified that,
    117         # indeed, it has one location.
    118         location = breakpoint.GetLocationAtIndex(0)
    119         self.assertTrue(location and
    120                         location.IsEnabled(),
    121                         VALID_BREAKPOINT_LOCATION)
    122 
    123         # Set the ignore count on the breakpoint location.
    124         location.SetIgnoreCount(2)
    125         self.assertTrue(location.GetIgnoreCount() == 2,
    126                         "SetIgnoreCount() works correctly")
    127 
    128         # Now launch the process, and do not stop at entry point.
    129         process = target.LaunchSimple(None, None, os.getcwd())
    130         self.assertTrue(process, PROCESS_IS_VALID)
    131 
    132         # Frame#0 should be on main.c:37, frame#1 should be on main.c:25, and
    133         # frame#2 should be on main.c:48.
    134         #lldbutil.print_stacktraces(process)
    135         from lldbutil import get_stopped_thread
    136         thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
    137         self.assertTrue(thread.IsValid(), "There should be a thread stopped due to breakpoint")
    138         frame0 = thread.GetFrameAtIndex(0)
    139         frame1 = thread.GetFrameAtIndex(1)
    140         frame2 = thread.GetFrameAtIndex(2)
    141         self.assertTrue(frame0.GetLineEntry().GetLine() == self.line1 and
    142                         frame1.GetLineEntry().GetLine() == self.line3 and
    143                         frame2.GetLineEntry().GetLine() == self.line4,
    144                         STOPPED_DUE_TO_BREAKPOINT_IGNORE_COUNT)
    145 
    146         # The hit count for the breakpoint should be 3.
    147         self.assertTrue(breakpoint.GetHitCount() == 3)
    148 
    149         process.Continue()
    150 
    151         
    152 if __name__ == '__main__':
    153     import atexit
    154     lldb.SBDebugger.Initialize()
    155     atexit.register(lambda: lldb.SBDebugger.Terminate())
    156     unittest2.main()
    157