[Lldb-commits] [lldb] r282207 - Add the ability to deserialize only breakpoints matching a given name.

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Thu Sep 22 15:20:28 PDT 2016


Author: jingham
Date: Thu Sep 22 17:20:28 2016
New Revision: 282207

URL: http://llvm.org/viewvc/llvm-project?rev=282207&view=rev
Log:
Add the ability to deserialize only breakpoints matching a given name.

Also tests for this and the ThreadSpec serialization.

Modified:
    lldb/trunk/include/lldb/API/SBTarget.h
    lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py
    lldb/trunk/scripts/interface/SBTarget.i
    lldb/trunk/source/API/SBTarget.cpp
    lldb/trunk/source/Breakpoint/Breakpoint.cpp
    lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
    lldb/trunk/source/Target/Target.cpp

Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=282207&r1=282206&r2=282207&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Thu Sep 22 17:20:28 2016
@@ -646,15 +646,66 @@ public:
 
   lldb::SBBreakpoint BreakpointCreateBySBAddress(SBAddress &address);
 
-  // Reads in breakpoints from source_file, returning the newly created
-  // breakpoints in new_bps.
+  //------------------------------------------------------------------
+  /// Read breakpoints from source_file and return the newly created
+  /// breakpoints in bkpt_list.
+  ///
+  /// @param[in] source_file
+  ///    The file from which to read the breakpoints.
+  ///
+  /// @param[out] bkpt_list
+  ///    A list of the newly created breakpoints.
+  ///
+  /// @return
+  ///     An SBError detailing any errors in reading in the breakpoints.
+  //------------------------------------------------------------------
   lldb::SBError BreakpointsCreateFromFile(SBFileSpec &source_file,
                                           SBBreakpointList &new_bps);
 
-  // Writes all breakpoints to dest_file.
+  //------------------------------------------------------------------
+  /// Read breakpoints from source_file and return the newly created
+  /// breakpoints in bkpt_list.
+  ///
+  /// @param[in] source_file
+  ///    The file from which to read the breakpoints.
+  ///
+  /// @param[in] matching_names
+  ///    Only read in breakpoints whose names match one of the names in this
+  ///    list.
+  ///
+  /// @param[out] bkpt_list
+  ///    A list of the newly created breakpoints.
+  ///
+  /// @return
+  ///     An SBError detailing any errors in reading in the breakpoints.
+  //------------------------------------------------------------------
+  lldb::SBError BreakpointsCreateFromFile(SBFileSpec &source_file,
+                                          SBStringList &matching_names,
+                                          SBBreakpointList &new_bps);
+
+  //------------------------------------------------------------------
+  /// Write breakpoints to dest_file.
+  ///
+  /// @param[in] dest_file
+  ///    The file to which to write the breakpoints.
+  ///
+  /// @return
+  ///     An SBError detailing any errors in writing in the breakpoints.
+  //------------------------------------------------------------------
   lldb::SBError BreakpointsWriteToFile(SBFileSpec &dest_file);
 
-  // Writes the breakpoints in bkpt_list to dest_file
+  //------------------------------------------------------------------
+  /// Write breakpoints listed in bkpt_list to dest_file.
+  ///
+  /// @param[in] dest_file
+  ///    The file to which to write the breakpoints.
+  ///
+  /// @param[in] bkpt_list
+  ///    Only write breakpoints from this list.
+  ///
+  /// @return
+  ///     An SBError detailing any errors in writing in the breakpoints.
+  //------------------------------------------------------------------
   lldb::SBError BreakpointsWriteToFile(SBFileSpec &dest_file,
                                        SBBreakpointList &bkpt_list);
 

Modified: lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/Breakpoint.h?rev=282207&r1=282206&r2=282207&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/Breakpoint.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/Breakpoint.h Thu Sep 22 17:20:28 2016
@@ -180,6 +180,10 @@ public:
   static lldb::BreakpointSP CreateFromStructuredData(
       Target &target, StructuredData::ObjectSP &data_object_sp, Error &error);
 
+  static bool
+  SerializedBreakpointMatchesNames(StructuredData::ObjectSP &bkpt_object_sp,
+                                   std::vector<std::string> &names);
+
   virtual StructuredData::ObjectSP SerializeToStructuredData();
 
   static const char *GetSerializationKey() { return "Breakpoint"; }

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=282207&r1=282206&r2=282207&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Thu Sep 22 17:20:28 2016
@@ -684,6 +684,10 @@ public:
   Error CreateBreakpointsFromFile(const FileSpec &file,
                                   BreakpointIDList &new_bps);
 
+  Error CreateBreakpointsFromFile(const FileSpec &file,
+                                  std::vector<std::string> &names,
+                                  BreakpointIDList &new_bps);
+
   //------------------------------------------------------------------
   /// Get \a load_addr as a callable code load address for this target
   ///

