GNOME Bugzilla – Bug 760874
build panel cancel button does not cause autotools to abort build
Last modified: 2016-02-16 02:27:05 UTC
Something is awry with the GCancellable that gets cancelled between the cancel button being clicked and the cancellable used to perform a build operation. This will need some tracking down to see if the cancellable is indeed getting triggered, and then how far down it goes. Ensure that the GSubprocess' that are spawned are using the same GCancellable.
Created attachment 320796 [details] [review] Experimental changes to prove that the GCancellable is being triggered. This patch is just an experiment. I have made the following changes and I believe that the same GCancellable is being used correctly. Also, I think that somehow the function to kill the GSubprocess isn't working. I have created and attached a handler function to the GCancellable, which when triggered, is calling g_subprocess_force_exit(process). However. This doesn't seem to work.The subprocess continues to build the files. (I call Cancel immediately after I call Build). Is there any other way I can terminate a subprocess().? Also in the APIs it says "Cancelling doesn't kill the subprocess. Call g_subprocess_force_exit() if it is desirable.". I have even tried using the g_subprocess_send_signal(process,9). Still it doesn't work.
Also, here is my output when I press Build followed by Cancel immediately. 18:33:32.0003 (null)[7367]: WARNING: Spawned process in make all. 18:33:33.0130 (null)[7337]: WARNING: Invocation of force_exit process made here.. 18:33:33.0130 (null)[7367]: WARNING: cancellable was triggered inside the subprocess 18:33:33.0131 (null)[7337]: WARNING: Operation was cancelled
Excellent research. So perhaps we need to make a helper to handle the cancelled event and call force quit? Interestingly, I'm working on IdeSubprocessLauncher on the wip/chergert/runtimes branch where we might be able to plumb this in. (We need the ability for runtimes to prefix shell commands with something like "xdg-app build ", so we are doing our own GSubprocessLauncher-like abstraction).
Created attachment 321338 [details] test case of make not getting killed So here is a small test case that runs make and then kills the subprocess. You'll notice the subprocess doesn't die, and I think this is because the death signal isn't being inherited by the grandchildren. We might need to create a process group leader, or some other mechanism (cgroup) to allow us to kill everything in the group. Doing this in a portable fashion (I really only care about Linux, and BSD but to a lesser degree) is sort of painful, but seems possible.
Created attachment 321339 [details] [review] libide: use setsid() and kill(-pid, SIGKILL) to kill process group We had an issue where "gmake", despite getting SIGKILL, would not cause the build process to exit. This seems to be caused by the descendent processes not dying with the parent. To allow us to kill all of the processes, we first create a new session group with setsid() in our child setup function. If the process should be cancelled (via g_cancellable_cancel()), then we send SIGKILL to all members of the session group with kill(-pid, SIGKILL). Specifying a negated(pid) indicates delivery to all members of the group. We probably need to verify that this works on FreeBSD, but it seems plausible that will.
This problem has been fixed in the unstable development version. The fix will be available in the next major software release. You may need to upgrade your Linux distribution to obtain that newer version.