1"""
2Test breakpoint hit count features.
3"""
4
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class BreakpointHitCountTestCase(TestBase):
13
14    NO_DEBUG_INFO_TESTCASE = True
15
16    mydir = TestBase.compute_mydir(__file__)
17
18    @add_test_categories(['pyapi'])
19    def test_breakpoint_location_hit_count(self):
20        """Use Python APIs to check breakpoint hit count."""
21        self.build()
22        self.do_test_breakpoint_location_hit_count()
23
24    def test_breakpoint_one_shot(self):
25        """Check that one-shot breakpoints trigger only once."""
26        self.build()
27
28        exe = self.getBuildArtifact("a.out")
29        target = self.dbg.CreateTarget(exe)
30        self.assertTrue(target, VALID_TARGET)
31
32        self.runCmd("tb a")
33        process = target.LaunchSimple(
34            None, None, self.get_process_working_directory())
35        self.assertTrue(process, PROCESS_IS_VALID)
36
37        from lldbsuite.test.lldbutil import get_stopped_thread
38        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
39        self.assertTrue(
40            thread.IsValid(),
41            "There should be a thread stopped due to breakpoint")
42
43        frame0 = thread.GetFrameAtIndex(0)
44        self.assertTrue(frame0.GetFunctionName() == "a(int)" or frame0.GetFunctionName() == "int a(int)");
45
46        process.Continue()
47        self.assertEqual(process.GetState(), lldb.eStateExited)
48
49    def setUp(self):
50        # Call super's setUp().
51        TestBase.setUp(self)
52        self.a_int_body_line_no = line_number(
53            'main.cpp', '// Breakpoint Location 1')
54        self.a_float_body_line_no = line_number(
55            'main.cpp', '// Breakpoint Location 2')
56
57    def do_test_breakpoint_location_hit_count(self):
58        """Use Python APIs to check breakpoint hit count."""
59        exe = self.getBuildArtifact("a.out")
60
61        target = self.dbg.CreateTarget(exe)
62        self.assertTrue(target, VALID_TARGET)
63
64        # Create a breakpoint in main.cpp by name 'a',
65        # there should be two locations.
66        breakpoint = target.BreakpointCreateByName('a', 'a.out')
67        self.assertTrue(breakpoint and
68                        breakpoint.GetNumLocations() == 2,
69                        VALID_BREAKPOINT)
70
71        # Verify all breakpoint locations are enabled.
72        location1 = breakpoint.GetLocationAtIndex(0)
73        self.assertTrue(location1 and
74                        location1.IsEnabled(),
75                        VALID_BREAKPOINT_LOCATION)
76
77        location2 = breakpoint.GetLocationAtIndex(1)
78        self.assertTrue(location2 and
79                        location2.IsEnabled(),
80                        VALID_BREAKPOINT_LOCATION)
81
82        # Launch the process, and do not stop at entry point.
83        process = target.LaunchSimple(
84            None, None, self.get_process_working_directory())
85        self.assertTrue(process, PROCESS_IS_VALID)
86
87        # Verify 1st breakpoint location is hit.
88        from lldbsuite.test.lldbutil import get_stopped_thread
89        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
90        self.assertTrue(
91            thread.IsValid(),
92            "There should be a thread stopped due to breakpoint")
93
94        frame0 = thread.GetFrameAtIndex(0)
95        location1 = breakpoint.FindLocationByAddress(frame0.GetPC())
96        self.assertTrue(
97            frame0.GetLineEntry().GetLine() == self.a_int_body_line_no,
98            "Stopped in int a(int)")
99        self.assertTrue(location1)
100        self.assertEqual(location1.GetHitCount(), 1)
101        self.assertEqual(breakpoint.GetHitCount(), 1)
102
103        process.Continue()
104
105        # Verify 2nd breakpoint location is hit.
106        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
107        self.assertTrue(
108            thread.IsValid(),
109            "There should be a thread stopped due to breakpoint")
110
111        frame0 = thread.GetFrameAtIndex(0)
112        location2 = breakpoint.FindLocationByAddress(frame0.GetPC())
113        self.assertTrue(
114            frame0.GetLineEntry().GetLine() == self.a_float_body_line_no,
115            "Stopped in float a(float)")
116        self.assertTrue(location2)
117        self.assertEqual(location2.GetHitCount(), 1)
118        self.assertEqual(location1.GetHitCount(), 1)
119        self.assertEqual(breakpoint.GetHitCount(), 2)
120
121        process.Continue()
122
123        # Verify 2nd breakpoint location is hit again.
124        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
125        self.assertTrue(
126            thread.IsValid(),
127            "There should be a thread stopped due to breakpoint")
128
129        self.assertEqual(location2.GetHitCount(), 2)
130        self.assertEqual(location1.GetHitCount(), 1)
131        self.assertEqual(breakpoint.GetHitCount(), 3)
132
133        process.Continue()
134