[lldb] Stop searching for a symbol in a pdb by regex
authorAaron Smith <aaron.smith@microsoft.com>
Fri, 22 Dec 2017 05:26:50 +0000 (05:26 +0000)
committerAaron Smith <aaron.smith@microsoft.com>
Fri, 22 Dec 2017 05:26:50 +0000 (05:26 +0000)
Summary:
It was possible when searching for a symbol by regex in a pdb that an invalid regex would cause an exception on Windows. This updates the code to avoid throwing an exception.

When fixing the exception it was decided there is no reason to search for a symbol in a pdb by regex. To support this, SymbolFilePDB::FindTypes() now only searches for types by name and no longer calls FindTypesByRegEx().

Reviewers: zturner, lldb-commits

Reviewed By: zturner

Subscribers: clayborg

Differential Revision: https://reviews.llvm.org/D41086

llvm-svn: 321344

lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp

index 9b98ebe..7802d6f 100644 (file)
@@ -124,6 +124,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
   } else if (auto type_def = llvm::dyn_cast<PDBSymbolTypeTypedef>(&type)) {
     lldb_private::Type *target_type =
         m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId());
+    if (!target_type)
+      return nullptr;
     std::string name = type_def->getName();
     uint64_t bytes = type_def->getLength();
     if (!target_type)
@@ -179,6 +181,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) {
 
     lldb_private::Type *element_type =
         m_ast.GetSymbolFile()->ResolveTypeUID(element_uid);
+    if (!element_type)
+      return nullptr;
     CompilerType element_ast_type = element_type->GetFullCompilerType();
     CompilerType array_ast_type =
         m_ast.CreateArrayType(element_ast_type, num_elements, false);
index 84c2555..de9b9f0 100644 (file)
@@ -19,6 +19,7 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Symbol/TypeMap.h"
+#include "lldb/Utility/RegularExpression.h"
 
 #include "llvm/DebugInfo/PDB/GenericError.h"
 #include "llvm/DebugInfo/PDB/IPDBDataStream.h"
@@ -293,7 +294,8 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
     return nullptr;
 
   lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);
-  m_types.insert(std::make_pair(type_uid, result));
+  if (result.get())
+    m_types.insert(std::make_pair(type_uid, result));
   return result.get();
 }
 
@@ -428,19 +430,16 @@ uint32_t SymbolFilePDB::FindTypes(
 
   std::string name_str = name.AsCString();
 
-  // If this might be a regex, we have to return EVERY symbol and process them
-  // one by one, which is going to destroy performance on large PDB files.  So
-  // try really hard not to use a regex match.
-  if (name_str.find_first_of("[]?*.-+\\") != std::string::npos)
-    FindTypesByRegex(name_str, max_matches, types);
-  else
-    FindTypesByName(name_str, max_matches, types);
+  // There is an assumption 'name' is not a regex
+  FindTypesByName(name_str, max_matches, types);
+   
   return types.GetSize();
 }
 
-void SymbolFilePDB::FindTypesByRegex(const std::string &regex,
-                                     uint32_t max_matches,
-                                     lldb_private::TypeMap &types) {
+void
+SymbolFilePDB::FindTypesByRegex(const lldb_private::RegularExpression &regex,
+                                uint32_t max_matches,
+                                lldb_private::TypeMap &types) {
   // When searching by regex, we need to go out of our way to limit the search
   // space as much as possible since this searches EVERYTHING in the PDB,
   // manually doing regex comparisons.  PDB library isn't optimized for regex
@@ -452,8 +451,6 @@ void SymbolFilePDB::FindTypesByRegex(const std::string &regex,
   auto global = m_session_up->getGlobalScope();
   std::unique_ptr<IPDBEnumSymbols> results;
 
-  std::regex re(regex);
-
   uint32_t matches = 0;
 
   for (auto tag : tags_to_search) {
@@ -476,7 +473,7 @@ void SymbolFilePDB::FindTypesByRegex(const std::string &regex,
         continue;
       }
 
-      if (!std::regex_match(type_name, re))
+      if (!regex.Execute(type_name))
         continue;
 
       // This should cause the type to get cached and stored in the `m_types`
index efd2cb0..d78358c 100644 (file)
@@ -172,7 +172,8 @@ private:
       const llvm::pdb::PDBSymbolCompiland &cu,
       llvm::DenseMap<uint32_t, uint32_t> &index_map) const;
 
-  void FindTypesByRegex(const std::string &regex, uint32_t max_matches,
+  void FindTypesByRegex(const lldb_private::RegularExpression &regex,
+                        uint32_t max_matches,
                         lldb_private::TypeMap &types);
 
   void FindTypesByName(const std::string &name, uint32_t max_matches,
index 77a18aa..ac4eba1 100644 (file)
@@ -519,6 +519,13 @@ TEST_F(SymbolFilePDBTests, TestRegexNameMatch) {
                                             false, 0, searched_files, results);
   EXPECT_GT(num_results, 1u);
   EXPECT_EQ(num_results, results.GetSize());
+
+  // We expect no exception thrown if the given regex can't be compiled
+  results.Clear();
+  num_results = symfile->FindTypes(sc, ConstString("**"), nullptr,
+                                   false, 0, searched_files, results);
+  EXPECT_EQ(num_results, 0u);
+  EXPECT_EQ(num_results, results.GetSize());
 }
 
 TEST_F(SymbolFilePDBTests, TestMaxMatches) {