From patchwork Thu Dec 8 11:31:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom de Vries X-Patchwork-Id: 61694 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 E751C3836D28 for ; Thu, 8 Dec 2022 11:32:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E751C3836D28 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1670499126; bh=V9c8k9rvyWVO1Cvt6KlMf62J1QopubQbjj1pY1v/qvI=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=VH5931sDyn65qegLQU+yeNuMQ4GczIefykWUgPwIch3KvRr+4/zF3xgJAGCduQ9e8 Ifwh8QCMPpPuNKXPhCmsccSHOxMw+qkWxyz8DiFsLEXk1mOF8uxbpdt3DEd2pgGoAC JYZufgRBagmVAwCVyYJH5zzEGITG/SQSDJ8m5lyY= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by sourceware.org (Postfix) with ESMTPS id 6EA9E383FF65 for ; Thu, 8 Dec 2022 11:31:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6EA9E383FF65 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id AB911208B8; Thu, 8 Dec 2022 11:31:40 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 8E05F138E0; Thu, 8 Dec 2022 11:31:40 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 8lRyIRzLkWN+JgAAMHmgww (envelope-from ); Thu, 08 Dec 2022 11:31:40 +0000 To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [RFC] [gdb] Stop on undetermined longjmp target during next Date: Thu, 8 Dec 2022 12:31:40 +0100 Message-Id: <20221208113140.1231-1-tdevries@suse.de> X-Mailer: git-send-email 2.35.3 MIME-Version: 1.0 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, 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 de Vries via Gdb-patches From: Tom de Vries Reply-To: Tom de Vries Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Currently, for a libc without probes, we have: ... 56 longjmp (env, 1);^M (gdb) PASS: gdb.base/longjmp.exp: pattern 1: next to longjmp next^M ^M Breakpoint 3, main () at longjmp.c:59^M 59 i = 1; /* miss_step_1 */^M (gdb) KFAIL: gdb.base/longjmp.exp: pattern 1: gdb/26967 (PRMS: next over longjmp) ... In other words, the next degrades to a continue, and we stop only because of the safety net breakpoint at miss_step_1. Instead, stop in the longjmp, in order to not lose the context that the next was issued from: ... 56 longjmp (env, 1);^M (gdb) PASS: gdb.base/longjmp.exp: pattern 1: next to longjmp next^M warning: GDB can't determine the longjmp target^M 0x00007ffff76dc8de in siglongjmp () from /lib64/libc.so.6^M (gdb) KFAIL: gdb.base/longjmp.exp: pattern 1: gdb/26967 (PRMS: next over longjmp) ... We can get the old behaviour back by issuing a continue command. However, it also changes behaviour in the following case. Without this patch, we have: ... Breakpoint 6, main () at longjmp.c:75^M 75 hidden_longjmp (); /* patt3 */^M (gdb) PASS: gdb.base/longjmp.exp: pattern 3: setup: \ continue to breakpoint at pattern start next^M 77 i = 77; /* longjmp caught */^M (gdb) PASS: gdb.base/longjmp.exp: pattern 3: next over pattern ... and with this patch, we get instead: ... 75 hidden_longjmp (); /* patt3 */^M (gdb) PASS: gdb.base/longjmp.exp: pattern 3: setup: \ continue to breakpoint at pattern start next^M warning: GDB can't determine the longjmp target^M 0x00007ffff76dc8de in siglongjmp () from /lib64/libc.so.6^M (gdb) KFAIL: gdb.base/longjmp.exp: pattern 3: gdb/26967 (PRMS: next over pattern) ... In this case, we cannot get the old behaviour back by issuing a continue command, because the stop will have removed the temporary breakpoint on line 77 placed there by the next command. Instead, our only option to "finish the next" as before is to set a breakpoint on line 77 and continue. Note that while the user experience in the first case improves, in the second case it degrades, and possibly this is the reason that the old behaviour was chosen in the first place. [ It would be possible to address this conundrum by presenting the user with a question to choose the behaviour: stop, or continue and hope to finish the next. Another option would be to leave the address of the temporary breakpoint in some convenience variable, such that the user could do something like: ... warning: next aborted, tbreak address available in \ $_aborted_next_tbreak_address (gdb) tbreak *$_aborted_next_tbreak_address (gdb) continue ... ] Note also that this makes the behaviour the same between the scenarios that: - the longjmp target cannot be found, and - the longjmp target can be found, but is mangled and we fail to set a breakpoint, in the sense that we now get a stop in both cases. Tested on x86_64-linux, with a glibc that does support probes, and a gdb patch that ignores the libc longjmp probe: ... base-commit: c9a2e0cd0a03944351807b6ab2f1b80ea7724126 --- a/gdb/probe.c +++ b/gdb/probe.c @@ -980,4 +980,6 @@ OBJECT matches the executable or shared library name.\n\ If you do not specify any argument then the command will ignore\n\ all defined probes. Only supported for SystemTap probes"), &maintenancelist); + + ignore_probes_command ("libc ^longjmp$", 0); } ... using the RFC patch introducing the "maint ignore-probes" command ( https://sourceware.org/pipermail/gdb-patches/2022-December/194535.html ). The gdb.base/longjmp.exp test-case has been updated to accept the new behaviour. I found these regressions (only first in test-case listed): ... FAIL: gdb.base/longjmp-until-in-main.exp: until $line, in main FAIL: gdb.base/premature-dummy-frame-removal.exp: p some_func () FAIL: gdb.base/stale-infcall.exp: test system longjmp tracking support ... These will need to be updated to accept the new behaviour. Since this is an RFC, I've left that for now. Suggested-By: Simon Marchi --- gdb/infrun.c | 3 ++- gdb/testsuite/gdb.base/longjmp.exp | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index c67458b30b6..51bc72dae5f 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -6650,7 +6650,8 @@ process_event_stop_test (struct execution_control_state *ecs) { infrun_debug_printf ("BPSTAT_WHAT_SET_LONGJMP_RESUME " "(!gdbarch_get_longjmp_target)"); - keep_going (ecs); + warning (_("GDB can't determine the longjmp target")); + end_stepping_range (ecs); return; } diff --git a/gdb/testsuite/gdb.base/longjmp.exp b/gdb/testsuite/gdb.base/longjmp.exp index 0f78304a14a..c3f46f06698 100644 --- a/gdb/testsuite/gdb.base/longjmp.exp +++ b/gdb/testsuite/gdb.base/longjmp.exp @@ -81,6 +81,9 @@ set re_cannot_insert_bp \ "Cannot insert breakpoint $decimal\\." \ "Cannot access memory at address $hex"] +set re_no_longjmp_target \ + "warning: GDB can't determine the longjmp target" + # # Pattern 1 - simple longjmp. # @@ -111,7 +114,7 @@ with_test_prefix "pattern 1" { gdb_test "next" "resumes\\+\\+.*" "next into else block" gdb_test "next" "miss_step_1.*" "next into safety net" } - -re "miss_step_1.*$gdb_prompt $" { + -re -wrap "\r\n$re_no_longjmp_target\r\n.*" { if { $have_longjmp_probe } { fail $gdb_test_name } else { @@ -158,7 +161,7 @@ with_test_prefix "pattern 2" { gdb_test "next" "resumes\\+\\+.*" "next into else block" gdb_test "next" "miss_step_2.*" "next into safety net" } - -re "miss_step_2.*$gdb_prompt $" { + -re -wrap "\r\n$re_no_longjmp_target\r\n.*" { if { $have_longjmp_probe } { fail $gdb_test_name } else { @@ -194,6 +197,13 @@ with_test_prefix "pattern 3" { -re -wrap "longjmp caught.*" { pass $gdb_test_name } + -re -wrap "\r\n$re_no_longjmp_target\r\n.*" { + if { $have_longjmp_probe } { + fail $gdb_test_name + } else { + kfail $gdb_test_name "gdb/26967" + } + } -re -wrap "\r\n$re_cannot_insert_bp\r\n.*" { if { $have_longjmp_probe } { fail $gdb_test_name