[RFA,2/2] Fix kill issue leading to zombie process on MacOS Sierra

Message ID 20180713204456.23626-3-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey July 13, 2018, 8:44 p.m. UTC
  From: Xavier Roirand <roirand@adacore.com>

Starting with MacOS version Sierra, the gdb kill command
seems to work but inferior remains as zombie on the host.
Notice that, as zombie process, the inferior is not killable
by the user, nor by root.

The kill signal gdb sent to the inferior is not handled
in gdb as a signal sent by gdb thus no reply is made and
the process remains (since MacOS does not "release" the
inferior because no reply have been made to the signal
message).

This patch fixes this problem.

gdb/ChangeLog
2018-07-13  Xavier Roirand  <roirand@adacore.com>

	PR gdb/22629:
        * darwin-nat.c (darwin_kill_inferior): Fix handling of
        kill inferior.
---
 gdb/ChangeLog    |  6 ++++++
 gdb/darwin-nat.c | 18 ++++++++++++++++++
 2 files changed, 24 insertions(+)
  

Comments

Xavier Roirand Aug. 2, 2018, 2:49 p.m. UTC | #1
Le 7/13/18 à 10:44 PM, Tom Tromey a écrit :
> From: Xavier Roirand <roirand@adacore.com>
> 
> Starting with MacOS version Sierra, the gdb kill command
> seems to work but inferior remains as zombie on the host.
> Notice that, as zombie process, the inferior is not killable
> by the user, nor by root.
> 
> The kill signal gdb sent to the inferior is not handled
> in gdb as a signal sent by gdb thus no reply is made and
> the process remains (since MacOS does not "release" the
> inferior because no reply have been made to the signal
> message).
> 
> This patch fixes this problem.
> 
> gdb/ChangeLog
> 2018-07-13  Xavier Roirand  <roirand@adacore.com>
> 
> 	PR gdb/22629:
>          * darwin-nat.c (darwin_kill_inferior): Fix handling of
>          kill inferior.
> ---
>   gdb/ChangeLog    |  6 ++++++
>   gdb/darwin-nat.c | 18 ++++++++++++++++++
>   2 files changed, 24 insertions(+)
> 
> diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
> index 6d7b80ddcb1..be80163d22e 100644
> --- a/gdb/darwin-nat.c
> +++ b/gdb/darwin-nat.c
> @@ -1549,6 +1549,24 @@ darwin_nat_target::kill ()
>   
>     if (res == 0)
>       {
> +      /* On MacOS version Sierra, the darwin_restore_exception_ports call
> +         does not work as expected.
> +         When the kill function is called, the SIGKILL signal is received
> +         by gdb whereas it should have been received by the kernel since
> +         the exception ports have been restored.
> +         This behavior is not the expected one thus gdb does not reply to
> +         the received SIGKILL message. This situation leads to a "busy"
> +         resource from the kernel point of view and the inferior is never
> +         released, causing it to remain as a zombie process, even after
> +	 GDB exits.
> +         To work around this, we mark all the threads of the inferior as
> +         signaled thus darwin_decode_message function knows that the kill
> +         signal was sent by gdb and will take the appropriate action
> +         (cancel signal and reply to the signal message).  */
> +      darwin_inferior *priv = get_darwin_inferior (inf);
> +      for (darwin_thread_t *thread : priv->threads)
> +        thread->signaled = 1;
> +
>         darwin_resume_inferior (inf);
>   
>         ptid = darwin_wait (inferior_ptid, &wstatus);
> 

LGTM.

Regards.
  

Patch

diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
index 6d7b80ddcb1..be80163d22e 100644
--- a/gdb/darwin-nat.c
+++ b/gdb/darwin-nat.c
@@ -1549,6 +1549,24 @@  darwin_nat_target::kill ()
 
   if (res == 0)
     {
+      /* On MacOS version Sierra, the darwin_restore_exception_ports call
+         does not work as expected.
+         When the kill function is called, the SIGKILL signal is received
+         by gdb whereas it should have been received by the kernel since
+         the exception ports have been restored.
+         This behavior is not the expected one thus gdb does not reply to
+         the received SIGKILL message. This situation leads to a "busy"
+         resource from the kernel point of view and the inferior is never
+         released, causing it to remain as a zombie process, even after
+	 GDB exits.
+         To work around this, we mark all the threads of the inferior as
+         signaled thus darwin_decode_message function knows that the kill
+         signal was sent by gdb and will take the appropriate action
+         (cancel signal and reply to the signal message).  */
+      darwin_inferior *priv = get_darwin_inferior (inf);
+      for (darwin_thread_t *thread : priv->threads)
+        thread->signaled = 1;
+
       darwin_resume_inferior (inf);
 
       ptid = darwin_wait (inferior_ptid, &wstatus);