Modified: 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=282207&r1=282206&r2=282207&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/breakpoint/serialize/TestBreakpointSerialization.py Thu Sep 22 17:20:28 2016
@@ -37,6 +37,12 @@ class BreakpointSerialization(TestBase):
         self.setup_targets_and_cleanup()
         self.do_check_options()
 
+    def test_name_filters(self):
+        """Use python APIs to test that reading in by name works correctly."""
+        self.build()
+        self.setup_targets_and_cleanup()
+        self.do_check_names()
+
     def setup_targets_and_cleanup(self):
         def cleanup ():
             self.RemoveTempFile(self.bkpts_file_path)
@@ -50,7 +56,7 @@ class BreakpointSerialization(TestBase):
 
         exe = os.path.join(os.getcwd(), "a.out")
 
-        # Create a targets we are making breakpoint in and copying to:
+        # Create the targets we are making breakpoints in and copying them to:
         self.orig_target = self.dbg.CreateTarget(exe)
         self.assertTrue(self.orig_target, VALID_TARGET)
         
@@ -169,6 +175,7 @@ class BreakpointSerialization(TestBase):
         bkpt = self.orig_target.BreakpointCreateByLocation("blubby.c", 666)
         bkpt.SetEnabled(False)
         bkpt.SetOneShot(True)
+        bkpt.SetThreadID(10)
         source_bps.Append(bkpt)
         
         # Make sure we get one right:
@@ -177,10 +184,12 @@ class BreakpointSerialization(TestBase):
 
         bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)
         bkpt.SetIgnoreCount(10)
+        bkpt.SetThreadName("grubby")
         source_bps.Append(bkpt)
 
         bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list)
         bkpt.SetCondition("something != something_else")
+        bkpt.SetQueueName("grubby")
         bkpt.AddName("FirstName")
         bkpt.AddName("SecondName")
 
@@ -196,6 +205,30 @@ class BreakpointSerialization(TestBase):
 
         self.check_equivalence(source_bps)
 
+    def do_check_names(self):
+        bkpt = self.orig_target.BreakpointCreateByLocation("blubby.c", 666)
+        good_bkpt_name = "GoodBreakpoint"
+        write_bps = lldb.SBBreakpointList(self.orig_target)
+        bkpt.AddName(good_bkpt_name)
+        write_bps.Append(bkpt)
+        
+        error = lldb.SBError()
+        error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, write_bps)
+        self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
 
+        copy_bps = lldb.SBBreakpointList(self.copy_target)
+        names_list = lldb.SBStringList()
+        names_list.AppendString("NoSuchName")
 
+        error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, names_list, copy_bps)
+        self.assertTrue(error.Success(), "Failed reading breakpoints from file: %s"%(error.GetCString()))
+        self.assertTrue(copy_bps.GetSize() == 0, "Found breakpoints with a nonexistent name.")
+
+        names_list.AppendString(good_bkpt_name)
+        error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, names_list, copy_bps)
+        self.assertTrue(error.Success(), "Failed reading breakpoints from file: %s"%(error.GetCString()))
+        self.assertTrue(copy_bps.GetSize() == 1, "Found the matching breakpoint.")
+        
+        
+        
         

Modified: lldb/trunk/scripts/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBTarget.i?rev=282207&r1=282206&r2=282207&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBTarget.i (original)
+++ lldb/trunk/scripts/interface/SBTarget.i Thu Sep 22 17:20:28 2016
@@ -720,13 +720,76 @@ public:
     bool
     DeleteAllBreakpoints ();
 
