<div dir="ltr">Thanks!</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jul 24, 2013 at 10:32 AM, Rafael Espindola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rafael<br>
Date: Wed Jul 24 09:32:01 2013<br>
New Revision: 187042<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=187042&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=187042&view=rev</a><br>
Log:<br>
Don't leak when expanding response files.<br>
<br>
Before this patch we would strdup each argument. If one was a response file,<br>
we would replace it with the response file contents, leaking the original<br>
strdup result.<br>
<br>
We now don't strdup the originals and let StringSaver free any memory it<br>
allocated. This also saves a bit of malloc traffic when response files are<br>
not used.<br>
<br>
Leak found by the valgrind build bot.<br>
<br>
Modified:<br>
    llvm/trunk/lib/Support/CommandLine.cpp<br>
<br>
Modified: llvm/trunk/lib/Support/CommandLine.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CommandLine.cpp?rev=187042&r1=187041&r2=187042&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CommandLine.cpp?rev=187042&r1=187041&r2=187042&view=diff</a><br>

==============================================================================<br>
--- llvm/trunk/lib/Support/CommandLine.cpp (original)<br>
+++ llvm/trunk/lib/Support/CommandLine.cpp Wed Jul 24 09:32:01 2013<br>
@@ -563,8 +563,19 @@ bool cl::ExpandResponseFiles(StringSaver<br>
<br>
 namespace {<br>
   class StrDupSaver : public StringSaver {<br>
+    std::vector<char*> Dups;<br>
+  public:<br>
+    ~StrDupSaver() {<br>
+      for (std::vector<char *>::iterator I = Dups.begin(), E = Dups.end();<br>
+           I != E; ++I) {<br>
+        char *Dup = *I;<br>
+        free(Dup);<br>
+      }<br>
+    }<br>
     const char *SaveString(const char *Str) LLVM_OVERRIDE {<br>
-      return strdup(Str);<br>
+      char *Dup = strdup(Str);<br>
+      Dups.push_back(Dup);<br>
+      return Dup;<br>
     }<br>
   };<br>
 }<br>
@@ -588,20 +599,14 @@ void cl::ParseEnvironmentOptions(const c<br>
   // Get program's "name", which we wouldn't know without the caller<br>
   // telling us.<br>
   SmallVector<const char *, 20> newArgv;<br>
-  newArgv.push_back(strdup(progName));<br>
+  StrDupSaver Saver;<br>
+  newArgv.push_back(Saver.SaveString(progName));<br>
<br>
   // Parse the value of the environment variable into a "command line"<br>
   // and hand it off to ParseCommandLineOptions().<br>
-  StrDupSaver Saver;<br>
   TokenizeGNUCommandLine(envValue, Saver, newArgv);<br>
   int newArgc = static_cast<int>(newArgv.size());<br>
   ParseCommandLineOptions(newArgc, &newArgv[0], Overview);<br>
-<br>
-  // Free all the strdup()ed strings.<br>
-  for (SmallVectorImpl<const char *>::iterator i = newArgv.begin(),<br>
-                                               e = newArgv.end();<br>
-       i != e; ++i)<br>
-    free(const_cast<char *>(*i));<br>
 }<br>
<br>
 void cl::ParseCommandLineOptions(int argc, const char * const *argv,<br>
@@ -618,7 +623,7 @@ void cl::ParseCommandLineOptions(int arg<br>
   // Expand response files.<br>
   SmallVector<const char *, 20> newArgv;<br>
   for (int i = 0; i != argc; ++i)<br>
-    newArgv.push_back(strdup(argv[i]));<br>
+    newArgv.push_back(argv[i]);<br>
   StrDupSaver Saver;<br>
   ExpandResponseFiles(Saver, TokenizeGNUCommandLine, newArgv);<br>
   argv = &newArgv[0];<br>
@@ -914,13 +919,6 @@ void cl::ParseCommandLineOptions(int arg<br>
   PositionalOpts.clear();<br>
   MoreHelp->clear();<br>
<br>
-  // Free the memory allocated by ExpandResponseFiles.<br>
-  // Free all the strdup()ed strings.<br>
-  for (SmallVectorImpl<const char *>::iterator i = newArgv.begin(),<br>
-                                               e = newArgv.end();<br>
-       i != e; ++i)<br>
-    free(const_cast<char *>(*i));<br>
-<br>
   // If we had an error processing our arguments, don't let the program execute<br>
   if (ErrorParsing) exit(1);<br>
 }<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>