[Lldb-commits] [lldb] r267834 - Add the ability to limit "source regexp" breakpoints to a particular function

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Wed Apr 27 18:40:58 PDT 2016


Author: jingham
Date: Wed Apr 27 20:40:57 2016
New Revision: 267834

URL: http://llvm.org/viewvc/llvm-project?rev=267834&view=rev
Log:
Add the ability to limit "source regexp" breakpoints to a particular function
within a source file.

This isn't done, I need to make the name match smarter (right now it requires an
exact match which is annoying for methods of a class in a namespace.

Also, though we use it in tests all over the place, it doesn't look like we have
a test for Source Regexp breakpoints by themselves, I'll add that in a follow-on patch.

Modified:
    lldb/trunk/include/lldb/API/SBStringList.h
    lldb/trunk/include/lldb/API/SBTarget.h
    lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/scripts/interface/SBTarget.i
    lldb/trunk/source/API/SBStringList.cpp
    lldb/trunk/source/API/SBTarget.cpp
    lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp
    lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
    lldb/trunk/source/Target/Target.cpp

Modified: lldb/trunk/include/lldb/API/SBStringList.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBStringList.h?rev=267834&r1=267833&r2=267834&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBStringList.h (original)
+++ lldb/trunk/include/lldb/API/SBStringList.h Wed Apr 27 20:40:57 2016
@@ -45,6 +45,9 @@ public:
     const char *
     GetStringAtIndex (size_t idx);
 
+    const char *
+    GetStringAtIndex (size_t idx) const;
+
     void
     Clear ();
 

Modified: lldb/trunk/include/lldb/API/SBTarget.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=267834&r1=267833&r2=267834&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBTarget.h (original)
+++ lldb/trunk/include/lldb/API/SBTarget.h Wed Apr 27 20:40:57 2016
@@ -694,6 +694,12 @@ public:
                                    const SBFileSpecList &source_file);
     
     lldb::SBBreakpoint
+    BreakpointCreateBySourceRegex (const char *source_regex,
+                                   const SBFileSpecList &module_list,
+                                   const SBFileSpecList &source_file,
+                                   const SBStringList  &func_names);
+    
+    lldb::SBBreakpoint
     BreakpointCreateForException  (lldb::LanguageType language,
                                    bool catch_bp,
                                    bool throw_bp);

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h?rev=267834&r1=267833&r2=267834&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h Wed Apr 27 20:40:57 2016
@@ -12,9 +12,11 @@
 
 // C Includes
 // C++ Includes
+#include <set>
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Breakpoint/BreakpointResolver.h"
+#include "lldb/Core/ConstString.h"
 
 namespace lldb_private {
 
@@ -30,6 +32,7 @@ class BreakpointResolverFileRegex :
 public:
     BreakpointResolverFileRegex (Breakpoint *bkpt,
                                  RegularExpression &regex,
+                                 const std::unordered_set<std::string> &func_name_set,
                                  bool exact_match);
 
     ~BreakpointResolverFileRegex() override;
@@ -48,6 +51,9 @@ public:
 
     void
     Dump (Stream *s) const override;
+    
+    void
+    AddFunctionName(const char *func_name);
 
     /// Methods for support type inquiry through isa, cast, and dyn_cast:
     static inline bool classof(const BreakpointResolverFileRegex *) { return true; }
@@ -61,7 +67,8 @@ public:
 protected:
     friend class Breakpoint;
     RegularExpression m_regex; // This is the line expression that we are looking for.
-    bool m_exact_match;
+    bool m_exact_match;        // If true, then if the source we match is in a comment, we won't set a location there.
+    std::unordered_set<std::string> m_function_names; // Limit the search to functions in the comp_unit passed in.
 
 private:
     DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileRegex);

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=267834&r1=267833&r2=267834&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Wed Apr 27 20:40:57 2016
@@ -797,9 +797,11 @@ public:
                       LazyBool move_to_nearest_code);
 
     // Use this to create breakpoint that matches regex against the source lines in files given in source_file_list:
+    // If function_names is non-empty, also filter by function after the matches are made.
     lldb::BreakpointSP
     CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
                                  const FileSpecList *source_file_list,
+                                 const std::unordered_set<std::string> &function_names,
                                  RegularExpression &source_regex,
                                  bool internal,
                                  bool request_hardware,

Modified: lldb/trunk/scripts/interface/SBTarget.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBTarget.i?rev=267834&r1=267833&r2=267834&view=diff
==============================================================================
--- lldb/trunk/scripts/interface/SBTarget.i (original)
+++ lldb/trunk/scripts/interface/SBTarget.i Wed Apr 27 20:40:57 2016
@@ -676,6 +676,12 @@ public:
     BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpecList &module_list, const lldb::SBFileSpecList &file_list);
 
     lldb::SBBreakpoint
