From patchwork Mon Dec 5 18:56:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 61483 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4DF8A3948A4A for ; Mon, 5 Dec 2022 18:57:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4DF8A3948A4A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670266671; bh=h22jLBsFW4a6wtFxqsEUxAF6CU30AeYu0x3gv+V097U=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=C7BVZNPhzxLPLrqTmjSSm+X5zh/pLJi3SP3X5iEO6MDftNpGhELewV6IF0TGjIBsJ NBaDFNkc4ksL4syCAXtH+lxqhVanzygEXTNGtYD+wREVlynGGvkL48rxsDdtuXF3b2 drb8w4zGJvgF+Ed7DACfh3H6lgNoe7kthvMl8RcQ= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-io1-xd2c.google.com (mail-io1-xd2c.google.com [IPv6:2607:f8b0:4864:20::d2c]) by sourceware.org (Postfix) with ESMTPS id 7A9A9381D45D for ; Mon, 5 Dec 2022 18:56:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7A9A9381D45D Received: by mail-io1-xd2c.google.com with SMTP id g20so1041336iob.2 for ; Mon, 05 Dec 2022 10:56:59 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=h22jLBsFW4a6wtFxqsEUxAF6CU30AeYu0x3gv+V097U=; b=VhEceEy2JQyS1MA89dHM+5eyg/tI2YNXsbH8DpiUGKhkiizfb6t/66ipX9lges5pLq CWoLHhoMMF6/8+4evrY9jjqQAJSIbH+Ni0yje5urXByYGWEDAOykkGZsABF1lZQvjHNc M9WEqloUO8DgOL1KKoArCkdTpPLt+PvLSC00ufNqY/f7J2Uu9ZN6FbQ1/bjDjfWckili 9QD+sGx8EFe8LDWvBv+n8VkNMo6mb/8T0NtBn8bIrASR/NSnqT+d/wEeuOSXVNxjwHyW /edPoKD0CaJ6g621ZC2x8HuqrqthdIXeePUSc15n9oEIL25riuEtyGV9qAxR397eZXTx sGrw== X-Gm-Message-State: ANoB5pkifZOMEVpp249ZOChAKQhdAmjrFTqdG7Dn7wlqmnC/8jyA2aQu wEkwoAcg9J/j4T/jxON/jeOPYQ8+6eLjKtzm X-Google-Smtp-Source: AA0mqf7HKkqGE6v1bmx7wfI9F0dXFy0goPmT7xuq1TlOVeDNGqmzmlE3iLlnNyno6aGHRCLJVO4tPw== X-Received: by 2002:a02:c905:0:b0:374:e77e:d3d8 with SMTP id t5-20020a02c905000000b00374e77ed3d8mr38541835jao.103.1670266618801; Mon, 05 Dec 2022 10:56:58 -0800 (PST) Received: from localhost.localdomain (97-122-76-186.hlrn.qwest.net. [97.122.76.186]) by smtp.gmail.com with ESMTPSA id z29-20020a027a5d000000b00389d02a032dsm2000459jad.172.2022.12.05.10.56.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Dec 2022 10:56:58 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 1/3] Rename install_sigint_handler Date: Mon, 5 Dec 2022 11:56:49 -0700 Message-Id: <20221205185651.2704492-2-tromey@adacore.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20221205185651.2704492-1-tromey@adacore.com> References: <20221205185651.2704492-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" A subsequent patch will introduce a global 'install_sigint_handler' function, so first rename the static one in extension.c. --- gdb/extension.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gdb/extension.c b/gdb/extension.c index 8cbd80f45d5..1d951d60041 100644 --- a/gdb/extension.c +++ b/gdb/extension.c @@ -657,7 +657,7 @@ get_active_ext_lang (void) /* Install a SIGINT handler. */ static void -install_sigint_handler (const struct signal_handler *handler_state) +install_ext_sigint_handler (const struct signal_handler *handler_state) { gdb_assert (handler_state->handler_saved); @@ -756,7 +756,7 @@ restore_active_ext_lang (struct active_ext_lang_state *previous) { /* Restore the previous SIGINT handler if one was saved. */ if (previous->sigint_handler.handler_saved) - install_sigint_handler (&previous->sigint_handler); + install_ext_sigint_handler (&previous->sigint_handler); /* If there's a SIGINT recorded in the cooperative extension languages, move it to the new language, or save it in GDB's global flag if the From patchwork Mon Dec 5 18:56:50 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 61481 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 99A423948825 for ; Mon, 5 Dec 2022 18:57:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 99A423948825 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670266646; bh=e76TkS87vnR35H5MuZakzS3F8w2RJrvmoQRCM0cOk1A=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=H1Q8/HcfyjUExEsp72k1RitZ9GqOKo4mzDqhsLMN0SdPNrLq+4XIUnGp+ybi2svDI jyFJHM98amFmyJx4r8e8TQXaGMxQ03Osu5P0xxYrzvAd2CGVyd2KhYAcOTwWuxeVFo jCcqbFGIPXI/aCldGQalxhzlBBwyUdd3+yHYdB4A= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x131.google.com (mail-il1-x131.google.com [IPv6:2607:f8b0:4864:20::131]) by sourceware.org (Postfix) with ESMTPS id 619F33947C1E for ; Mon, 5 Dec 2022 18:57:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 619F33947C1E Received: by mail-il1-x131.google.com with SMTP id o13so5498954ilc.7 for ; Mon, 05 Dec 2022 10:57:00 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=e76TkS87vnR35H5MuZakzS3F8w2RJrvmoQRCM0cOk1A=; b=BF7oWK370p+anJKWe1bTdfNmIX/L8rw2XzgUpzzxBWhC3pUqgZRUMd6d95LuYeBcBe CsDwN2cOc47uigfl5cQM4h2eVQ60FnG/AVMmKYia3Q/A76MIlO5NbqErdK8xJA92ofDH KVDRFtJVF8idJYJM8ZMaB3YZOLHC5MNkq3epERAoFVHV0mqy2EJHuDjrjfo9wB/8apYd KYBDRCT+LA5VxMY+AbvxDaAp+rU2h8zHzlh2eooGuXgttzofHUWKKlmqqLEeLFzQm0hK B6qzmBkKzjIWAWXHDbTEo6zxd9GmU5EkMb+7XYoTltJ8iabl3maQbij5u9kPFrp2izqX YYHw== X-Gm-Message-State: ANoB5pmfX7X5dNvDQwiyW1/1s37Lh70SbL3tPYz2Fx49TqHyCKqtw+mv aBgOiosWiTHpFDDYcQM+efebE1YEWtJV2XR9 X-Google-Smtp-Source: AA0mqf4qWv7ToO5EaN4W3JFK/ssHwJd/8FJWtGy+U1Y3QdeU1n0VcMPPu8qzzEITjkdtYFrW2yJMGQ== X-Received: by 2002:a92:d144:0:b0:300:5d50:15d3 with SMTP id t4-20020a92d144000000b003005d5015d3mr27937984ilg.173.1670266619637; Mon, 05 Dec 2022 10:56:59 -0800 (PST) Received: from localhost.localdomain (97-122-76-186.hlrn.qwest.net. [97.122.76.186]) by smtp.gmail.com with ESMTPSA id z29-20020a027a5d000000b00389d02a032dsm2000459jad.172.2022.12.05.10.56.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Dec 2022 10:56:59 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 2/3] Refactor code to check for terminal sharing Date: Mon, 5 Dec 2022 11:56:50 -0700 Message-Id: <20221205185651.2704492-3-tromey@adacore.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20221205185651.2704492-1-tromey@adacore.com> References: <20221205185651.2704492-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This refactors the code to check for terminal sharing. is_gdb_terminal is exported, and sharing_input_terminal_1 is renamed, slightly refactored, and moved to posix-hdep.c. A new Windows-specific implementation of this function is added to mingw-hdep.c. One thing I'm not sure of here is how GetConsoleProcessList will work in all situations. MSDN has a warning about it: This API is not recommended and does not have a virtual terminal equivalent. [...] Applications remoting via cross-platform utilities and transports like SSH may not work as expected if using this API. However, I don't precisely know what this means. --- gdb/inferior.h | 11 +++++++++++ gdb/inflow.c | 27 +++------------------------ gdb/mingw-hdep.c | 31 ++++++++++++++++++++++++++++++- gdb/posix-hdep.c | 20 +++++++++++++++++++- 4 files changed, 63 insertions(+), 26 deletions(-) diff --git a/gdb/inferior.h b/gdb/inferior.h index 69525a2e053..547e8751d08 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -167,6 +167,17 @@ extern void default_print_float_info (struct gdbarch *gdbarch, frame_info_ptr frame, const char *args); +/* Try to determine whether TTY is GDB's input terminal. Returns + TRIBOOL_UNKNOWN if we can't tell. */ + +extern tribool is_gdb_terminal (const char *tty); + +/* Helper for sharing_input_terminal. Try to determine whether pid + PID is using the same TTY for input as GDB is. Returns + TRIBOOL_UNKNOWN if we can't tell. */ + +extern tribool sharing_input_terminal (int pid); + extern void child_terminal_info (struct target_ops *self, const char *, int); extern void child_terminal_ours (struct target_ops *self); diff --git a/gdb/inflow.c b/gdb/inflow.c index 5477624bcd5..17b1e8ce282 100644 --- a/gdb/inflow.c +++ b/gdb/inflow.c @@ -212,10 +212,9 @@ gdb_save_tty_state (void) } } -/* Try to determine whether TTY is GDB's input terminal. Returns - TRIBOOL_UNKNOWN if we can't tell. */ +/* See inferior.h. */ -static tribool +tribool is_gdb_terminal (const char *tty) { struct stat gdb_tty; @@ -236,26 +235,6 @@ is_gdb_terminal (const char *tty) : TRIBOOL_FALSE); } -/* Helper for sharing_input_terminal. Try to determine whether - inferior INF is using the same TTY for input as GDB is. Returns - TRIBOOL_UNKNOWN if we can't tell. */ - -static tribool -sharing_input_terminal_1 (inferior *inf) -{ - /* Using host-dependent code here is fine, because the - child_terminal_foo functions are meant to be used by child/native - targets. */ -#if defined (__linux__) || defined (__sun__) - char buf[100]; - - xsnprintf (buf, sizeof (buf), "/proc/%d/fd/0", inf->pid); - return is_gdb_terminal (buf); -#else - return TRIBOOL_UNKNOWN; -#endif -} - /* Return true if the inferior is using the same TTY for input as GDB is. If this is true, then we save/restore terminal flags/state. @@ -287,7 +266,7 @@ sharing_input_terminal (inferior *inf) { terminal_info *tinfo = get_inflow_inferior_data (inf); - tribool res = sharing_input_terminal_1 (inf); + tribool res = sharing_input_terminal (inf->pid); if (res == TRIBOOL_UNKNOWN) { diff --git a/gdb/mingw-hdep.c b/gdb/mingw-hdep.c index 651e795216d..9d0337cf4ef 100644 --- a/gdb/mingw-hdep.c +++ b/gdb/mingw-hdep.c @@ -21,8 +21,8 @@ #include "main.h" #include "serial.h" #include "gdbsupport/event-loop.h" - #include "gdbsupport/gdb_select.h" +#include "inferior.h" #include @@ -371,3 +371,32 @@ gdb_console_fputs (const char *linebuf, FILE *fstream) last_style = style; return 1; } + +/* See inferior.h. */ + +tribool +sharing_input_terminal (int pid) +{ + std::vector results (10); + DWORD len = 0; + while (true) + { + len = GetConsoleProcessList (results.data (), results.size ()); + /* Note that LEN == 0 is a failure, but we can treat it the same + as a "no". */ + if (len < results.size ()) + break; + + results.resize (len); + } + /* In case the vector was too big. */ + results.resize (len); + if (std::find (results.begin (), results.end (), pid) != results.end ()) + { + /* The pid is in the list sharing the console, so don't + interrupt the inferior -- it will get the signal itself. */ + return TRIBOOL_TRUE; + } + + return TRIBOOL_FALSE; +} diff --git a/gdb/posix-hdep.c b/gdb/posix-hdep.c index 3d44338d2ae..26211978d06 100644 --- a/gdb/posix-hdep.c +++ b/gdb/posix-hdep.c @@ -19,8 +19,8 @@ #include "defs.h" #include "gdbsupport/event-loop.h" - #include "gdbsupport/gdb_select.h" +#include "inferior.h" /* Wrapper for select. Nothing special needed on POSIX platforms. */ @@ -38,3 +38,21 @@ gdb_console_fputs (const char *buf, FILE *f) { return 0; } + +/* See inferior.h. */ + +tribool +sharing_input_terminal (int pid) +{ + /* Using host-dependent code here is fine, because the + child_terminal_foo functions are meant to be used by child/native + targets. */ +#if defined (__linux__) || defined (__sun__) + char buf[100]; + + xsnprintf (buf, sizeof (buf), "/proc/%d/fd/0", pid); + return is_gdb_terminal (buf); +#else + return TRIBOOL_UNKNOWN; +#endif +} From patchwork Mon Dec 5 18:56:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 61482 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BF3113948A6E for ; Mon, 5 Dec 2022 18:57:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BF3113948A6E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670266652; bh=Qr9ShZlKq5Wt+tDhTMVF+mpoCpgQdKrtsBIrwGzUsPI=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=cBATgJVXWmIFUfNP4yBjty4GmABpZ6jd0W7/orhBbABbsrzX5LwDON5cIFSGR3uAo 7LYmtNPMgRdqT1HLGFlVrark22TMo+NNDGN/61fDvCuV4lCa6g8nssfk4mbm/fvXE9 39oxHd4yYdhA3OiGbz/S4cgtXZ6a9pzf+O3qWQrM= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-il1-x12a.google.com (mail-il1-x12a.google.com [IPv6:2607:f8b0:4864:20::12a]) by sourceware.org (Postfix) with ESMTPS id 3D0DC39484A3 for ; Mon, 5 Dec 2022 18:57:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3D0DC39484A3 Received: by mail-il1-x12a.google.com with SMTP id s16so5506556iln.4 for ; Mon, 05 Dec 2022 10:57:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Qr9ShZlKq5Wt+tDhTMVF+mpoCpgQdKrtsBIrwGzUsPI=; b=ZkVvEWMA245itdxPAqvjUff3OnSOsSd/SzbYB2dNh1uWaPjUTeMaGxlaLaqt9w+qLJ PYMXbun06eVPYhA3kTh2yeh7Ieu5QtTixwf7MxRULBZfXgiCMGH4rTZzCzfhxZQJpLBx OOIAlrsg2prvu++FE5QLsLaL9Uh0nb2MikLhBWlHvNHrMfmXM0TI1fconAoDhPW9srr/ AjsPrFvi8KsoqhscBz22Zx1nc81C6n6fX1Ktb5ZSNMFZtrDJlGvGO563yPtuG/IWARCZ wr1LgF44UTHQ7gWxElC0h73+4w89OFX9p+rHKpqN3EHcPyWG8fKWsduDkuDOXggwoqSX 85MA== X-Gm-Message-State: ANoB5pljV5WIuby1q4POQUTvMigrn3F61EGRsi2bFCJHn0CWlbESnpPk dqqJQsj5CgsnOC4tJFsj32yWCEppX7J5a6jS X-Google-Smtp-Source: AA0mqf7q48GdsOoN9TXRL7zcDGsBRjZoTv3MUT+MZa7owuZWMx0yLXuRuR0vrgnRat/V0ZqrdHNPuA== X-Received: by 2002:a92:dc49:0:b0:302:f72b:2032 with SMTP id x9-20020a92dc49000000b00302f72b2032mr22218026ilq.93.1670266620314; Mon, 05 Dec 2022 10:57:00 -0800 (PST) Received: from localhost.localdomain (97-122-76-186.hlrn.qwest.net. [97.122.76.186]) by smtp.gmail.com with ESMTPSA id z29-20020a027a5d000000b00389d02a032dsm2000459jad.172.2022.12.05.10.56.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Dec 2022 10:56:59 -0800 (PST) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 3/3] Fix control-c handling on Windows Date: Mon, 5 Dec 2022 11:56:51 -0700 Message-Id: <20221205185651.2704492-4-tromey@adacore.com> X-Mailer: git-send-email 2.34.3 In-Reply-To: <20221205185651.2704492-1-tromey@adacore.com> References: <20221205185651.2704492-1-tromey@adacore.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tom Tromey via Gdb-patches From: Tom Tromey Reply-To: Tom Tromey Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" As Hannes pointed out, the Windows target-async patches broke C-c handling there. Looking into this, I found a few oddities, fixed here. First, windows_nat_target::interrupt calls GenerateConsoleCtrlEvent. I think this event can be ignored by the inferior, so it's not a great way to interrupt. Instead, using DebugBreakProcess (or a more complicated thing for Wow64) seems better. Second, windows_nat_target did not implement the pass_ctrlc method. Implementing this lets us remove the special code to call SetConsoleCtrlHandler and instead integrate into gdb's approach to C-c handling. I believe that this should also fix the race that's described in the comment that's being removed. Initially, I thought a simpler version of this patch would work. However, I think what happens is that some other library (I'm not sure what) calls SetConsoleCtrlHandler while gdb is running, and this intercepts and handles C-c -- so that the gdb SIGINT handler is not called. C-break continues to work, presumably because whatever handler is installed ignores it. This patch works around this issue by ensuring that the gdb handler always comes first. --- gdb/event-top.c | 2 +- gdb/extension.c | 5 +-- gdb/inferior.h | 10 ++++++ gdb/inflow.c | 8 ++--- gdb/mingw-hdep.c | 37 +++++++++++++++++++++ gdb/posix-hdep.c | 24 ++++++++++++++ gdb/windows-nat.c | 83 +++++++++++------------------------------------ 7 files changed, 98 insertions(+), 71 deletions(-) diff --git a/gdb/event-top.c b/gdb/event-top.c index 0e371194ee3..29dd151f0b5 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -1071,7 +1071,7 @@ gdb_init_signals (void) sigint_token = create_async_signal_handler (async_request_quit, NULL, "sigint"); - signal (SIGINT, handle_sigint); + install_sigint_handler (handle_sigint); async_sigterm_token = create_async_signal_handler (async_sigterm_handler, NULL, "sigterm"); diff --git a/gdb/extension.c b/gdb/extension.c index 1d951d60041..ae8ef0d6e31 100644 --- a/gdb/extension.c +++ b/gdb/extension.c @@ -33,6 +33,7 @@ #include "python/python.h" #include "guile/guile.h" #include +#include "inferior.h" static script_sourcer_func source_gdb_script; static objfile_script_sourcer_func source_gdb_objfile_script; @@ -661,7 +662,7 @@ install_ext_sigint_handler (const struct signal_handler *handler_state) { gdb_assert (handler_state->handler_saved); - signal (SIGINT, handler_state->handler); + install_sigint_handler (handler_state->handler); } /* Install GDB's SIGINT handler, storing the previous version in *PREVIOUS. @@ -675,7 +676,7 @@ install_gdb_sigint_handler (struct signal_handler *previous) /* Save here to simplify comparison. */ sighandler_t handle_sigint_for_compare = handle_sigint; - previous->handler = signal (SIGINT, handle_sigint); + previous->handler = install_sigint_handler (handle_sigint); if (previous->handler != handle_sigint_for_compare) previous->handler_saved = 1; else diff --git a/gdb/inferior.h b/gdb/inferior.h index 547e8751d08..6fc0a30b12c 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -178,6 +178,16 @@ extern tribool is_gdb_terminal (const char *tty); extern tribool sharing_input_terminal (int pid); +/* The type of the function that is called when SIGINT is handled. */ + +typedef void c_c_handler_ftype (int); + +/* Install a new SIGINT handler in a host-dependent way. The previous + handler is returned. It is fine to pass SIG_IGN for FN, but not + SIG_DFL. */ + +extern c_c_handler_ftype *install_sigint_handler (c_c_handler_ftype *fn); + extern void child_terminal_info (struct target_ops *self, const char *, int); extern void child_terminal_ours (struct target_ops *self); diff --git a/gdb/inflow.c b/gdb/inflow.c index 17b1e8ce282..344a4eaf509 100644 --- a/gdb/inflow.c +++ b/gdb/inflow.c @@ -332,7 +332,7 @@ child_terminal_inferior (struct target_ops *self) if (!job_control) { - sigint_ours = signal (SIGINT, SIG_IGN); + sigint_ours = install_sigint_handler (SIG_IGN); #ifdef SIGQUIT sigquit_ours = signal (SIGQUIT, SIG_IGN); #endif @@ -480,7 +480,7 @@ child_terminal_ours_1 (target_terminal_state desired_state) if (!job_control && desired_state == target_terminal_state::is_ours) { - signal (SIGINT, sigint_ours); + install_sigint_handler (sigint_ours); #ifdef SIGQUIT signal (SIGQUIT, sigquit_ours); #endif @@ -865,7 +865,7 @@ set_sigint_trap (void) if (inf->attach_flag || !tinfo->run_terminal.empty ()) { - osig = signal (SIGINT, pass_signal); + osig = install_sigint_handler (pass_signal); osig_set = 1; } else @@ -877,7 +877,7 @@ clear_sigint_trap (void) { if (osig_set) { - signal (SIGINT, osig); + install_sigint_handler (osig); osig_set = 0; } } diff --git a/gdb/mingw-hdep.c b/gdb/mingw-hdep.c index 9d0337cf4ef..5a69282b99b 100644 --- a/gdb/mingw-hdep.c +++ b/gdb/mingw-hdep.c @@ -400,3 +400,40 @@ sharing_input_terminal (int pid) return TRIBOOL_FALSE; } + +/* Current C-c handler. */ +static c_c_handler_ftype *current_handler; + +/* The Windows callback that forwards requests to the C-c handler. */ +static BOOL WINAPI +ctrl_c_handler (DWORD event_type) +{ + if (event_type == CTRL_BREAK_EVENT || event_type == CTRL_C_EVENT) + { + if (current_handler != SIG_IGN) + current_handler (SIGINT); + } + else + return FALSE; + return TRUE; +} + +/* See inferior.h. */ + +c_c_handler_ftype * +install_sigint_handler (c_c_handler_ftype *fn) +{ + /* We want to make sure the gdb handler always comes first, so that + gdb gets to handle the C-c. This is why the handler is always + removed and reinstalled here. Note that trying to remove the + function without installing it first will cause a crash. */ + static bool installed = false; + if (installed) + SetConsoleCtrlHandler (ctrl_c_handler, FALSE); + SetConsoleCtrlHandler (ctrl_c_handler, TRUE); + installed = true; + + c_c_handler_ftype *result = current_handler; + current_handler = fn; + return result; +} diff --git a/gdb/posix-hdep.c b/gdb/posix-hdep.c index 26211978d06..eddf73f38c9 100644 --- a/gdb/posix-hdep.c +++ b/gdb/posix-hdep.c @@ -21,6 +21,7 @@ #include "gdbsupport/event-loop.h" #include "gdbsupport/gdb_select.h" #include "inferior.h" +#include /* Wrapper for select. Nothing special needed on POSIX platforms. */ @@ -56,3 +57,26 @@ sharing_input_terminal (int pid) return TRIBOOL_UNKNOWN; #endif } + +/* Current C-c handler. */ +static c_c_handler_ftype *current_handler; + +/* A wrapper that reinstalls the current signal handler. */ +static void +handler_wrapper (int num) +{ + signal (num, handler_wrapper); + if (current_handler != SIG_IGN) + current_handler (num); +} + +/* See inferior.h. */ + +c_c_handler_ftype * +install_sigint_handler (c_c_handler_ftype *fn) +{ + signal (SIGINT, handler_wrapper); + c_c_handler_ftype *result = current_handler; + current_handler = fn; + return result; +} diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index b3329cd1a0d..dafda4781b9 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -298,6 +298,7 @@ struct windows_nat_target final : public x86_nat_target std::string pid_to_str (ptid_t) override; void interrupt () override; + void pass_ctrlc () override; const char *pid_to_exec_file (int pid) override; @@ -1509,24 +1510,12 @@ windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig) windows_continue (continue_status, ptid.lwp (), 0); } -/* Ctrl-C handler used when the inferior is not run in the same console. The - handler is in charge of interrupting the inferior using DebugBreakProcess. - Note that this function is not available prior to Windows XP. In this case - we emit a warning. */ -static BOOL WINAPI -ctrl_c_handler (DWORD event_type) -{ - const int attach_flag = current_inferior ()->attach_flag; - - /* Only handle Ctrl-C and Ctrl-Break events. Ignore others. */ - if (event_type != CTRL_C_EVENT && event_type != CTRL_BREAK_EVENT) - return FALSE; - - /* If the inferior and the debugger share the same console, do nothing as - the inferior has also received the Ctrl-C event. */ - if (!new_console && !attach_flag) - return TRUE; +/* Interrupt the inferior. */ +void +windows_nat_target::interrupt () +{ + DEBUG_EVENTS ("interrupt"); #ifdef __x86_64__ if (windows_process.wow64_process) { @@ -1548,19 +1537,24 @@ ctrl_c_handler (DWORD event_type) windows_process.wow64_dbgbreak, NULL, 0, NULL); if (thread) - CloseHandle (thread); + { + CloseHandle (thread); + return; + } } } else #endif - { - if (!DebugBreakProcess (windows_process.handle)) - warning (_("Could not interrupt program. " - "Press Ctrl-c in the program console.")); - } + if (DebugBreakProcess (windows_process.handle)) + return; + warning (_("Could not interrupt program. " + "Press Ctrl-c in the program console.")); +} - /* Return true to tell that Ctrl-C has been handled. */ - return TRUE; +void +windows_nat_target::pass_ctrlc () +{ + interrupt (); } /* Get the next event from the child. Returns the thread ptid. */ @@ -1840,35 +1834,7 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, while (1) { - /* If the user presses Ctrl-c while the debugger is waiting - for an event, he expects the debugger to interrupt his program - and to get the prompt back. There are two possible situations: - - - The debugger and the program do not share the console, in - which case the Ctrl-c event only reached the debugger. - In that case, the ctrl_c handler will take care of interrupting - the inferior. Note that this case is working starting with - Windows XP. For Windows 2000, Ctrl-C should be pressed in the - inferior console. - - - The debugger and the program share the same console, in which - case both debugger and inferior will receive the Ctrl-c event. - In that case the ctrl_c handler will ignore the event, as the - Ctrl-c event generated inside the inferior will trigger the - expected debug event. - - FIXME: brobecker/2008-05-20: If the inferior receives the - signal first and the delay until GDB receives that signal - is sufficiently long, GDB can sometimes receive the SIGINT - after we have unblocked the CTRL+C handler. This would - lead to the debugger stopping prematurely while handling - the new-thread event that comes with the handling of the SIGINT - inside the inferior, and then stop again immediately when - the user tries to resume the execution in the inferior. - This is a classic race that we should try to fix one day. */ - SetConsoleCtrlHandler (&ctrl_c_handler, TRUE); ptid_t result = get_windows_debug_event (pid, ourstatus, options); - SetConsoleCtrlHandler (&ctrl_c_handler, FALSE); if (result != null_ptid) { @@ -2868,17 +2834,6 @@ windows_nat_target::mourn_inferior () inf_child_target::mourn_inferior (); } -/* Send a SIGINT to the process group. This acts just like the user typed a - ^C on the controlling terminal. */ - -void -windows_nat_target::interrupt () -{ - DEBUG_EVENTS ("GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)"); - CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, - windows_process.current_event.dwProcessId)); -} - /* Helper for windows_xfer_partial that handles memory transfers. Arguments are like target_xfer_partial. */