diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp --- a/lldb/source/Breakpoint/Breakpoint.cpp +++ b/lldb/source/Breakpoint/Breakpoint.cpp @@ -532,12 +532,12 @@ locations_with_no_section.Add(break_loc_sp); continue; } - + if (!break_loc_sp->IsEnabled()) continue; - + SectionSP section_sp(section_addr.GetSection()); - + // If we don't have a Section, that means this location is a raw // address that we haven't resolved to a section yet. So we'll have to // look in all the new modules to resolve this location. Otherwise, if @@ -554,9 +554,9 @@ } } } - + size_t num_to_delete = locations_with_no_section.GetSize(); - + for (size_t i = 0; i < num_to_delete; i++) m_locations.RemoveLocation(locations_with_no_section.GetByIndex(i)); @@ -1132,12 +1132,13 @@ bp.try_emplace("resolveTime", m_resolve_time.get().count()); bp.try_emplace("numLocations", (int64_t)GetNumLocations()); bp.try_emplace("numResolvedLocations", (int64_t)GetNumResolvedLocations()); + bp.try_emplace("hitCount", (int64_t)GetHitCount()); bp.try_emplace("internal", IsInternal()); if (!m_kind_description.empty()) bp.try_emplace("kindDescription", m_kind_description); // Put the full structured data for reproducing this breakpoint in a key/value // pair named "details". This allows the breakpoint's details to be visible - // in the stats in case we need to reproduce a breakpoint that has long + // in the stats in case we need to reproduce a breakpoint that has long // resolve times StructuredData::ObjectSP bp_data_sp = SerializeToStructuredData(); if (bp_data_sp) { diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py --- a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py +++ b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py @@ -423,7 +423,6 @@ patterns=["bktptcmd.function"]) - def test_breakpoint_delete_disabled(self): """Test 'break delete --disabled' works""" self.build() @@ -548,3 +547,26 @@ source_map_json = self.get_source_map_json() self.assertEquals(len(source_map_json), 0, "source map should not be deduced") + + + def test_breakpoint_statistics_hitcount(self): + """Test breakpoints statistics have hitCount field.""" + self.build() + target = self.createTestTarget() + + lldbutil.run_break_set_by_file_and_line( + self, "main.c", self.line, num_expected_locations=1, loc_exact=True) + + stream = lldb.SBStream() + res = target.GetStatistics().GetAsJSON(stream) + self.assertTrue(res.Success()) + debug_stats = json.loads(stream.GetData()) + self.assertEqual('targets' in debug_stats, True, + 'Make sure the "targets" key in in target.GetStatistics()') + target_stats = debug_stats['targets'][0] + self.assertNotEqual(target_stats, None) + + breakpoints_stats = target_stats['breakpoints'] + self.assertNotEqual(breakpoints_stats, None) + for breakpoint_stats in breakpoints_stats: + self.assertIn("hitCount", breakpoint_stats)