[Lldb-commits] [lldb] r281690 - First tests for serializing breakpoints.
Jim Ingham via lldb-commits
lldb-commits at lists.llvm.org
Thu Sep 15 18:41:27 PDT 2016
Author: jingham
Date: Thu Sep 15 20:41:27 2016
New Revision: 281690
URL: http://llvm.org/viewvc/llvm-project?rev=281690&view=rev
Log:
First tests for serializing breakpoints.
Plus a few bug fixes I found along the way.
Added:
lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/
lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/Makefile
lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py
lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/main.c
Modified:
lldb/trunk/include/lldb/API/SBBreakpoint.h
lldb/trunk/scripts/interface/SBBreakpoint.i
lldb/trunk/source/API/SBBreakpoint.cpp
lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp
lldb/trunk/source/Core/SearchFilter.cpp
Modified: lldb/trunk/include/lldb/API/SBBreakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBBreakpoint.h?rev=281690&r1=281689&r2=281690&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBBreakpoint.h (original)
+++ lldb/trunk/include/lldb/API/SBBreakpoint.h Thu Sep 15 20:41:27 2016
@@ -104,6 +104,8 @@ public:
bool GetDescription(lldb::SBStream &description);
+ bool GetDescription(lldb::SBStream &description, bool include_locations);
+
static bool EventIsBreakpointEvent(const lldb::SBEvent &event);
static lldb::BreakpointEventType
@@ -152,6 +154,8 @@ public:
SBBreakpoint GetBreakpointAtIndex(size_t idx);
+ SBBreakpoint FindBreakpointByID(lldb::break_id_t);
+
void Append(const SBBreakpoint &sb_file);
bool AppendIfUnique(const SBBreakpoint &sb_file);
Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/Makefile?rev=281690&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/Makefile Thu Sep 15 20:41:27 2016
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py?rev=281690&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py Thu Sep 15 20:41:27 2016
@@ -0,0 +1,147 @@
+"""
+Test breakpoint ignore count features.
+"""
+
+from __future__ import print_function
+
+
+import os
+import time
+import re
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class BreakpointSerialization(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @add_test_categories(['pyapi'])
+ def test_resolvers(self):
+ """Use Python APIs to test that we serialize resolvers."""
+ self.build()
+ self.setup_targets_and_cleanup()
+ self.do_check_resolvers()
+
+ def not_test_filters(self):
+ """Use Python APIs to test that we serialize search filters correctly."""
+ self.build()
+ self.setup_targets_and_cleanup()
+ self.check_filters()
+
+ def not_test_options(self):
+ """Use Python APIs to test that we serialize breakpoint options correctly."""
+ self.build()
+ self.setup_targets_and_cleanup()
+ self.check_filters()
+
+ def not_test_complex(self):
+ """Use Python APIs to test that we serialize complex breakpoints correctly."""
+ self.build()
+ self.setup_targets_and_cleanup()
+ self.check_filters()
+
+ def setup_targets_and_cleanup(self):
+ def cleanup ():
+ #self.RemoveTempFile(self.bkpts_file_path)
+
+ if self.orig_target.IsValid():
+ self.dbg.DeleteTarget(self.orig_target)
+ self.dbg.DeleteTarget(self.copy_target)
+
+ self.addTearDownHook(cleanup)
+ #self.RemoveTempFile(self.bkpts_file_path)
+
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a targets we are making breakpoint in and copying to:
+ self.orig_target = self.dbg.CreateTarget(exe)
+ self.assertTrue(self.orig_target, VALID_TARGET)
+
+ self.copy_target = self.dbg.CreateTarget(exe)
+ self.assertTrue(self.copy_target, VALID_TARGET)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ self.bkpts_file_path = os.path.join(os.getcwd(), "breakpoints.json")
+ self.bkpts_file_spec = lldb.SBFileSpec(self.bkpts_file_path)
+
+ def do_check_resolvers(self):
+ """Use Python APIs to check serialization of breakpoint resolvers"""
+
+ empty_module_list = lldb.SBFileSpecList()
+ empty_cu_list = lldb.SBFileSpecList()
+ blubby_file_spec = lldb.SBFileSpec(os.path.join(os.getcwd(), "blubby.c"))
+
+ # It isn't actually important for these purposes that these breakpoint
+ # actually have locations.
+ source_bps = lldb.SBBreakpointList(self.orig_target)
+ source_bps.Append(self.orig_target.BreakpointCreateByLocation("blubby.c", 666))
+ source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list))
+ source_bps.Append(self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list))
+ source_bps.Append(self.orig_target.BreakpointCreateBySourceRegex("dont really care", blubby_file_spec))
+
+ error = lldb.SBError()
+ error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec)
+ self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
+
+ copy_bps = lldb.SBBreakpointList(self.copy_target)
+ error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, copy_bps)
+ self.assertTrue(error.Success(), "Failed reading breakpoints from file: %s"%(error.GetCString()))
+
+ num_source_bps = source_bps.GetSize()
+ num_copy_bps = copy_bps.GetSize()
+ self.assertTrue(num_source_bps == num_copy_bps, "Didn't get same number of input and output breakpoints - orig: %d copy: %d"%(num_source_bps, num_copy_bps))
+
+ for i in range(0, num_source_bps):
+ source_bp = source_bps.GetBreakpointAtIndex(i)
+ source_desc = lldb.SBStream()
+ source_bp.GetDescription(source_desc, False)
+ source_text = source_desc.GetData()
+
+ # I am assuming here that the breakpoints will get written out in breakpoint ID order, and
+ # read back in ditto. That is true right now, and I can't see any reason to do it differently
+ # but if we do we can go to writing the breakpoints one by one, or sniffing the descriptions to
+ # see which one is which.
+ copy_id = source_bp.GetID()
+ copy_bp = copy_bps.FindBreakpointByID(copy_id)
+ self.assertTrue(copy_bp.IsValid(), "Could not find copy breakpoint %d."%(copy_id))
+
+ copy_desc = lldb.SBStream()
+ copy_bp.GetDescription(copy_desc, False)
+ copy_text = copy_desc.GetData()
+
+ # These two should be identical.
+ print ("Source test for %d is %s."%(i, source_text))
+ self.assertTrue (source_text == copy_text, "Source and dest breakpoints are not identical: \nsource: %s\ndest: %s"%(source_text, copy_text))
+
+ def check_filters(self):
+ """Use Python APIs to check serialization of breakpoint filters."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ def check_options(self):
+ """Use Python APIs to check serialization of breakpoint options."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ def check_resolvers(self):
+ """Use Python APIs to check serialization of breakpoint resolvers."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+
+
Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/main.c?rev=281690&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/main.c (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/main.c Thu Sep 15 20:41:27 2016
@@ -0,0 +1,54 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdio.h>
+
+// This simple program is to demonstrate the capability of the lldb command
+// "breakpoint modify -i <count> breakpt-id" to set the number of times a
+// breakpoint is skipped before stopping. Ignore count can also be set upon
+// breakpoint creation by 'breakpoint set ... -i <count>'.
+
+int a(int);
+int b(int);
+int c(int);
+
+int a(int val)
+{
+ if (val <= 1)
+ return b(val);
+ else if (val >= 3)
+ return c(val); // a(3) -> c(3) Find the call site of c(3).
+
+ return val;
+}
+
+int b(int val)
+{
+ return c(val);
+}
+
+int c(int val)
+{
+ return val + 3; // Find the line number of function "c" here.
+}
+
+int main (int argc, char const *argv[])
+{
+ int A1 = a(1); // a(1) -> b(1) -> c(1)
+ printf("a(1) returns %d\n", A1);
+
+ int B2 = b(2); // b(2) -> c(2) Find the call site of b(2).
+ printf("b(2) returns %d\n", B2);
+
+ int A3 = a(3); // a(3) -> c(3) Find the call site of a(3).
+ printf("a(3) returns %d\n", A3);
+
+ int C1 = c(5); // Find the call site of c in main.
+ printf ("c(5) returns %d\n", C1);
+ return 0;
+}
Modified: lldb/trunk/scripts/interface/SBBreakpoint.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBBreakpoint.i?rev=281690&r1=281689&r2=281690&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBBreakpoint.i (original)
+++ lldb/trunk/scripts/interface/SBBreakpoint.i Thu Sep 15 20:41:27 2016
@@ -221,6 +221,9 @@ public:
bool
GetDescription (lldb::SBStream &description);
+ bool
+ GetDescription(lldb::SBStream &description, bool include_locations);
+
bool
operator == (const lldb::SBBreakpoint& rhs);
@@ -276,6 +279,9 @@ public:
SBBreakpoint
GetBreakpointAtIndex(size_t idx);
+
+ SBBreakpoint
+ FindBreakpointByID(lldb::break_id_t);
void Append(const SBBreakpoint &sb_bkpt);
Modified: lldb/trunk/source/API/SBBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBreakpoint.cpp?rev=281690&r1=281689&r2=281690&view=diff
==============================================================================
--- lldb/trunk/source/API/SBBreakpoint.cpp (original)
+++ lldb/trunk/source/API/SBBreakpoint.cpp Thu Sep 15 20:41:27 2016
@@ -449,14 +449,20 @@ size_t SBBreakpoint::GetNumLocations() c
}
bool SBBreakpoint::GetDescription(SBStream &s) {
+ return GetDescription(s, true);
+}
+
+bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
if (m_opaque_sp) {
std::lock_guard<std::recursive_mutex> guard(
m_opaque_sp->GetTarget().GetAPIMutex());
s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
m_opaque_sp->GetResolverDescription(s.get());
m_opaque_sp->GetFilterDescription(s.get());
- const size_t num_locations = m_opaque_sp->GetNumLocations();
- s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
+ if (include_locations) {
+ const size_t num_locations = m_opaque_sp->GetNumLocations();
+ s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
+ }
return true;
}
s.Printf("No value");
@@ -702,6 +708,18 @@ public:
return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);
}
+ BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {
+ TargetSP target_sp = m_target_wp.lock();
+ if (!target_sp)
+ return BreakpointSP();
+
+ for (lldb::break_id_t &break_id : m_break_ids) {
+ if (break_id == desired_id)
+ return target_sp->GetBreakpointList().FindBreakpointByID(break_id);
+ }
+ return BreakpointSP();
+ }
+
bool Append(Breakpoint &bkpt) {
TargetSP target_sp = m_target_wp.lock();
if (!target_sp)
@@ -772,6 +790,13 @@ SBBreakpoint SBBreakpointList::GetBreakp
return SBBreakpoint(bkpt_sp);
}
+SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {
+ if (!m_opaque_sp)
+ return SBBreakpoint();
+ BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);
+ return SBBreakpoint(bkpt_sp);
+}
+
void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
if (!sb_bkpt.IsValid())
return;
Modified: lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp?rev=281690&r1=281689&r2=281690&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp Thu Sep 15 20:41:27 2016
@@ -30,7 +30,7 @@ using namespace lldb_private;
BreakpointResolverFileRegex::BreakpointResolverFileRegex(
Breakpoint *bkpt, RegularExpression ®ex,
const std::unordered_set<std::string> &func_names, bool exact_match)
- : BreakpointResolver(bkpt, BreakpointResolver::FileLineResolver),
+ : BreakpointResolver(bkpt, BreakpointResolver::FileRegexResolver),
m_regex(regex), m_exact_match(exact_match), m_function_names(func_names) {
}
Modified: lldb/trunk/source/Core/SearchFilter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/SearchFilter.cpp?rev=281690&r1=281689&r2=281690&view=diff
==============================================================================
--- lldb/trunk/source/Core/SearchFilter.cpp (original)
+++ lldb/trunk/source/Core/SearchFilter.cpp Thu Sep 15 20:41:27 2016
@@ -37,7 +37,7 @@ const char *SearchFilter::FilterTyToName
}
SearchFilter::FilterTy SearchFilter::NameToFilterTy(const char *name) {
- for (size_t i = 0; i < LastKnownFilterType; i++) {
+ for (size_t i = 0; i <= LastKnownFilterType; i++) {
if (strcmp(name, g_ty_to_name[i]) == 0)
return (FilterTy)i;
}
@@ -163,8 +163,13 @@ SearchFilter::WrapOptionsDict(Structured
void SearchFilter::SerializeFileSpecList(
StructuredData::DictionarySP &options_dict_sp, OptionNames name,
FileSpecList &file_list) {
- StructuredData::ArraySP module_array_sp(new StructuredData::Array());
size_t num_modules = file_list.GetSize();
+
+ // Don't serialize empty lists.
+ if (num_modules == 0)
+ return;
+
+ StructuredData::ArraySP module_array_sp(new StructuredData::Array());
for (size_t i = 0; i < num_modules; i++) {
module_array_sp->AddItem(StructuredData::StringSP(
new StructuredData::String(file_list.GetFileSpecAtIndex(i).GetPath())));
@@ -630,22 +635,19 @@ SearchFilterSP SearchFilterByModuleList:
StructuredData::Array *modules_array;
bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
modules_array);
- if (!success) {
- error.SetErrorString("SFBM::CFSD: Could not find the module list key.");
- return nullptr;
- }
-
- size_t num_modules = modules_array->GetSize();
FileSpecList modules;
- for (size_t i = 0; i < num_modules; i++) {
- std::string module;
- success = modules_array->GetItemAtIndexAsString(i, module);
- if (!success) {
- error.SetErrorStringWithFormat(
- "SFBM::CFSD: filter module item %zu not a string.", i);
- return nullptr;
+ if (success) {
+ size_t num_modules = modules_array->GetSize();
+ for (size_t i = 0; i < num_modules; i++) {
+ std::string module;
+ success = modules_array->GetItemAtIndexAsString(i, module);
+ if (!success) {
+ error.SetErrorStringWithFormat(
+ "SFBM::CFSD: filter module item %zu not a string.", i);
+ return nullptr;
+ }
+ modules.Append(FileSpec(module.c_str(), false));
}
- modules.Append(FileSpec(module.c_str(), false));
}
return SearchFilterSP(
@@ -694,29 +696,26 @@ SearchFilterByModuleListAndCU::~SearchFi
lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData(
Target &target, const StructuredData::Dictionary &data_dict, Error &error) {
- StructuredData::Array *modules_array;
+ StructuredData::Array *modules_array = nullptr;
SearchFilterSP result_sp;
bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
modules_array);
- if (!success) {
- error.SetErrorString("SFBM::CFSD: Could not find the module list key.");
- return result_sp;
- }
-
- size_t num_modules = modules_array->GetSize();
FileSpecList modules;
- for (size_t i = 0; i < num_modules; i++) {
- std::string module;
- success = modules_array->GetItemAtIndexAsString(i, module);
- if (!success) {
- error.SetErrorStringWithFormat(
- "SFBM::CFSD: filter module item %zu not a string.", i);
- return result_sp;
+ if (success) {
+ size_t num_modules = modules_array->GetSize();
+ for (size_t i = 0; i < num_modules; i++) {
+ std::string module;
+ success = modules_array->GetItemAtIndexAsString(i, module);
+ if (!success) {
+ error.SetErrorStringWithFormat(
+ "SFBM::CFSD: filter module item %zu not a string.", i);
+ return result_sp;
+ }
+ modules.Append(FileSpec(module.c_str(), false));
}
- modules.Append(FileSpec(module.c_str(), false));
}
- StructuredData::Array *cus_array;
+ StructuredData::Array *cus_array = nullptr;
success =
data_dict.GetValueForKeyAsArray(GetKey(OptionNames::CUList), cus_array);
if (!success) {
@@ -728,7 +727,7 @@ lldb::SearchFilterSP SearchFilterByModul
FileSpecList cus;
for (size_t i = 0; i < num_cus; i++) {
std::string cu;
- success = modules_array->GetItemAtIndexAsString(i, cu);
+ success = cus_array->GetItemAtIndexAsString(i, cu);
if (!success) {
error.SetErrorStringWithFormat(
"SFBM::CFSD: filter cu item %zu not a string.", i);
More information about the lldb-commits
mailing list