gcc - GNU Compiler Collection (original) (raw)

author Senthil Kumar Selvaraj saaadhu@gcc.gnu.org 2025-12-18 11:45:50 +0530
committer Senthil Kumar Selvaraj saaadhu@gcc.gnu.org 2025-12-18 11:45:50 +0530
commit 5ae3346507bbc39731bf4d43efe56cdb208f23fc (patch)
tree 1db8558490bc3fc21e4e14140ee23a3840ebf918
parent ch: Fix detection of non-executed loop exit (diff)

Do not skip jobserver flags with negative file descriptorsHEADtrunkmaster

As part of jobserver detection, the jobserver_info constructor looks for the last occurence of "--jobserver-auth=", and parses the argument for that option to look for either a named pipe (has a "fifo:" prefix) or read and write pipe fds separated by a comma. With GNU Make 4.4 and above, named pipes are used by default because anonymous pipe fds cannot be used reliably (see https://savannah.gnu.org/bugs/?57242), but it still supports a --jobserver-style=pipe option for compatibility reasons. With that flag enabled, or with older GNU Make versions, the jobserver detection code checks if the provided fds are greater than 0 and valid. If invalid, it drops them from MAKEFLAGS used for subsequent child processes. However, GNU Make explicitly provides negative jobserver pipe fds if the command is not marked as recursive (i.e is missing a '+' prefix in the Makefile) - see https://savannah.gnu.org/bugs/?57242#comment13\. The MAKEFLAGS look like this in that case. -j4 --jobserver-auth=3,4 --jobserver-auth=-2,-2 Stripping off the final --jobserver-auth with negative fds undoes this helpful hint from GNU Make, and exposes child processes (like lto-wrapper) to all the issues with anonymous pipe fds that forced GNU Make to switch to named pipes by default. This patch prevents that stripping if jobserver communication is *not* via a named pipe *and* file descriptors are negative. As a result, child processes receive MAKEFLAGS with negative file descriptors too, and correctly decide that a jobserver is not available. gcc/ChangeLog: * opts-common.cc (jobserver_info::jobserver_info): Do not skip negative file descriptors in simple UNIX pipe mode.

-rw-r--r-- gcc/opts-common.cc 17

1 files changed, 11 insertions, 6 deletions

diff --git a/gcc/opts-common.cc b/gcc/opts-common.ccindex 379402e68a63..aaed63d13446 100644--- a/gcc/opts-common.cc+++ b/gcc/opts-common.cc
@@ -2110,7 +2110,8 @@ jobserver_info::jobserver_info ()
2110 if (n != string::npos) 2110 if (n != string::npos)
2111 { 2111 {
2112 string ending = makeflags.substr (n + js_needle.size ()); 2112 string ending = makeflags.substr (n + js_needle.size ());
2113 if (ending.find (fifo_prefix) == 0) 2113 bool is_named_pipe = ending.find (fifo_prefix) == 0;
2114 if (is_named_pipe)
2114 { 2115 {
2115 ending = ending.substr (fifo_prefix.size ()); 2116 ending = ending.substr (fifo_prefix.size ());
2116 pipe_path = ending.substr (0, ending.find (' ')); 2117 pipe_path = ending.substr (0, ending.find (' '));
@@ -2125,11 +2126,15 @@ jobserver_info::jobserver_info ()
2125 is_active = true; 2126 is_active = true;
2126 else 2127 else
2127 { 2128 {
2128 string dup = makeflags.substr (0, n); 2129 bool negative_fds = !is_named_pipe && rfd < 0 && wfd < 0;
2129 size_t pos = makeflags.find (' ', n); 2130 if (!negative_fds)
2130 if (pos != string::npos) 2131 {
2131 dup += makeflags.substr (pos); 2132 string dup = makeflags.substr (0, n);
2132 skipped_makeflags = "MAKEFLAGS=" + dup; 2133 size_t pos = makeflags.find (' ', n);
2134 if (pos != string::npos)
2135 dup += makeflags.substr (pos);
2136 skipped_makeflags = "MAKEFLAGS=" + dup;
2137 }
2133 error_msg 2138 error_msg
2134 = "cannot access %<" + js_needle + "%> file descriptors"; 2139 = "cannot access %<" + js_needle + "%> file descriptors";
2135 } 2140 }