[ccache] ccache interrupt handling bug

Nadav Har'El nyh at cloudius-systems.com
Sun Aug 16 21:31:29 UTC 2015

On Sun, Aug 9, 2015 at 11:23 PM, Joel Rosdahl <joel at rosdahl.net> wrote:

> Hi Nadav,
> (Sorry for the delayed reply.)
> Hi, I found a bug in ccache, which makes it impossible to
>> correctly interrupt a compilation with a control-C (I tried this on Linux).
>> [...]
> Thanks for the bug report and analysis. This will be fixed in ccache 3.2.3.
> Regards,
> -- Joel
Thanks. I see now the fix in 3.2.3, which if I understand correctly, is

--- a/ccache.c
+++ b/ccache.c
@@ -341,6 +341,7 @@ signal_handler(int signo)
+       _exit(1);

First of all, thanks. This indeed fixes the bug, and is exactly the first
patch I tried to fix it this problem.

I want to explain, though, why I ended up sending a different patch for
this problem - a 4-line patch instead of this one-liner. The explanation is
not very important, and I should probably have done this earlier, but
perhaps someone would find it interesting.

When the user types ^C, the operating system sends SIGINT to all processes
belonging to the terminal's process group - and in particular it sends
SIGINT to *both* the child compiler and ccache, separately.

Your patch makes ccache exit as soon as it gets the SIGINT - but the child
compiler might still be running for a while longer. This will usually be
fine, but I thought the user can be surprised if he sees ccache (which he
considers to be the compiler) exit, but "ps" shows the compiler is still
running. This would be especially annoying if some hypothetical compiler
trapped SIGINT deliberately, and continued to run long after ccache exits.

My approach, was to let ccache continue after the SIGINT, and continue to
wait (as it always does) for the child compiler to finish. The child, who
received a SIGINT too, willl indeed finish quickly. The code already
recognizes this case of the child killed by a signal, and returns status ==
-1. So all my 4-line patch did was to not restart the compiler if it died
with a status = -1 (i.e., a signal) and not an ordinary failure. But ccache
does not exit immediately on a signal - just after the child compiler exits.

Again, I guess this destinction is not very important, but I just wanted to
point it out in case anybody thinks it is important.

Nadav Har'El
nyh at cloudius-systems.com

More information about the ccache mailing list