This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[lto] fix collect2 hang


The patch below fixes an error I saw on the PPC64 machine I have: we
would sometimes hang in collect2 while scanning object files for the LTO
symbol marker.  I think what would happen is the following:

- 'nm' would produce some output;
- 'collect2' would consume that output and scan it for 'gnu_lto_v1';
- 'nm' would produce more output, filling up the pipe to 'collect2', but
   not enough to be finished with output;
- 'collect2' would find 'gnu_lto_v1' and wait for 'nm' to complete;
- 'nm' would be waiting for 'collect2' to flush the pipe's buffer...

...resulting in deadlock.

We fix this by simply reading all of the output from 'nm', even after we
found the marker we're looking for.

Committed to the LTO branch.

-Nathan

2007-12-29  Nathan Froyd  <froydnj@codesourcery.com>

	* collect2.c (scan_prog_file): Read all the output when reading
	information for LTO.

Index: collect2.c
===================================================================
--- collect2.c	(revision 131213)
+++ collect2.c	(working copy)
@@ -2365,6 +2365,7 @@ scan_prog_file (const char *prog_name, e
   int err;
   char *p, buf[1024];
   FILE *inf;
+  int found_lto = 0;
 
   if (which_pass == PASS_SECOND)
     return;
@@ -2440,6 +2441,9 @@ scan_prog_file (const char *prog_name, e
 
       if (which_pass == PASS_LTOINFO)
         {
+          if (found_lto)
+            continue;
+
           /* Look for the LTO info marker symbol, and add filename to
              the LTO objects list if found.  */
           for (p = buf; (ch = *p) != '\0' && ch != '\n'; p++)
@@ -2449,17 +2453,11 @@ scan_prog_file (const char *prog_name, e
               {
                 add_lto_object (&lto_objects, prog_name);
 
-                /* No need to look any further.  Clean up and return.  */
-                if (debug)
-                  fprintf (stderr, "\n");
-
-                do_wait (nm_file_name, pex);
+                /* We need to read all the input, so we can't just
+                   return here.  But we can avoid useless work.  */
+                found_lto = 1;
 
-                signal (SIGINT,  int_handler);
-#ifdef SIGQUIT
-                signal (SIGQUIT, quit_handler);
-#endif
-                return;
+                break;
               }
         }
       else


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]