+     %feature("docstring", "
+    //------------------------------------------------------------------
+    /// Read breakpoints from source_file and return the newly created 
+    /// breakpoints in bkpt_list.
+    ///
+    /// @param[in] source_file
+    ///    The file from which to read the breakpoints
+    /// 
+    /// @param[out] bkpt_list
+    ///    A list of the newly created breakpoints.
+    ///
+    /// @return
+    ///     An SBError detailing any errors in reading in the breakpoints.
+    //------------------------------------------------------------------
+    ") BreakpointsCreateFromFile;
     lldb::SBError
     BreakpointsCreateFromFile(SBFileSpec &source_file, 
                               SBBreakpointList &bkpt_list);
 
+     %feature("docstring", "
+    //------------------------------------------------------------------
+    /// Read breakpoints from source_file and return the newly created 
+    /// breakpoints in bkpt_list.
+    ///
+    /// @param[in] source_file
+    ///    The file from which to read the breakpoints
+    ///
+    /// @param[in] matching_names
+    ///    Only read in breakpoints whose names match one of the names in this
+    ///    list.
+    /// 
+    /// @param[out] bkpt_list
+    ///    A list of the newly created breakpoints.
+    ///
+    /// @return
+    ///     An SBError detailing any errors in reading in the breakpoints.
+    //------------------------------------------------------------------
+    ") BreakpointsCreateFromFile;
+    lldb::SBError BreakpointsCreateFromFile(SBFileSpec &source_file,
+                                          SBStringList &matching_names,
+                                          SBBreakpointList &new_bps);
+
+     %feature("docstring", "
+    //------------------------------------------------------------------
+    /// Write breakpoints to dest_file.
+    ///
+    /// @param[in] dest_file
+    ///    The file to which to write the breakpoints.
+    ///
+    /// @return
+    ///     An SBError detailing any errors in writing in the breakpoints.
+    //------------------------------------------------------------------
+    ") BreakpointsCreateFromFile;
     lldb::SBError
     BreakpointsWriteToFile(SBFileSpec &dest_file);
       
+     %feature("docstring", "
+    //------------------------------------------------------------------
+    /// Write breakpoints listed in bkpt_list to dest_file.
+    ///
+    /// @param[in] dest_file
+    ///    The file to which to write the breakpoints.
+    ///
+    /// @param[in] bkpt_list
+    ///    Only write breakpoints from this list.
+    ///
+    /// @return
+    ///     An SBError detailing any errors in writing in the breakpoints.
+    //------------------------------------------------------------------
+    ") BreakpointsCreateFromFile;
     lldb::SBError
     BreakpointsWriteToFile(SBFileSpec &dest_file, SBBreakpointList &bkpt_list);
 

Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=282207&r1=282206&r2=282207&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Thu Sep 22 17:20:28 2016
@@ -1128,6 +1128,13 @@ bool SBTarget::DeleteAllBreakpoints() {
 
 lldb::SBError SBTarget::BreakpointsCreateFromFile(SBFileSpec &source_file,
                                                   SBBreakpointList &new_bps) {
+  SBStringList empty_name_list;
+  return BreakpointsCreateFromFile(source_file, empty_name_list, new_bps);
+}
+
+lldb::SBError SBTarget::BreakpointsCreateFromFile(SBFileSpec &source_file,
+                                                  SBStringList &matching_names,
+                                                  SBBreakpointList &new_bps) {
   SBError sberr;
   TargetSP target_sp(GetSP());
   if (!target_sp) {
@@ -1138,7 +1145,14 @@ lldb::SBError SBTarget::BreakpointsCreat
   std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
 
   BreakpointIDList bp_ids;
-  sberr.ref() = target_sp->CreateBreakpointsFromFile(source_file.ref(), bp_ids);
+
+  std::vector<std::string> name_vector;
+  size_t num_names = matching_names.GetSize();
+  for (size_t i = 0; i < num_names; i++)
+    name_vector.push_back(matching_names.GetStringAtIndex(i));
+
+  sberr.ref() = target_sp->CreateBreakpointsFromFile(source_file.ref(),
+                                                     name_vector, bp_ids);
   if (sberr.Fail())
     return sberr;
 

Modified: lldb/trunk/source/Breakpoint/Breakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Breakpoint.cpp?rev=282207&r1=282206&r2=282207&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/Breakpoint.cpp (original)
+++ lldb/trunk/source/Breakpoint/Breakpoint.cpp Thu Sep 22 17:20:28 2016
@@ -216,6 +216,41 @@ lldb::BreakpointSP Breakpoint::CreateFro
   return result_sp;
 }
 
+bool Breakpoint::SerializedBreakpointMatchesNames(
+    StructuredData::ObjectSP &bkpt_object_sp, std::vector<std::string> &names) {
+  if (!bkpt_object_sp)
+    return false;
+
+  StructuredData::Dictionary *bkpt_dict = bkpt_object_sp->GetAsDictionary();
+  if (!bkpt_dict)
+    return false;
+
+  if (names.empty())
+    return true;
+
+  StructuredData::Array *names_array;
+
+  bool success =
+      bkpt_dict->GetValueForKeyAsArray(GetKey(OptionNames::Names), names_array);
+  // If there are no names, it can't match these names;
+  if (!success)
+    return false;
+
+  size_t num_names = names_array->GetSize();
+  std::vector<std::string>::iterator begin = names.begin();
+  std::vector<std::string>::iterator end = names.end();
+
+  for (size_t i = 0; i < num_names; i++) {
+    std::string name;
+    if (names_array->GetItemAtIndexAsString(i, name)) {
+      if (std::find(begin, end, name) != end) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
 const lldb::TargetSP Breakpoint::GetTargetSP() {
   return m_target.shared_from_this();
 }

Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=282207&r1=282206&r2=282207&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Thu Sep 22 17:20:28 2016
@@ -2077,10 +2077,11 @@ public:
 //-------------------------------------------------------------------------
 // CommandObjectBreakpointRead
 //-------------------------------------------------------------------------
-#pragma mark Modify::CommandOptions
+#pragma mark Read::CommandOptions
 static OptionDefinition g_breakpoint_read_options[] = {
     // clang-format off
-  { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename,    "The file from which to read the breakpoints." },
+  { LLDB_OPT_SET_ALL, true, "file",                   'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename,       "The file from which to read the breakpoints." },
+  {LLDB_OPT_SET_ALL, false, "breakpoint-name",        'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0,                                       eArgTypeBreakpointName, "Only read in breakpoints with this name."},
     // clang-format on
 };
 
@@ -2121,6 +2122,16 @@ public:
       case 'f':
         m_filename.assign(option_arg);
         break;
+      case 'N': {
+        Error name_error;
+        if (!BreakpointID::StringIsBreakpointName(llvm::StringRef(option_arg),
+                                                  name_error)) {
+          error.SetErrorStringWithFormat("Invalid breakpoint name: %s",
+                                         name_error.AsCString());
+        }
+        m_names.push_back(option_arg);
+        break;
+      }
       default:
         error.SetErrorStringWithFormat("unrecognized option '%c'",
                                        short_option);
@@ -2132,6 +2143,7 @@ public:
 
     void OptionParsingStarting(ExecutionContext *execution_context) override {
       m_filename.clear();
+      m_names.clear();
     }
 
     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -2141,6 +2153,7 @@ public:
     // Instance variables to hold the values for command options.
 
     std::string m_filename;
+    std::vector<std::string> m_names;
   };
 
 protected:
@@ -2152,16 +2165,38 @@ protected:
       return false;
     }
 
+    std::unique_lock<std::recursive_mutex> lock;
+    target->GetBreakpointList().GetListMutex(lock);
+
     FileSpec input_spec(m_options.m_filename, true);
     BreakpointIDList new_bps;
-    Error error = target->CreateBreakpointsFromFile(input_spec, new_bps);
+    Error error = target->CreateBreakpointsFromFile(input_spec,
+                                                    m_options.m_names, new_bps);
 
     if (!error.Success()) {
       result.AppendError(error.AsCString());
       result.SetStatus(eReturnStatusFailed);
       return false;
     }
-    // FIXME: Report the newly created breakpoints.
+
+    Stream &output_stream = result.GetOutputStream();
+
+    size_t num_breakpoints = new_bps.GetSize();
+    if (num_breakpoints == 0) {
+      result.AppendMessage("No breakpoints added.");
+    } else {
+      // No breakpoint selected; show info about all currently set breakpoints.
+      result.AppendMessage("New breakpoints:");
+      for (size_t i = 0; i < num_breakpoints; ++i) {
+        BreakpointID bp_id = new_bps.GetBreakpointIDAtIndex(i);
+        Breakpoint *bp = target->GetBreakpointList()
+                             .FindBreakpointByID(bp_id.GetBreakpointID())
+                             .get();
+        if (bp)
+          bp->GetDescription(&output_stream, lldb::eDescriptionLevelInitial,
+                             false);
+      }
+    }
     return result.Succeeded();
   }
 

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=282207&r1=282206&r2=282207&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Thu Sep 22 17:20:28 2016
@@ -869,6 +869,13 @@ Error Target::SerializeBreakpointsToFile
 
 Error Target::CreateBreakpointsFromFile(const FileSpec &file,
                                         BreakpointIDList &new_bps) {
+  std::vector<std::string> no_names;
+  return CreateBreakpointsFromFile(file, no_names, new_bps);
+}
+
+Error Target::CreateBreakpointsFromFile(const FileSpec &file,
+                                        std::vector<std::string> &names,
+                                        BreakpointIDList &new_bps) {
   std::unique_lock<std::recursive_mutex> lock;
   GetBreakpointList().GetListMutex(lock);
 
@@ -891,6 +898,8 @@ Error Target::CreateBreakpointsFromFile(
   }
 
   size_t num_bkpts = bkpt_array->GetSize();
+  size_t num_names = names.size();
+
   for (size_t i = 0; i < num_bkpts; i++) {
     StructuredData::ObjectSP bkpt_object_sp = bkpt_array->GetItemAtIndex(i);
     // Peel off the breakpoint key, and feed the rest to the Breakpoint:
@@ -903,6 +912,10 @@ Error Target::CreateBreakpointsFromFile(
     }
     StructuredData::ObjectSP bkpt_data_sp =
         bkpt_dict->GetValueForKey(Breakpoint::GetSerializationKey());
+    if (num_names &&
+        !Breakpoint::SerializedBreakpointMatchesNames(bkpt_data_sp, names))
+      continue;
+
     BreakpointSP bkpt_sp =
         Breakpoint::CreateFromStructuredData(*this, bkpt_data_sp, error);
     if (!error.Success()) {




More information about the lldb-commits mailing list