Home | History | Annotate | Download | only in breakpoint_command
      1 """
      2 Test lldb breakpoint command add/list/delete.
      3 """
      4 
      5 import os, time
      6 import unittest2
      7 import lldb
      8 from lldbtest import *
      9 import lldbutil
     10 
     11 class BreakpointCommandTestCase(TestBase):
     12 
     13     mydir = os.path.join("functionalities", "breakpoint", "breakpoint_command")
     14 
     15     @classmethod
     16     def classCleanup(cls):
     17         """Cleanup the test byproduct of breakpoint_command_sequence(self)."""
     18         cls.RemoveTempFile("output.txt")
     19         cls.RemoveTempFile("output2.txt")
     20 
     21     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     22     @dsym_test
     23     def test_with_dsym(self):
     24         """Test a sequence of breakpoint command add, list, and delete."""
     25         self.buildDsym()
     26         self.breakpoint_command_sequence()
     27         self.breakpoint_command_script_parameters ()
     28 
     29     @dwarf_test
     30     def test_with_dwarf(self):
     31         """Test a sequence of breakpoint command add, list, and delete."""
     32         self.buildDwarf()
     33         self.breakpoint_command_sequence()
     34         self.breakpoint_command_script_parameters ()
     35 
     36     def setUp(self):
     37         # Call super's setUp().
     38         TestBase.setUp(self)
     39         # Find the line number to break inside main().
     40         self.line = line_number('main.c', '// Set break point at this line.')
     41         # disable "There is a running process, kill it and restart?" prompt
     42         self.runCmd("settings set auto-confirm true")
     43         self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
     44 
     45     def breakpoint_command_sequence(self):
     46         """Test a sequence of breakpoint command add, list, and delete."""
     47         exe = os.path.join(os.getcwd(), "a.out")
     48         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
     49 
     50         # Add three breakpoints on the same line.  The first time we don't specify the file,
     51         # since the default file is the one containing main:
     52         lldbutil.run_break_set_by_file_and_line (self, None, self.line, num_expected_locations=1, loc_exact=True)
     53         lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
     54         lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
     55 
     56         # Now add callbacks for the breakpoints just created.
     57         self.runCmd("breakpoint command add -s command -o 'frame variable --show-types --scope' 1")
     58         self.runCmd("breakpoint command add -s python -o 'here = open(\"output.txt\", \"w\"); print >> here, \"lldb\"; here.close()' 2")
     59         self.runCmd("breakpoint command add --python-function bktptcmd.function 3")
     60 
     61         # Check that the breakpoint commands are correctly set.
     62 
     63         # The breakpoint list now only contains breakpoint 1.
     64         self.expect("breakpoint list", "Breakpoints 1 & 2 created",
     65             substrs = ["2: file = 'main.c', line = %d, locations = 1" % self.line],
     66             patterns = ["1: file = '.*main.c', line = %d, locations = 1" % self.line] )
     67 
     68         self.expect("breakpoint list -f", "Breakpoints 1 & 2 created",
     69             substrs = ["2: file = 'main.c', line = %d, locations = 1" % self.line],
     70             patterns = ["1: file = '.*main.c', line = %d, locations = 1" % self.line,
     71                         "1.1: .+at main.c:%d, .+unresolved, hit count = 0" % self.line,
     72                         "2.1: .+at main.c:%d, .+unresolved, hit count = 0" % self.line])
     73 
     74         self.expect("breakpoint command list 1", "Breakpoint 1 command ok",
     75             substrs = ["Breakpoint commands:",
     76                           "frame variable --show-types --scope"])
     77         self.expect("breakpoint command list 2", "Breakpoint 2 command ok",
     78             substrs = ["Breakpoint commands:",
     79                           "here = open",
     80                           "print >> here",
     81                           "here.close()"])
     82         self.expect("breakpoint command list 3", "Breakpoint 3 command ok",
     83             substrs = ["Breakpoint commands:",
     84                           "bktptcmd.function(frame, bp_loc, internal_dict)"])
     85 
     86         self.runCmd("command script import --allow-reload ./bktptcmd.py")
     87 
     88         # Next lets try some other breakpoint kinds.  First break with a regular expression
     89         # and then specify only one file.  The first time we should get two locations,
     90         # the second time only one:
     91 
     92         lldbutil.run_break_set_by_regexp (self, r"._MyFunction", num_expected_locations=2)
     93         
     94         lldbutil.run_break_set_by_regexp (self, r"._MyFunction", extra_options="-f a.c", num_expected_locations=1)
     95       
     96         lldbutil.run_break_set_by_regexp (self, r"._MyFunction", extra_options="-f a.c -f b.c", num_expected_locations=2)
     97 
     98         # Now try a source regex breakpoint:
     99         lldbutil.run_break_set_by_source_regexp (self, r"is about to return [12]0", extra_options="-f a.c -f b.c", num_expected_locations=2)
    100       
    101         lldbutil.run_break_set_by_source_regexp (self, r"is about to return [12]0", extra_options="-f a.c", num_expected_locations=1)
    102       
    103         # Run the program.  Remove 'output.txt' if it exists.
    104         self.RemoveTempFile("output.txt")
    105         self.RemoveTempFile("output2.txt")
    106         self.runCmd("run", RUN_SUCCEEDED)
    107 
    108         # Check that the file 'output.txt' exists and contains the string "lldb".
    109 
    110         # The 'output.txt' file should now exist.
    111         self.assertTrue(os.path.isfile("output.txt"),
    112                         "'output.txt' exists due to breakpoint command for breakpoint 2.")
    113         self.assertTrue(os.path.isfile("output2.txt"),
    114                         "'output2.txt' exists due to breakpoint command for breakpoint 3.")
    115 
    116         # Read the output file produced by running the program.
    117         with open('output.txt', 'r') as f:
    118             output = f.read()
    119 
    120         self.expect(output, "File 'output.txt' and the content matches", exe=False,
    121             startstr = "lldb")
    122 
    123         with open('output2.txt', 'r') as f:
    124             output = f.read()
    125 
    126         self.expect(output, "File 'output2.txt' and the content matches", exe=False,
    127             startstr = "lldb")
    128 
    129 
    130         # Finish the program.
    131         self.runCmd("process continue")
    132 
    133         # Remove the breakpoint command associated with breakpoint 1.
    134         self.runCmd("breakpoint command delete 1")
    135 
    136         # Remove breakpoint 2.
    137         self.runCmd("breakpoint delete 2")
    138 
    139         self.expect("breakpoint command list 1",
    140             startstr = "Breakpoint 1 does not have an associated command.")
    141         self.expect("breakpoint command list 2", error=True,
    142             startstr = "error: '2' is not a currently valid breakpoint id.")
    143 
    144         # The breakpoint list now only contains breakpoint 1.
    145         self.expect("breakpoint list -f", "Breakpoint 1 exists",
    146             patterns = ["1: file = '.*main.c', line = %d, locations = 1, resolved = 1" %
    147                         self.line,
    148                        "hit count = 1"])
    149 
    150         # Not breakpoint 2.
    151         self.expect("breakpoint list -f", "No more breakpoint 2", matching=False,
    152             substrs = ["2: file = 'main.c', line = %d, locations = 1, resolved = 1" %
    153                         self.line])
    154 
    155         # Run the program again, with breakpoint 1 remaining.
    156         self.runCmd("run", RUN_SUCCEEDED)
    157 
    158         # We should be stopped again due to breakpoint 1.
    159 
    160         # The stop reason of the thread should be breakpoint.
    161         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
    162             substrs = ['stopped',
    163                        'stop reason = breakpoint'])
    164 
    165         # The breakpoint should have a hit count of 2.
    166         self.expect("breakpoint list -f", BREAKPOINT_HIT_TWICE,
    167             substrs = ['resolved, hit count = 2'])
    168 
    169     def breakpoint_command_script_parameters (self):
    170         """Test that the frame and breakpoint location are being properly passed to the script breakpoint command function."""
    171         exe = os.path.join(os.getcwd(), "a.out")
    172         self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
    173 
    174         # Add a breakpoint.
    175         lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
    176 
    177         # Now add callbacks for the breakpoints just created.
    178         self.runCmd("breakpoint command add -s python -o 'here = open(\"output-2.txt\", \"w\"); print >> here, frame; print >> here, bp_loc; here.close()' 1")
    179 
    180         # Remove 'output-2.txt' if it already exists.
    181 
    182         if (os.path.exists('output-2.txt')):
    183             os.remove ('output-2.txt')
    184 
    185         # Run program, hit breakpoint, and hopefully write out new version of 'output-2.txt'
    186         self.runCmd ("run", RUN_SUCCEEDED)
    187 
    188         # Check that the file 'output.txt' exists and contains the string "lldb".
    189 
    190         # The 'output-2.txt' file should now exist.
    191         self.assertTrue(os.path.isfile("output-2.txt"),
    192                         "'output-2.txt' exists due to breakpoint command for breakpoint 1.")
    193 
    194         # Read the output file produced by running the program.
    195         with open('output-2.txt', 'r') as f:
    196             output = f.read()
    197 
    198         self.expect (output, "File 'output-2.txt' and the content matches", exe=False,
    199                      startstr = "frame #0:",
    200                      patterns = ["1.* where = .*main .* resolved, hit count = 1" ])
    201 
    202         # Now remove 'output-2.txt'
    203         os.remove ('output-2.txt')
    204 
    205 if __name__ == '__main__':
    206     import atexit
    207     lldb.SBDebugger.Initialize()
    208     atexit.register(lambda: lldb.SBDebugger.Terminate())
    209     unittest2.main()
    210