From patchwork Mon Dec 15 20:43:23 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Brobecker X-Patchwork-Id: 4260 Received: (qmail 26658 invoked by alias); 15 Dec 2014 20:43:26 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 26647 invoked by uid 89); 15 Dec 2014 20:43:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Mon, 15 Dec 2014 20:43:24 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 07D9E1163B2; Mon, 15 Dec 2014 15:43:23 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id R+6Cnf54VbVQ; Mon, 15 Dec 2014 15:43:22 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id E246111638D; Mon, 15 Dec 2014 15:43:22 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id 613A240166; Mon, 15 Dec 2014 15:43:23 -0500 (EST) Date: Mon, 15 Dec 2014 15:43:23 -0500 From: Joel Brobecker To: Pedro Alves Cc: gdb-patches@sourceware.org Subject: Re: [RFA/Linux] Ask kernel to kill inferior when GDB terminates Message-ID: <20141215204323.GE5457@adacore.com> References: <1415984034-27122-1-git-send-email-brobecker@adacore.com> <54663729.6010708@redhat.com> <20141114173255.GD5774@adacore.com> <20141119092547.GP5774@adacore.com> <546C69D4.5090300@redhat.com> <20141213162757.GL5457@adacore.com> <548EE088.20506@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <548EE088.20506@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) > I think we can get by without adding a new field. The process_info > structure has the "process->attached" field already. We could > check that here. Indeed! Attached is an updated patch which uses that flag. gdb/ChangeLog: * nat/linux-ptrace.h (PTRACE_O_EXITKILL): Define if not already defined. (linux_enable_event_reporting): Add parameter "attached". * nat/linux-ptrace.c (linux_test_for_exitkill): New advance declaration. New function. (linux_check_ptrace_features): Add new paramter "attached". Call linux_test_for_exitkill if !ATTACHED. (linux_enable_event_reporting): Add new parameter "attached". Update call to linux_check_ptrace_features. * linux-nat.c (linux_init_ptrace): Add parameter "attached". Use it. Update function description. (linux_child_post_attach, linux_child_post_startup_inferior): Update call to linux_enable_event_reporting. gdb/gdbserver/ChangeLog: * linux-low.c (linux_low_filter_event): Update call to linux_enable_event_reporting following the addition of a new parameter to that function. Tested on x86_64-linux, native and native-gdbserver. I also verified by hand that the inferior gets killed when killing GDB in the "run" case, while the inferior remains in the "attach" case. Same for GDBserver. OK to push? Thank you! From af12de3224fce611ea55325015db4822c7e96ff2 Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Tue, 11 Nov 2014 10:07:21 +0400 Subject: [PATCH] [Linux] Ask kernel to kill inferior when GDB terminates This patch enhances GDB on GNU/Linux systems in the situation where we are debugging an inferior that was created from GDB (as opposed to attached to), by asking the kernel to kill the inferior if GDB terminates without doing it itself. This would typically happen when GDB encounters a problem and crashes, or when it gets killed by an external process. This can be observed by starting a program under GDB, and then killing GDB with signal 9. After GDB is killed, the inferior still remains in "interruptible sleep (waiting for an event to complete)" state. This patch also fixes GDBserver similarly. This fix is conditional on the kernel supporting the PTRACE_O_EXITKILL feature. On older kernels, the behavior remains unchanged. gdb/ChangeLog: * nat/linux-ptrace.h (PTRACE_O_EXITKILL): Define if not already defined. (linux_enable_event_reporting): Add parameter "attached". * nat/linux-ptrace.c (linux_test_for_exitkill): New advance declaration. New function. (linux_check_ptrace_features): Add new paramter "attached". Call linux_test_for_exitkill if !ATTACHED. (linux_enable_event_reporting): Add new parameter "attached". Update call to linux_check_ptrace_features. * linux-nat.c (linux_init_ptrace): Add parameter "attached". Use it. Update function description. (linux_child_post_attach, linux_child_post_startup_inferior): Update call to linux_enable_event_reporting. gdb/gdbserver/ChangeLog: * linux-low.c (linux_low_filter_event): Update call to linux_enable_event_reporting following the addition of a new parameter to that function. Tested on x86_64-linux, native and native-gdbserver. I also verified by hand that the inferior gets killed when killing GDB in the "run" case, while the inferior remains in the "attach" case. Same for GDBserver. --- gdb/gdbserver/linux-low.c | 4 +++- gdb/linux-nat.c | 12 +++++++----- gdb/nat/linux-ptrace.c | 30 +++++++++++++++++++++++++----- gdb/nat/linux-ptrace.h | 7 ++++++- 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 5ea9200..65f72a2 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -1878,7 +1878,9 @@ linux_low_filter_event (ptid_t filter_ptid, int lwpid, int wstat) if (WIFSTOPPED (wstat) && child->must_set_ptrace_flags) { - linux_enable_event_reporting (lwpid); + struct process_info *proc = find_process_pid (pid_of (thread)); + + linux_enable_event_reporting (lwpid, proc->attached); child->must_set_ptrace_flags = 0; } diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 29133f9..845d566 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -321,25 +321,27 @@ pull_pid_from_list (struct simple_pid_list **listp, int pid, int *statusp) } /* Initialize ptrace warnings and check for supported ptrace - features given PID. */ + features given PID. + + ATTACHED should be nonzero iff we attached to the inferior. */ static void -linux_init_ptrace (pid_t pid) +linux_init_ptrace (pid_t pid, int attached) { - linux_enable_event_reporting (pid); + linux_enable_event_reporting (pid, attached); linux_ptrace_init_warnings (); } static void linux_child_post_attach (struct target_ops *self, int pid) { - linux_init_ptrace (pid); + linux_init_ptrace (pid, 1); } static void linux_child_post_startup_inferior (struct target_ops *self, ptid_t ptid) { - linux_init_ptrace (ptid_get_pid (ptid)); + linux_init_ptrace (ptid_get_pid (ptid), 0); } /* Return the number of known LWPs in the tgid given by PID. */ diff --git a/gdb/nat/linux-ptrace.c b/gdb/nat/linux-ptrace.c index 8bc3f16..8daa977 100644 --- a/gdb/nat/linux-ptrace.c +++ b/gdb/nat/linux-ptrace.c @@ -307,11 +307,13 @@ linux_child_function (gdb_byte *child_stack) static void linux_test_for_tracesysgood (int child_pid); static void linux_test_for_tracefork (int child_pid); +static void linux_test_for_exitkill (int child_pid); -/* Determine ptrace features available on this target. */ +/* Determine ptrace features available on this target. + ATTACHED should be nonzero iff we've attached to the inferior. */ static void -linux_check_ptrace_features (void) +linux_check_ptrace_features (int attached) { int child_pid, ret, status; @@ -338,6 +340,9 @@ linux_check_ptrace_features (void) linux_test_for_tracefork (child_pid); + if (!attached) + linux_test_for_exitkill (child_pid); + /* Clean things up and kill any pending children. */ do { @@ -449,15 +454,30 @@ linux_test_for_tracefork (int child_pid) "(%d, status 0x%x)"), ret, status); } -/* Enable reporting of all currently supported ptrace events. */ +/* Determine if PTRACE_O_EXITKILL can be used. */ + +static void +linux_test_for_exitkill (int child_pid) +{ + int ret; + + ret = ptrace (PTRACE_SETOPTIONS, child_pid, (PTRACE_TYPE_ARG3) 0, + (PTRACE_TYPE_ARG4) PTRACE_O_EXITKILL); + + if (ret == 0) + current_ptrace_options |= PTRACE_O_EXITKILL; +} + +/* Enable reporting of all currently supported ptrace events. + ATTACHED should be nonzero if we have attached to the inferior. */ void -linux_enable_event_reporting (pid_t pid) +linux_enable_event_reporting (pid_t pid, int attached) { /* Check if we have initialized the ptrace features for this target. If not, do it now. */ if (current_ptrace_options == -1) - linux_check_ptrace_features (); + linux_check_ptrace_features (attached); /* Set the options. */ ptrace (PTRACE_SETOPTIONS, pid, (PTRACE_TYPE_ARG3) 0, diff --git a/gdb/nat/linux-ptrace.h b/gdb/nat/linux-ptrace.h index 31a77cd..588d38a 100644 --- a/gdb/nat/linux-ptrace.h +++ b/gdb/nat/linux-ptrace.h @@ -69,6 +69,11 @@ struct buffer; #endif /* PTRACE_EVENT_FORK */ +#ifndef PTRACE_O_EXITKILL +/* Only defined in Linux Kernel 3.8 or later. */ +#define PTRACE_O_EXITKILL 0x00100000 +#endif + #if (defined __bfin__ || defined __frv__ || defined __sh__) \ && !defined PTRACE_GETFDPIC #define PTRACE_GETFDPIC 31 @@ -85,7 +90,7 @@ struct buffer; extern void linux_ptrace_attach_fail_reason (pid_t pid, struct buffer *buffer); extern void linux_ptrace_init_warnings (void); -extern void linux_enable_event_reporting (pid_t pid); +extern void linux_enable_event_reporting (pid_t pid, int attached); extern void linux_disable_event_reporting (pid_t pid); extern int linux_supports_tracefork (void); extern int linux_supports_traceclone (void); -- 1.9.1