+    BreakpointCreateBySourceRegex (const char *source_regex,
+                                   const SBFileSpecList &module_list,
+                                   const SBFileSpecList &source_file,
+                                   const SBStringList  &func_names);
+
+    lldb::SBBreakpoint
     BreakpointCreateForException  (lldb::LanguageType language,
                                    bool catch_bp,
                                    bool throw_bp);

Modified: lldb/trunk/source/API/SBStringList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBStringList.cpp?rev=267834&r1=267833&r2=267834&view=diff
==============================================================================
--- lldb/trunk/source/API/SBStringList.cpp (original)
+++ lldb/trunk/source/API/SBStringList.cpp Wed Apr 27 20:40:57 2016
@@ -126,6 +126,16 @@ SBStringList::GetStringAtIndex (size_t i
     return NULL;
 }
 
+const char *
+SBStringList::GetStringAtIndex (size_t idx) const
+{
+    if (IsValid())
+    {
+        return m_opaque_ap->GetStringAtIndex (idx);
+    }
+    return NULL;
+}
+
 void
 SBStringList::Clear ()
 {

Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=267834&r1=267833&r2=267834&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Wed Apr 27 20:40:57 2016
@@ -22,6 +22,7 @@
 #include "lldb/API/SBSourceManager.h"
 #include "lldb/API/SBProcess.h"
 #include "lldb/API/SBStream.h"
+#include "lldb/API/SBStringList.h"
 #include "lldb/API/SBSymbolContextList.h"
 #include "lldb/Breakpoint/BreakpointID.h"
 #include "lldb/Breakpoint/BreakpointIDList.h"
@@ -1124,42 +1125,21 @@ SBTarget::BreakpointCreateBySourceRegex
                                          const lldb::SBFileSpec &source_file,
                                          const char *module_name)
 {
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-
-    SBBreakpoint sb_bp;
-    TargetSP target_sp(GetSP());
-    if (target_sp && source_regex && source_regex[0])
-    {
-        Mutex::Locker api_locker (target_sp->GetAPIMutex());
-        RegularExpression regexp(source_regex);
-        FileSpecList source_file_spec_list;
-        const bool hardware = false;
-        const LazyBool move_to_nearest_code = eLazyBoolCalculate;
-        source_file_spec_list.Append (source_file.ref());
+        SBFileSpecList module_spec_list;
 
         if (module_name && module_name[0])
         {
-            FileSpecList module_spec_list;
             module_spec_list.Append (FileSpec (module_name, false));
-
-            *sb_bp = target_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false, hardware, move_to_nearest_code);
         }
-        else
+        
+        SBFileSpecList source_file_list;
+        if (source_file.IsValid())
         {
-            *sb_bp = target_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false, hardware, move_to_nearest_code);
+            source_file_list.Append(source_file);
         }
-    }
-
-    if (log)
-    {
-        char path[PATH_MAX];
-        source_file->GetPath (path, sizeof(path));
-        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\", file=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)",
-                     static_cast<void*>(target_sp.get()), source_regex, path,
-                     module_name, static_cast<void*>(sb_bp.get()));
-    }
+    
+        return BreakpointCreateBySourceRegex (source_regex, module_spec_list, source_file_list);
 
-    return sb_bp;
 }
 
 lldb::SBBreakpoint
@@ -1167,6 +1147,15 @@ SBTarget::BreakpointCreateBySourceRegex
                                                  const SBFileSpecList &module_list,
                                                  const lldb::SBFileSpecList &source_file_list)
 {
+    return BreakpointCreateBySourceRegex(source_regex, module_list, source_file_list, SBStringList());
+}
+
+lldb::SBBreakpoint
+SBTarget::BreakpointCreateBySourceRegex (const char *source_regex,
+                                                 const SBFileSpecList &module_list,
+                                                 const lldb::SBFileSpecList &source_file_list,
+                                                 const SBStringList &func_names)
+{
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 
     SBBreakpoint sb_bp;
@@ -1177,7 +1166,19 @@ SBTarget::BreakpointCreateBySourceRegex
         const bool hardware = false;
         const LazyBool move_to_nearest_code = eLazyBoolCalculate;
         RegularExpression regexp(source_regex);
-        *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false, hardware, move_to_nearest_code);
+        std::unordered_set<std::string> func_names_set;
+        for (size_t i = 0; i < func_names.GetSize(); i++)
+        {
+            func_names_set.insert(func_names.GetStringAtIndex(i));
+        }
+        
+        *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(),
+                                                         source_file_list.get(),
+                                                         func_names_set,
+                                                         regexp,
+                                                         false,
+                                                         hardware,
+                                                         move_to_nearest_code);
     }
 
     if (log)

Modified: lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp?rev=267834&r1=267833&r2=267834&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp Wed Apr 27 20:40:57 2016
@@ -30,11 +30,13 @@ BreakpointResolverFileRegex::BreakpointR
 (
     Breakpoint *bkpt,
     RegularExpression &regex,
+    const std::unordered_set<std::string> &func_names,
     bool exact_match
 ) :
     BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver),
     m_regex (regex),
