[Bro-Dev] Help Troubleshooting a Perftools Memleak

Siwek, Jon jsiwek at illinois.edu
Thu Oct 30 09:09:25 PDT 2014


> On Oct 29, 2014, at 10:35 PM, Robin Sommer <robin at icir.org> wrote:
> 
> Unfortunately the obvious fix doesn't work. I'm pasting it in below,
> but that change lets Bro crash because it now depends on the order in
> which global constructors run. If anybody has a better idea, let me
> know.

Extending your idea a bit and probably hacking it into a place originally intended for something else.  It may be a breaking change for other applications besides Bro, depending on how they define their RE_Matcher::Compile(), but not hard to fix.

diff --git a/lib/binpac_regex.h b/lib/binpac_regex.h
index b41e6db..ce5e7e3 100644
--- a/lib/binpac_regex.h
+++ b/lib/binpac_regex.h
@@ -14,7 +14,8 @@ public:
        RegExMatcher(const char *pattern)
                : pattern_(pattern)
                {
-               re_matcher_ = 0;
+               re_matcher_ = new RE_Matcher(pattern_.c_str());
+               re_matcher_->Compile(1);
                }
 
        ~RegExMatcher()
@@ -25,11 +26,6 @@ public:
        // Returns the length of longest match, or -1 on mismatch.
        int MatchPrefix(const_byteptr data, int len)
                {
-               if ( ! re_matcher_ )
-                       {
-                       re_matcher_ = new RE_Matcher(pattern_.c_str());
-                       re_matcher_->Compile();
-                       }
                return re_matcher_->MatchPrefix(data, len);
                }
 
diff --git a/src/RE.cc b/src/RE.cc
index 4855b0e..8aecbed 100644
--- a/src/RE.cc
+++ b/src/RE.cc
@@ -426,8 +426,27 @@ void RE_Matcher::AddPat(const char* new_pat)
        re_exact->AddPat(new_pat);
        }
 
+std::vector<RE_Matcher*> uncompiled_re_matchers;
+
+int init_uncompiled_re_matchers()
+       {
+       int rval = 1;
+
+       for ( size_t i = 0; i < uncompiled_re_matchers.size(); ++i )
+               if ( ! uncompiled_re_matchers[i]->Compile() )
+                       rval = 0;
+
+       return rval;
+       }
+
 int RE_Matcher::Compile(int lazy)
        {
+       if ( lazy )
+               {
+               uncompiled_re_matchers.push_back(this);
+               return 1;
+               }
+
        return re_anywhere->Compile(lazy) && re_exact->Compile(lazy);
        }
 
diff --git a/src/RE.h b/src/RE.h
index 7437dbb..dc9f881 100644
--- a/src/RE.h
+++ b/src/RE.h
@@ -11,6 +11,7 @@
 
 #include <set>
 #include <map>
+#include <vector>
 
 #include <ctype.h>
 typedef int (*cce_func)(int);
@@ -224,6 +225,10 @@ protected:
        Specific_RE_Matcher* re_exact;
 };
 
+extern std::vector<RE_Matcher*> uncompiled_re_matchers;
+
+int init_uncompiled_re_matchers();
+
 declare(PList, RE_Matcher);
 typedef PList(RE_Matcher) re_matcher_list;
 
diff --git a/src/main.cc b/src/main.cc
index 63949c5..a2be76d 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -775,6 +775,9 @@ int main(int argc, char** argv)
        // DEBUG_MSG("HMAC key: %s\n", md5_digest_print(shared_hmac_md5_key));
        init_hash_function();
 
+       if ( ! init_uncompiled_re_matchers() )
+               reporter->Error("Failed to lazy-compile regex matchers.");
+
        ERR_load_crypto_strings();
        OPENSSL_add_all_algorithms_conf();
        SSL_library_init();


More information about the bro-dev mailing list