about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorMartin Nowack <martin@se.inf.tu-dresden.de>2014-02-06 23:49:19 +0100
committerMartin Nowack <martin@se.inf.tu-dresden.de>2014-02-06 23:55:29 +0100
commit129a80e282a4740f479e68c84f8982a42f26ce83 (patch)
treeeb863ea837127fca7cc6459d2de25cbd546d4482
parentbaa7bff33bc9e69bdd4f0d6621b9c06ff82e11b4 (diff)
downloadklee-129a80e282a4740f479e68c84f8982a42f26ce83.tar.gz
Fix access of iterators after they have been invalidated
Iterators get invalidated after elements of std::vector/set are
deleted. Avoid this by remembering which elements need to be
deleted and do it after iterating over the data structure.
-rw-r--r--lib/Module/ModuleUtil.cpp68
1 files changed, 33 insertions, 35 deletions
diff --git a/lib/Module/ModuleUtil.cpp b/lib/Module/ModuleUtil.cpp
index 54cc0429..51375719 100644
--- a/lib/Module/ModuleUtil.cpp
+++ b/lib/Module/ModuleUtil.cpp
@@ -46,6 +46,7 @@
 #include "llvm/Support/Path.h"
 
 #include <map>
+#include <set>
 #include <iostream>
 #include <fstream>
 #include <sstream>
@@ -107,12 +108,13 @@ GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) {
 
   // Prune out any defined symbols from the undefined symbols set
   // and other symbols we don't want to treat as an undefined symbol
+  std::vector<std::string> RemovedSymbols;
   for (std::set<std::string>::iterator I = UndefinedSymbols.begin();
-       I != UndefinedSymbols.end(); )
+       I != UndefinedSymbols.end(); ++I )
   {
     if (DefinedSymbols.count(*I))
     {
-      UndefinedSymbols.erase(I++);  // This symbol really is defined!
+      RemovedSymbols.push_back(*I);
       continue;
     }
 
@@ -122,32 +124,29 @@ GetAllUndefinedSymbols(Module *M, std::set<std::string> &UndefinedSymbols) {
     {
       DEBUG_WITH_TYPE("klee_linker", dbgs() << "LLVM intrinsic " << *I <<
                       " has been removed from undefined symbols"<< "\n");
-      UndefinedSymbols.erase(I++);
+      RemovedSymbols.push_back(*I);
       continue;
     }
 
-    // Remove KLEE intrinsics from set of undefined symbols
-    bool kleeIntrinsicStripped=false;
-    for (SpecialFunctionHandler::const_iterator sf = SpecialFunctionHandler::begin(),
-         se = SpecialFunctionHandler::end(); sf != se; ++sf)
-    {
-      if (*I == sf->name)
-      {
-        DEBUG_WITH_TYPE("klee_linker", dbgs() << "KLEE intrinsic " << sf->name <<
-                        " has been removed from undefined symbols"<< "\n");
-        UndefinedSymbols.erase(I++);
-        kleeIntrinsicStripped=true;
-        break;
-      }
-    }
-
-    if (kleeIntrinsicStripped) continue;
-
     // Symbol really is undefined
     DEBUG_WITH_TYPE("klee_linker", dbgs() << "Symbol " << *I << " is undefined.\n");
-    ++I; // Keep this symbol in the undefined symbols list
   }
 
+  // Remove KLEE intrinsics from set of undefined symbols
+  for (SpecialFunctionHandler::const_iterator sf = SpecialFunctionHandler::begin(),
+       se = SpecialFunctionHandler::end(); sf != se; ++sf)
+  {
+    if (UndefinedSymbols.find(sf->name) == UndefinedSymbols.end())
+      continue;
+
+    RemovedSymbols.push_back(sf->name);
+    DEBUG_WITH_TYPE("klee_linker", dbgs() << "KLEE intrinsic " << sf->name <<
+                    " has been removed from undefined symbols"<< "\n");
+  }
+
+  for (size_t i = 0, j = RemovedSymbols.size(); i < j; ++i )
+    UndefinedSymbols.erase(RemovedSymbols[i]);
+
   DEBUG_WITH_TYPE("klee_linker", dbgs() << "*** Finished computing undefined symbols ***\n");
 }
 
@@ -262,33 +261,36 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er
     unsigned int modulesLoadedOnPass=0;
     previouslyUndefinedSymbols = undefinedSymbols;
 
-    for (std::vector<Module*>::iterator M = archiveModules.begin(), ME = archiveModules.end();
-        M != ME ;)
+    for (size_t i = 0, j = archiveModules.size(); i < j; ++i)
     {
+      // skip empty archives
+      if (archiveModules[i] == 0)
+        continue;
+      Module * M = archiveModules[i];
       // Look for the undefined symbols in the composite module
       for (std::set<std::string>::iterator S = undefinedSymbols.begin(), SE = undefinedSymbols.end();
          S != SE; ++S)
       {
+
         // FIXME: We aren't handling weak symbols here!
         // However the algorithm used in LLVM3.2 didn't seem to either
         // so maybe it doesn't matter?
+       // klee_warning("S: %s",(*S).c_str());
 
-        if ( GlobalValue* GV = dyn_cast_or_null<GlobalValue>((**M).getValueSymbolTable().lookup(*S)))
+        if ( GlobalValue* GV = dyn_cast_or_null<GlobalValue>(M->getValueSymbolTable().lookup(*S)))
         {
           if (GV->isDeclaration()) continue; // Not a definition
 
-          Module* moduleToLinkIn = *M;
-
-
           DEBUG_WITH_TYPE("klee_linker", dbgs() << "Found " << GV->getName() <<
-              " in " << (**M).getModuleIdentifier() << "\n");
+              " in " << M->getModuleIdentifier() << "\n");
 
 
-          if (Linker::LinkModules(composite, moduleToLinkIn, Linker::DestroySource, &errorMessage))
+          if (Linker::LinkModules(composite, M, Linker::DestroySource, &errorMessage))
           {
             // Linking failed
             SS << "Linking archive module with composite failed:" << errorMessage;
             SS.flush();
+            delete M;
             return false;
           }
           else
@@ -297,10 +299,8 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er
             modulesLoadedOnPass++;
             DEBUG_WITH_TYPE("klee_linker", dbgs() << "Linking succeeded.\n");
 
-            // Note use of postfix operator here so that the iterator gets incremented
-            // BEFORE we remove it from the vector so the iterator is not invalidated
-            archiveModules.erase(M++);
-            delete moduleToLinkIn;
+            delete M;
+            archiveModules[i] = 0;
 
             // We need to recompute the undefined symbols in the composite module
             // after linking
@@ -311,8 +311,6 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er
 
         }
       }
-
-      ++M; // Try next module
     }
 
     passCounter++;