[Lldb-commits] [lldb] r178702 - <rdar://problem/13384801>

Greg Clayton gclayton at apple.com
Wed Apr 3 14:37:16 PDT 2013


Author: gclayton
Date: Wed Apr  3 16:37:16 2013
New Revision: 178702

URL: http://llvm.org/viewvc/llvm-project?rev=178702&view=rev
Log:
<rdar://problem/13384801>

Make lldb_private::RegularExpression thread safe everywhere. This was done by removing the m_matches array from the lldb_private::RegularExpression class and putting it into the new lldb_private::RegularExpression::Match class. When executing a regular expression you now have the option to create a lldb_private::RegularExpression::Match object and pass a pointer in if you want to get parenthesized matching. If you don't want any matching, you pass in NULL. The lldb_private::RegularExpression::Match object is initialized with the number of matches you desire. Any matching strings are now extracted from the lldb_private::RegularExpression::Match objects. This makes the regular expression objects thread safe and as a result many more regex objects were turned into static objects that end up using a local lldb_private::RegularExpression::Match object when executing.


Modified:
    lldb/trunk/include/lldb/Core/RegularExpression.h
    lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
    lldb/trunk/source/Core/Disassembler.cpp
    lldb/trunk/source/Core/RegularExpression.cpp
    lldb/trunk/source/Interpreter/Args.cpp
    lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
    lldb/trunk/source/Symbol/ObjectFile.cpp
    lldb/trunk/source/Symbol/Variable.cpp
    lldb/trunk/source/Target/ThreadPlanStepInRange.cpp

