This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lto] fix collect2 hang
- From: Nathan Froyd <froydnj at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 29 Dec 2007 12:16:14 -0800
- Subject: [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 (<o_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