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        target = self.createTestTarget()
28
29        self.runCmd("tb a")
30        process = target.LaunchSimple(
31            None, None, self.get_process_working_directory())
32        self.assertTrue(process, PROCESS_IS_VALID)
33
34        from lldbsuite.test.lldbutil import get_stopped_thread
35        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
36        self.assertTrue(
37            thread.IsValid(),
38            "There should be a thread stopped due to breakpoint")
39
40        frame0 = thread.GetFrameAtIndex(0)
41        self.assertTrue(frame0.GetFunctionName() == "a(int)" or frame0.GetFunctionName() == "int a(int)");
42
43        process.Continue()
44        self.assertEqual(process.GetState(), lldb.eStateExited)
45
46    def setUp(self):
47        # Call super's setUp().
48        TestBase.setUp(self)
49        self.a_int_body_line_no = line_number(
50            'main.cpp', '// Breakpoint Location 1')
51        self.a_float_body_line_no = line_number(
52            'main.cpp', '// Breakpoint Location 2')
53
54    def do_test_breakpoint_location_hit_count(self):
55        """Use Python APIs to check breakpoint hit count."""
56        target = self.createTestTarget()
57
58        # Create a breakpoint in main.cpp by name 'a',
59        # there should be two locations.
60        breakpoint = target.BreakpointCreateByName('a', 'a.out')
61        self.assertTrue(breakpoint and
62                        breakpoint.GetNumLocations() == 2,
63                        VALID_BREAKPOINT)
64
65        # Verify all breakpoint locations are enabled.
66        location1 = breakpoint.GetLocationAtIndex(0)
67        self.assertTrue(location1 and
68                        location1.IsEnabled(),
69                        VALID_BREAKPOINT_LOCATION)
70
71        location2 = breakpoint.GetLocationAtIndex(1)
72        self.assertTrue(location2 and
73                        location2.IsEnabled(),
74                        VALID_BREAKPOINT_LOCATION)
75
76        # Launch the process, and do not stop at entry point.
77        process = target.LaunchSimple(
78            None, None, self.get_process_working_directory())
79        self.assertTrue(process, PROCESS_IS_VALID)
80
81        # Verify 1st breakpoint location is hit.
82        from lldbsuite.test.lldbutil import get_stopped_thread
83        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
84        self.assertTrue(
85            thread.IsValid(),
86            "There should be a thread stopped due to breakpoint")
87
88        frame0 = thread.GetFrameAtIndex(0)
89        location1 = breakpoint.FindLocationByAddress(frame0.GetPC())
90        self.assertEqual(
91            frame0.GetLineEntry().GetLine(), self.a_int_body_line_no,
92            "Stopped in int a(int)")
93        self.assertTrue(location1)
94        self.assertEqual(location1.GetHitCount(), 1)
95        self.assertEqual(breakpoint.GetHitCount(), 1)
96
97        process.Continue()
98
99        # Verify 2nd breakpoint location is hit.
100        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
101        self.assertTrue(
102            thread.IsValid(),
103            "There should be a thread stopped due to breakpoint")
104
105        frame0 = thread.GetFrameAtIndex(0)
106        location2 = breakpoint.FindLocationByAddress(frame0.GetPC())
107        self.assertEqual(
108            frame0.GetLineEntry().GetLine(), self.a_float_body_line_no,
109            "Stopped in float a(float)")
110        self.assertTrue(location2)
111        self.assertEqual(location2.GetHitCount(), 1)
112        self.assertEqual(location1.GetHitCount(), 1)
113        self.assertEqual(breakpoint.GetHitCount(), 2)
114
115        process.Continue()
116
117        # Verify 2nd breakpoint location is hit again.
118        thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint)
119        self.assertTrue(
120            thread.IsValid(),
121            "There should be a thread stopped due to breakpoint")
122
123        self.assertEqual(location2.GetHitCount(), 2)
124        self.assertEqual(location1.GetHitCount(), 1)
125        self.assertEqual(breakpoint.GetHitCount(), 3)
126
127        process.Continue()
128