Modified: lldb/trunk/include/lldb/Core/RegularExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RegularExpression.h?rev=178702&r1=178701&r2=178702&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/RegularExpression.h (original)
+++ lldb/trunk/include/lldb/Core/RegularExpression.h Wed Apr  3 16:37:16 2013
@@ -35,6 +35,52 @@ namespace lldb_private {
 class RegularExpression
 {
 public:
+    class Match
+    {
+    public:
+        Match (uint32_t max_matches) :
+            m_matches ()
+        {
+            if (max_matches > 0)
+                m_matches.resize(max_matches + 1);
+        }
+
+        void
+        Clear()
+        {
+            const size_t num_matches = m_matches.size();
+            regmatch_t invalid_match = { -1, -1 };
+            for (size_t i=0; i<num_matches; ++i)
+                m_matches[i] = invalid_match;
+        }
+
+        size_t
+        GetSize () const
+        {
+            return m_matches.size();
+        }
+        
+        regmatch_t *
+        GetData ()
+        {
+            if (m_matches.empty())
+                return NULL;
+            return m_matches.data();
+        }
+        
+        bool
+        GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const;
+        
+        bool
+        GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const;
+        
+        bool
+        GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const;
+
+    protected:
+        
+        std::vector<regmatch_t> m_matches; ///< Where parenthesized subexpressions results are stored
+    };
     //------------------------------------------------------------------
     /// Default constructor.
     ///
@@ -115,8 +161,10 @@ public:
     /// @param[in] string
     ///     The string to match against the compile regular expression.
     ///
-    /// @param[in] match_count
-    ///     The number of regmatch_t objects in \a match_ptr
+    /// @param[in] match
+    ///     A pointer to a RegularExpression::Match structure that was
+    ///     properly initialized with the desired number of maximum
+    ///     matches, or NULL if no parenthesized matching is needed.
     ///
     /// @param[in] execute_flags
     ///     Flags to pass to the \c regexec() function.
@@ -126,24 +174,11 @@ public:
     ///     expression, \b false otherwise.
     //------------------------------------------------------------------
     bool
-    Execute (const char* string, size_t match_count = 0, int execute_flags = 0) const;
+    Execute (const char* string, Match *match = NULL, int execute_flags = 0) const;
 
-    bool
-    ExecuteThreadSafe (const char* s,
-                       llvm::StringRef *matches,
-                       size_t num_matches,
-                       int execute_flags = 0) const;
     size_t
     GetErrorAsCString (char *err_str, size_t err_str_max_len) const;
 
-    bool
-    GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const;
-
-    bool
-    GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const;
-    
-    bool
-    GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const;
     //------------------------------------------------------------------
     /// Free the compiled regular expression.
     ///
@@ -210,8 +245,6 @@ private:
     int m_comp_err;     ///< Error code for the regular expression compilation
     regex_t m_preg;     ///< The compiled regular expression
     int     m_compile_flags; ///< Stores the flags from the last compile.
-    mutable std::vector<regmatch_t> m_matches; ///< Where parenthesized subexpressions results are stored
-    
 };
 
 } // namespace lldb_private

Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=178702&r1=178701&r2=178702&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Wed Apr  3 16:37:16 2013
@@ -53,11 +53,12 @@ DecodeHostAndPort (const char *host_and_
                    int32_t& port,
                    Error *error_ptr)
 {
-    RegularExpression regex ("([^:]+):([0-9]+)");
-    if (regex.Execute (host_and_port, 2))
+    static RegularExpression g_regex ("([^:]+):([0-9]+)");
+    RegularExpression::Match regex_match(2);
+    if (g_regex.Execute (host_and_port, &regex_match))
     {
-        if (regex.GetMatchAtIndex (host_and_port, 1, host_str) &&
-            regex.GetMatchAtIndex (host_and_port, 2, port_str))
+        if (regex_match.GetMatchAtIndex (host_and_port, 1, host_str) &&
+            regex_match.GetMatchAtIndex (host_and_port, 2, port_str))
         {
             port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
             if (port != INT32_MIN)

Modified: lldb/trunk/source/Core/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=178702&r1=178701&r2=178702&view=diff
==============================================================================
--- lldb/trunk/source/Core/Disassembler.cpp (original)
+++ lldb/trunk/source/Core/Disassembler.cpp Wed Apr  3 16:37:16 2013
@@ -684,10 +684,11 @@ Instruction::ReadArray (FILE *in_file, S
         if (line.size() > 0)
         {
             std::string value;
-            RegularExpression reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
-            bool reg_exp_success = reg_exp.Execute (line.c_str(), 1);
+            static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
+            RegularExpression::Match regex_match(1);
+            bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
             if (reg_exp_success)
-                reg_exp.GetMatchAtIndex (line.c_str(), 1, value);
+                regex_match.GetMatchAtIndex (line.c_str(), 1, value);
             else
                 value = line;
                 
@@ -752,14 +753,16 @@ Instruction::ReadDictionary (FILE *in_fi
         // Try to find a key-value pair in the current line and add it to the dictionary.
         if (line.size() > 0)
         {
-            RegularExpression reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
-            bool reg_exp_success = reg_exp.Execute (line.c_str(), 2);
+            static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
+            RegularExpression::Match regex_match(2);
+
+            bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
             std::string key;
             std::string value;
             if (reg_exp_success)
             {
-                reg_exp.GetMatchAtIndex (line.c_str(), 1, key);
-                reg_exp.GetMatchAtIndex (line.c_str(), 2, value);
+                regex_match.GetMatchAtIndex (line.c_str(), 1, key);
+                regex_match.GetMatchAtIndex (line.c_str(), 2, value);
             }
             else 
             {

Modified: lldb/trunk/source/Core/RegularExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/RegularExpression.cpp?rev=178702&r1=178701&r2=178702&view=diff
==============================================================================
--- lldb/trunk/source/Core/RegularExpression.cpp (original)
+++ lldb/trunk/source/Core/RegularExpression.cpp Wed Apr  3 16:37:16 2013
@@ -20,8 +20,7 @@ RegularExpression::RegularExpression() :
     m_re(),
     m_comp_err (1),
     m_preg(),
-    m_compile_flags(REG_EXTENDED),
-    m_matches()
+    m_compile_flags(REG_EXTENDED)
 {
     memset(&m_preg,0,sizeof(m_preg));
 }
@@ -125,59 +124,45 @@ RegularExpression::Compile(const char* r
 // matches "match_count" should indicate the number of regmatch_t
 // values that are present in "match_ptr". The regular expression
 // will be executed using the "execute_flags".
-//----------------------------------------------------------------------
-bool
-RegularExpression::Execute(const char* s, size_t num_matches, int execute_flags) const
-{
-    int match_result = 1;
-    if (m_comp_err == 0)
-    {
-        if (num_matches > 0)
-            m_matches.resize(num_matches + 1);
-        else
-            m_matches.clear();
-
-        match_result = ::regexec (&m_preg,
-                                  s,
-                                  m_matches.size(),
-                                  &m_matches[0],
-                                  execute_flags);
-    }
-    return match_result == 0;
-}
-
+//---------------------------------------------------------------------
 bool
-RegularExpression::ExecuteThreadSafe (const char* s, llvm::StringRef *match_srefs, size_t count, int execute_flags) const
+RegularExpression::Execute(const char* s, Match *match, int execute_flags) const
 {
-    bool success = false;
+    int err = 1;
     if (m_comp_err == 0)
     {
-        std::vector<regmatch_t> matches;
-        
-        if (match_srefs && count > 0)
-            matches.resize(count + 1);
-        
-        success = ::regexec (&m_preg,
+        if (match)
+        {
+            err = ::regexec (&m_preg,
                              s,
-                             matches.size(),
-                             matches.data(),
-                             execute_flags) == 0;
-        for (size_t i=0; i<count; ++i)
+                             match->GetSize(),
+                             match->GetData(),
+                             execute_flags);
+        }
+        else
         {
-            size_t match_idx = i+1;
-            if (success && matches[match_idx].rm_so < matches[match_idx].rm_eo)
-                match_srefs[i] = llvm::StringRef(s + matches[match_idx].rm_so, matches[match_idx].rm_eo - matches[match_idx].rm_so);
-            else
-                match_srefs[i] = llvm::StringRef();
+            err = ::regexec (&m_preg,
+                             s,
+                             0,
+                             NULL,
+                             execute_flags);
         }
     }
-    return success;
+    
+    if (err != 0)
+    {
+        // The regular expression didn't compile, so clear the matches
+        if (match)
+            match->Clear();
+        return false;
+    }
+    return true;
 }
 
 bool
-RegularExpression::GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const
+RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const
 {
-    if (idx <= m_preg.re_nsub && idx < m_matches.size())
+    if (idx < m_matches.size())
     {
         if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
         {
@@ -196,9 +181,9 @@ RegularExpression::GetMatchAtIndex (cons
 }
 
 bool
-RegularExpression::GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const
+RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const
 {
-    if (idx <= m_preg.re_nsub && idx < m_matches.size())
+    if (idx < m_matches.size())
     {
         if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
         {
@@ -216,9 +201,9 @@ RegularExpression::GetMatchAtIndex (cons
 }
 
 bool
-RegularExpression::GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const
+RegularExpression::Match::GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const
 {
-    if (idx1 <= m_preg.re_nsub && idx1 < m_matches.size() && idx2 <= m_preg.re_nsub && idx2 < m_matches.size())
+    if (idx1 < m_matches.size() && idx2 < m_matches.size())
     {
         if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo)
         {

Modified: lldb/trunk/source/Interpreter/Args.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/Args.cpp?rev=178702&r1=178701&r2=178702&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/Args.cpp (original)
+++ lldb/trunk/source/Interpreter/Args.cpp Wed Apr  3 16:37:16 2013
@@ -854,20 +854,21 @@ Args::StringToAddress (const ExecutionCo
                     // Since the compiler can't handle things like "main + 12" we should
                     // try to do this for now. The compliler doesn't like adding offsets
                     // to function pointer types.
-                    RegularExpression symbol_plus_offset_regex("^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
-                    if (symbol_plus_offset_regex.Execute(s, 3))
+                    static RegularExpression g_symbol_plus_offset_regex("^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+                    RegularExpression::Match regex_match(3);
+                    if (g_symbol_plus_offset_regex.Execute(s, &regex_match))
                     {
                         uint64_t offset = 0;
                         bool add = true;
                         std::string name;
                         std::string str;
-                        if (symbol_plus_offset_regex.GetMatchAtIndex(s, 1, name))
+                        if (regex_match.GetMatchAtIndex(s, 1, name))
                         {
-                            if (symbol_plus_offset_regex.GetMatchAtIndex(s, 2, str))
+                            if (regex_match.GetMatchAtIndex(s, 2, str))
                             {
                                 add = str[0] == '+';
                                 
-                                if (symbol_plus_offset_regex.GetMatchAtIndex(s, 3, str))
+                                if (regex_match.GetMatchAtIndex(s, 3, str))
                                 {
                                     offset = Args::StringToUInt64(str.c_str(), 0, 0, &success);
                                     

Modified: lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp?rev=178702&r1=178701&r2=178702&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObjectRegexCommand.cpp Wed Apr  3 16:37:16 2013
@@ -60,7 +60,9 @@ CommandObjectRegexCommand::DoExecute
         EntryCollection::const_iterator pos, end = m_entries.end();
         for (pos = m_entries.begin(); pos != end; ++pos)
         {
-            if (pos->regex.Execute (command, m_max_matches))
+            RegularExpression::Match regex_match(m_max_matches);
+
+            if (pos->regex.Execute (command, &regex_match))
             {
                 std::string new_command(pos->command);
                 std::string match_str;
@@ -68,7 +70,7 @@ CommandObjectRegexCommand::DoExecute
                 size_t idx, percent_var_idx;
                 for (uint32_t match_idx=1; match_idx <= m_max_matches; ++match_idx)
                 {
-                    if (pos->regex.GetMatchAtIndex (command, match_idx, match_str))
+                    if (regex_match.GetMatchAtIndex (command, match_idx, match_str))
                     {
                         const int percent_var_len = ::snprintf (percent_var, sizeof(percent_var), "%%%u", match_idx);
                         for (idx = 0; (percent_var_idx = new_command.find(percent_var, idx)) != std::string::npos; )

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp?rev=178702&r1=178701&r2=178702&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Wed Apr  3 16:37:16 2013
@@ -958,15 +958,16 @@ DWARFCompileUnit::ParseProducerInfo ()
             }
             else if (strstr(producer_cstr, "clang"))
             {
-                RegularExpression clang_regex("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)");
-                if (clang_regex.Execute (producer_cstr, 3))
+                static RegularExpression g_clang_version_regex("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)");
+                RegularExpression::Match regex_match(3);
+                if (g_clang_version_regex.Execute (producer_cstr, &regex_match))
                 {
                     std::string str;
-                    if (clang_regex.GetMatchAtIndex (producer_cstr, 1, str))
+                    if (regex_match.GetMatchAtIndex (producer_cstr, 1, str))
                         m_producer_version_major = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
-                    if (clang_regex.GetMatchAtIndex (producer_cstr, 2, str))
+                    if (regex_match.GetMatchAtIndex (producer_cstr, 2, str))
                         m_producer_version_minor = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
-                    if (clang_regex.GetMatchAtIndex (producer_cstr, 3, str))
+                    if (regex_match.GetMatchAtIndex (producer_cstr, 3, str))
                         m_producer_version_update = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
                 }
                 m_producer = eProducerClang;

Modified: lldb/trunk/source/Symbol/ObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ObjectFile.cpp?rev=178702&r1=178701&r2=178702&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ObjectFile.cpp (original)
+++ lldb/trunk/source/Symbol/ObjectFile.cpp Wed Apr  3 16:37:16 2013
@@ -517,12 +517,13 @@ bool
 ObjectFile::SplitArchivePathWithObject (const char *path_with_object, FileSpec &archive_file, ConstString &archive_object, bool must_exist)
 {
     RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
-    if (g_object_regex.Execute (path_with_object, 2))
+    RegularExpression::Match regex_match(2);
+    if (g_object_regex.Execute (path_with_object, &regex_match))
     {
         std::string path;
         std::string obj;
-        if (g_object_regex.GetMatchAtIndex (path_with_object, 1, path) &&
-            g_object_regex.GetMatchAtIndex (path_with_object, 2, obj))
+        if (regex_match.GetMatchAtIndex (path_with_object, 1, path) &&
+            regex_match.GetMatchAtIndex (path_with_object, 2, obj))
         {
             archive_file.SetFile (path.c_str(), false);
             archive_object.SetCString(obj.c_str());

Modified: lldb/trunk/source/Symbol/Variable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Variable.cpp?rev=178702&r1=178701&r2=178702&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Variable.cpp (original)
+++ lldb/trunk/source/Symbol/Variable.cpp Wed Apr  3 16:37:16 2013
@@ -396,11 +396,12 @@ Variable::GetValuesForVariableExpression
             
         default:
             {
-                RegularExpression regex ("^([A-Za-z_:][A-Za-z_0-9:]*)(.*)");
-                if (regex.Execute(variable_expr_path, 1))
+                static RegularExpression g_regex ("^([A-Za-z_:][A-Za-z_0-9:]*)(.*)");
+                RegularExpression::Match regex_match(1);
+                if (g_regex.Execute(variable_expr_path, &regex_match))
                 {
                     std::string variable_name;
-                    if (regex.GetMatchAtIndex(variable_expr_path, 1, variable_name))
+                    if (regex_match.GetMatchAtIndex(variable_expr_path, 1, variable_name))
                     {
                         variable_list.Clear();
                         if (callback (baton, variable_name.c_str(), variable_list))

Modified: lldb/trunk/source/Target/ThreadPlanStepInRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanStepInRange.cpp?rev=178702&r1=178701&r2=178702&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanStepInRange.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanStepInRange.cpp Wed Apr  3 16:37:16 2013
@@ -279,13 +279,16 @@ ThreadPlanStepInRange::FrameMatchesAvoid
                 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
                 if (log)
                     num_matches = 1;
-                bool return_value = avoid_regexp_to_use->Execute(frame_function_name, num_matches);
+                
+                RegularExpression::Match regex_match(num_matches);
+
+                bool return_value = avoid_regexp_to_use->Execute(frame_function_name, &regex_match);
                 if (return_value)
                 {
                     if (log)
                     {
                         std::string match;
-                        avoid_regexp_to_use->GetMatchAtIndex(frame_function_name,0, match);
+                        regex_match.GetMatchAtIndex(frame_function_name,0, match);
                         log->Printf ("Stepping out of function \"%s\" because it matches the avoid regexp \"%s\" - match substring: \"%s\".",
                                      frame_function_name,
                                      avoid_regexp_to_use->GetText(),





More information about the lldb-commits mailing list