From patchwork Fri Nov 17 19:21:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 24329 Received: (qmail 43135 invoked by alias); 17 Nov 2017 19:22:02 -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 43081 invoked by uid 89); 17 Nov 2017 19:22:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KB_WAM_FROM_NAME_SINGLEWORD, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=ours, pressed X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 17 Nov 2017 19:21:59 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3EB9480F79 for ; Fri, 17 Nov 2017 19:21:52 +0000 (UTC) Received: from cascais.lan (ovpn04.gateway.prod.ext.ams2.redhat.com [10.39.146.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9B0725C8B6 for ; Fri, 17 Nov 2017 19:21:51 +0000 (UTC) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH] linux-nat: Eliminate custom target_terminal_{inferior, ours}, stop using set_sigint_trap Date: Fri, 17 Nov 2017 19:21:50 +0000 Message-Id: <1510946510-6064-1-git-send-email-palves@redhat.com> This patch gets rid of linux-nat.c's custom target_terminal_inferior/target_terminal_ours implementations. The only remaining reason those overrides exist is to install clear_sigint_trap in order to pass Ctrl-C/SIGINT to the inferior process in case the inferior is not sharing GDB's terminal (and target_wait was called without TARGET_WNOHANG). However, I think that's better handled by QUIT / target_pass_ctrlc nowadays. Going that route avoids the issue with set_sigint_trap only looking at the current inferior to know whether to override SIGINT or not, which doesn't really work correctly with multi-inferior in the picture. Also centralizing on a single SIGINT handler as much as possible seems better considering a future multi-target world. Tested on x86-64 GNU/Linux. gdb/ChangeLog: yyyy-mm-dd Pedro Alves * linux-nat.c (wait_for_signal): New function. (wait_lwp, linux_nat_wait_1): Use it instead of calling sigsuspend directly. (async_terminal_is_ours) (linux_nat_terminal_inferior, linux_nat_terminal_ours): Delete. (linux_nat_add_target): Don't override to_terminal_inferior/to_terminal_ours. --- gdb/linux-nat.c | 78 +++++++++++++++++++-------------------------------------- 1 file changed, 26 insertions(+), 52 deletions(-) diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index a6395f4..9afa2c2 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -2173,6 +2173,30 @@ linux_handle_extended_wait (struct lwp_info *lp, int status) _("unknown ptrace event %d"), event); } +/* Suspend waiting for a signal. We're mostly interested in + SIGCHLD/SIGINT. */ + +static void +wait_for_signal () +{ + if (debug_linux_nat) + fprintf_unfiltered (gdb_stdlog, "linux-nat: about to sigsuspend\n"); + sigsuspend (&suspend_mask); + + /* If the quit flag is set, it means that the user pressed Ctrl-C + and we're debugging a process that is running on a separate + terminal, so we must forward the Ctrl-C to the inferior. (If the + inferior is sharing GDB's terminal, then the Ctrl-C reaches the + inferior directly.) We must do this here because functions that + need to block waiting for a signal loop forever until there's an + event to report before returning back to the event loop. */ + if (!target_terminal::is_ours ()) + { + if (check_quit_flag ()) + target_pass_ctrlc (); + } +} + /* Wait for LP to stop. Returns the wait status, or 0 if the LWP has exited. */ @@ -2238,10 +2262,7 @@ wait_lwp (struct lwp_info *lp) linux_nat_wait_1 and there if we get called my_waitpid gets called again before it gets to sigsuspend so we can safely let the handlers get executed here. */ - - if (debug_linux_nat) - fprintf_unfiltered (gdb_stdlog, "WL: about to sigsuspend\n"); - sigsuspend (&suspend_mask); + wait_for_signal (); } restore_child_signals_mask (&prev_mask); @@ -3425,9 +3446,7 @@ linux_nat_wait_1 (struct target_ops *ops, gdb_assert (lp == NULL); /* Block until we get an event reported with SIGCHLD. */ - if (debug_linux_nat) - fprintf_unfiltered (gdb_stdlog, "LNW: about to sigsuspend\n"); - sigsuspend (&suspend_mask); + wait_for_signal (); } gdb_assert (lp); @@ -4450,49 +4469,6 @@ linux_nat_supports_disable_randomization (struct target_ops *self) #endif } -static int async_terminal_is_ours = 1; - -/* target_terminal_inferior implementation. - - This is a wrapper around child_terminal_inferior to add async support. */ - -static void -linux_nat_terminal_inferior (struct target_ops *self) -{ - child_terminal_inferior (self); - - /* Calls to target_terminal_*() are meant to be idempotent. */ - if (!async_terminal_is_ours) - return; - - async_terminal_is_ours = 0; - set_sigint_trap (); -} - -/* target_terminal::ours implementation. - - This is a wrapper around child_terminal_ours to add async support (and - implement the target_terminal::ours vs target_terminal::ours_for_output - distinction). child_terminal_ours is currently no different than - child_terminal_ours_for_output. - We leave target_terminal::ours_for_output alone, leaving it to - child_terminal_ours_for_output. */ - -static void -linux_nat_terminal_ours (struct target_ops *self) -{ - /* GDB should never give the terminal to the inferior if the - inferior is running in the background (run&, continue&, etc.), - but claiming it sure should. */ - child_terminal_ours (self); - - if (async_terminal_is_ours) - return; - - clear_sigint_trap (); - async_terminal_is_ours = 1; -} - /* SIGCHLD handler that serves two purposes: In non-stop/async mode, so we notice when any child changes state, and notify the event-loop; it allows us to use sigsuspend in linux_nat_wait_1 @@ -4841,8 +4817,6 @@ linux_nat_add_target (struct target_ops *t) t->to_supports_non_stop = linux_nat_supports_non_stop; t->to_always_non_stop_p = linux_nat_always_non_stop_p; t->to_async = linux_nat_async; - t->to_terminal_inferior = linux_nat_terminal_inferior; - t->to_terminal_ours = linux_nat_terminal_ours; super_close = t->to_close; t->to_close = linux_nat_close;