-    m_exact_match (exact_match)
+    m_exact_match (exact_match),
+    m_function_names(func_names)
 {
 }
 
@@ -68,6 +70,32 @@ BreakpointResolverFileRegex::SearchCallb
         const bool search_inlines = false;
         
         cu->ResolveSymbolContext (cu_file_spec, line_matches[i], search_inlines, m_exact_match, eSymbolContextEverything, sc_list);
+        // Find all the function names:
+        if (!m_function_names.empty())
+        {
+            std::vector<size_t> sc_to_remove;
+            for (size_t i = 0; i < sc_list.GetSize(); i++)
+            {
+                SymbolContext sc_ctx;
+                sc_list.GetContextAtIndex(i, sc_ctx);
+                std::string name(sc_ctx.GetFunctionName(Mangled::NamePreference::ePreferDemangledWithoutArguments).AsCString());
+                if (!m_function_names.count(name))
+                {
+                    sc_to_remove.push_back(i);
+                }
+            }
+            
+            if (!sc_to_remove.empty())
+            {
+                std::vector<size_t>::reverse_iterator iter;
+                std::vector<size_t>::reverse_iterator rend = sc_to_remove.rend();
+                for (iter = sc_to_remove.rbegin(); iter != rend; iter++)
+                {
+                    sc_list.RemoveContextAtIndex(*iter);
+                }
+            }
+        }
+        
         const bool skip_prologue = true;
         
         BreakpointResolver::SetSCMatchesByLine (filter, sc_list, skip_prologue, m_regex.GetText());
@@ -98,7 +126,13 @@ BreakpointResolverFileRegex::Dump (Strea
 lldb::BreakpointResolverSP
 BreakpointResolverFileRegex::CopyForBreakpoint (Breakpoint &breakpoint)
 {
-    lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(&breakpoint, m_regex, m_exact_match));
+    lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(&breakpoint, m_regex, m_function_names, m_exact_match));
     return ret_sp;
 }
 
+void
+BreakpointResolverFileRegex::AddFunctionName(const char *func_name)
+{
+    m_function_names.insert(func_name);
+}
+

Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=267834&r1=267833&r2=267834&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Wed Apr 27 20:40:57 2016
@@ -342,6 +342,10 @@ public:
                        error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
                     break;
 
+                case 'X':
+                    m_source_regex_func_names.insert(option_arg);
+                    break;
+                    
                 default:
                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
                     break;
@@ -381,6 +385,7 @@ public:
             m_all_files = false;
             m_exception_extra_args.Clear();
             m_move_to_nearest_code = eLazyBoolCalculate;
+            m_source_regex_func_names.clear();
         }
     
         const OptionDefinition*
@@ -423,6 +428,7 @@ public:
         bool m_all_files;
         Args m_exception_extra_args;
         LazyBool m_move_to_nearest_code;
+        std::unordered_set<std::string> m_source_regex_func_names;
     };
 
 protected:
@@ -608,6 +614,7 @@ protected:
                     }
                     bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules),
                                                               &(m_options.m_filenames),
+                                                              m_options.m_source_regex_func_names,
                                                               regexp,
                                                               internal,
                                                               m_options.m_hardware,
@@ -805,6 +812,9 @@ CommandObjectBreakpointSet::CommandOptio
     { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
         "Set the breakpoint by function name.  Can be repeated multiple times to make one breakpoint for multiple names" },
 
+    { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
+        "When used with '-p' limits the source regex to source contained in the named functions.  Can be repeated multiple times." },
+
     { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName,
         "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and "
         "for Objective C this means a full function prototype with class and selector.  "
@@ -855,7 +865,7 @@ CommandObjectBreakpointSet::CommandOptio
         "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."},
 
     { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName,
-        "Adds this to the list of names for this breakopint."},
+        "Adds this to the list of names for this breakpoint."},
 
     { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress,
         "Add the specified offset to whatever address(es) the breakpoint resolves to.  "

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=267834&r1=267833&r2=267834&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Wed Apr 27 20:40:57 2016
@@ -326,6 +326,7 @@ Target::GetBreakpointByID (break_id_t br
 BreakpointSP
 Target::CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
                                      const FileSpecList *source_file_spec_list,
+                                     const std::unordered_set<std::string> &function_names,
                                      RegularExpression &source_regex,
                                      bool internal,
                                      bool hardware,
@@ -334,7 +335,11 @@ Target::CreateSourceRegexBreakpoint (con
     SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, source_file_spec_list));
     if (move_to_nearest_code == eLazyBoolCalculate)
         move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo;
-    BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(nullptr, source_regex, !static_cast<bool>(move_to_nearest_code)));
+    BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(nullptr,
+                                                                     source_regex,
+                                                                     function_names,
+                                                                     !static_cast<bool>(move_to_nearest_code)));
+    
     return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true);
 }
 




More information about the lldb-commits mailing list