From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id J3lTKTyp2GrZkgIAWB0awg (envelope-from ) for ; Wed, 21 Oct 2026 07:59:56 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=mi5n/R5B; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=5LE93opv; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=mi5n/R5B; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=5LE93opv; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 94BAA1E047; Wed, 21 Oct 2026 07:59:56 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-5.4 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [IPv6:2620:52:6:3111::32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 776BE1E047 for ; Wed, 21 Oct 2026 07:59:52 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1BE474BA23EB for ; Wed, 21 Oct 2026 11:59:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1BE474BA23EB Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=mi5n/R5B; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=5LE93opv; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=mi5n/R5B; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=5LE93opv Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2a07:de40:b251:101:10:150:64:2]) by sourceware.org (Postfix) with ESMTPS id 1165C4BA23E9 for ; Wed, 21 Oct 2026 11:59:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1165C4BA23E9 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.de ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1165C4BA23E9 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=2a07:de40:b251:101:10:150:64:2 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1792583961; cv=none; b=QQYx6TYSufEfmN6WpnK0KcSN8/BbUm6YtAgsM4zZJLUuZ8tGjwFmYXA9qMthaT/GvbVWXRK/YbQutefXZxHh4vsx/Mf84XRy1rFcjq1ycYtIiDlX1Dq8gX+pKVTm3r15wfuX01KX/9X2LQpFLCEquzHkMixsl1X1X7egYe6mfP8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1792583961; c=relaxed/simple; bh=OEcBR/9YubJTAFWcKTmOoDAz6cQzzg32TfUafUMM+qI=; h=DKIM-Signature:DKIM-Signature:DKIM-Signature:DKIM-Signature:From: To:Subject:Date:Message-ID:MIME-Version; b=omDONL26MJHdAGfKAuVNHDDxnQu125FUKcKHJS5EmoZa5XYTv/oeLAgUS7RlS1+VLqgvS+K7yRNsueCIdHA/1i61qQgYOSEcHqdtmo9lhZEyP/aRd/FYfLJSbubj8xtXhJ8jaYBohr7QO+1m+mfg310/WIXiTfV6Jv8JNDxGzqU= ARC-Authentication-Results: i=1; sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=mi5n/R5B; dkim=pass header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=5LE93opv; dkim=pass (1024-bit key) header.d=suse.de header.i=@suse.de header.a=rsa-sha256 header.s=susede2_rsa header.b=mi5n/R5B; dkim=neutral header.d=suse.de header.i=@suse.de header.a=ed25519-sha256 header.s=susede2_ed25519 header.b=5LE93opv DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1165C4BA23E9 Received: from imap1.dmz-prg2.suse.org (unknown [10.150.64.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 7A22A1F794 for ; Wed, 21 Oct 2026 11:59:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1792583959; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=Fkm9ELAvEOWu35ivL22nTn+e1dwrOpAM1qXwkE9IrVE=; b=mi5n/R5BDISFefaMHKAGdg3czQ60UaxXomIBf2tFcVxCXAu5EYppP1DLkRWIaJAMbgv7fr vs6KA3Aef38gXJnXT8E0MyAR9sW2cI/wVLibxavktdSo3L77rAczA/TAiB3oZfkz/ff808 oHpgPEgK2BKRseGzJC4pkRQK6+qvNMA= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1792583959; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=Fkm9ELAvEOWu35ivL22nTn+e1dwrOpAM1qXwkE9IrVE=; b=5LE93opvp/3Qn5QmdEHaZArsyCKfPisRHwwRVPmrG7F3f2G38AakXtILK2l8SNOzi8elQX vLJfzablwy2OyaDA== Authentication-Results: smtp-out2.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1792583959; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=Fkm9ELAvEOWu35ivL22nTn+e1dwrOpAM1qXwkE9IrVE=; b=mi5n/R5BDISFefaMHKAGdg3czQ60UaxXomIBf2tFcVxCXAu5EYppP1DLkRWIaJAMbgv7fr vs6KA3Aef38gXJnXT8E0MyAR9sW2cI/wVLibxavktdSo3L77rAczA/TAiB3oZfkz/ff808 oHpgPEgK2BKRseGzJC4pkRQK6+qvNMA= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1792583959; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=Fkm9ELAvEOWu35ivL22nTn+e1dwrOpAM1qXwkE9IrVE=; b=5LE93opvp/3Qn5QmdEHaZArsyCKfPisRHwwRVPmrG7F3f2G38AakXtILK2l8SNOzi8elQX vLJfzablwy2OyaDA== Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id 41B23134FD for ; Wed, 21 Oct 2026 11:59:19 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id 3+uyBhep2GpsNAAAD6G6ig (envelope-from ) for ; Wed, 21 Oct 2026 11:59:19 +0000 From: Tom de Vries To: gdb-patches@sourceware.org Subject: [PATCH] [gdb/tui] Fix segfault in tui_win_info::forward_scroll Date: Wed, 21 Oct 2026 13:59:18 +0200 Message-ID: <20261021115918.443487-1-tdevries@suse.de> X-Mailer: git-send-email 2.51.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spamd-Result: default: False [-11.80 / 50.00]; SUSE_INTERNAL_BYPASS(-9.00)[]; BAYES_HAM(-3.00)[100.00%]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000]; R_MISSING_CHARSET(0.50)[]; NEURAL_HAM_SHORT(-0.20)[-0.999]; MIME_GOOD(-0.10)[text/plain]; RCPT_COUNT_ONE(0.00)[1]; RCVD_VIA_SMTP_AUTH(0.00)[]; ARC_NA(0.00)[]; DKIM_SIGNED(0.00)[suse.de:s=susede2_rsa,suse.de:s=susede2_ed25519]; DBL_BLOCKED_OPENRESOLVER(0.00)[imap1.dmz-prg2.suse.org:helo]; FROM_EQ_ENVFROM(0.00)[]; FROM_HAS_DN(0.00)[]; MIME_TRACE(0.00)[0:+]; RCVD_COUNT_TWO(0.00)[2]; TO_MATCH_ENVRCPT_ALL(0.00)[]; TO_DN_NONE(0.00)[]; PREVIOUSLY_DELIVERED(0.00)[gdb-patches@sourceware.org]; RCVD_TLS_ALL(0.00)[] X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org Consider the following setup: we create a TUI layout with only the command window, and enable it: ... (gdb) tui new-layout command-layout cmd 1 (gdb) layout command-layout ... Now say we use the "scroll window forward" command: ... (gdb) help + Scroll window forward. Usage: + [N] [WIN] Scroll window WIN N lines forwards. Both WIN and N are optional, N defaults to 1, and WIN defaults to the currently focused window. ... on the command window: ... (gdb) + 1 cmd ... We run into a segfault in tui_win_info::forward_scroll because this is nullptr. That happens because in parse_scrolling_args we do: ... else if (*win_to_scroll == tui_cmd_win ()) *win_to_scroll = *(tui_source_windows ().begin ()); ... while tui_source_windows () is an empty range. Dereferencing begin () for an empty range means dereferencing end (), which is undefined behavior. But it happens to set *win_to_scroll to nullptr. Tui_scroll_forward_command doesn't expect a nullptr win_to_scroll, and just dereferences it: ... if (arg == NULL) parse_scrolling_args (arg, &win_to_scroll, NULL); else parse_scrolling_args (arg, &win_to_scroll, &num_to_scroll); win_to_scroll->forward_scroll (num_to_scroll); ... which causes the segfault in tui_win_info::forward_scroll. Fix this conservatively, by ignoring the scroll if there are no source windows. While working on this patch, I noticed a related problem in parse_scrolling_args: there's a difference in behavior between the cases where you specify the command window implicitly (command window has focus) and explicitly [1]. More concretely, in a TUI setup with source and command window, and the focus on the command window, this command (using the command window, because it's the one with focus) has no effect: ... (gdb) + 1 ... but this command (using the command window, because it's explicitly specified) scrolls the source window: ... (gdb) + 1 cmd ... This behavior is not specified in the documentation or help message, not checked in the testsuite and not replicated in any of the other scroll methods. So an alternative way of fixing this would be to drop the special treatment of the command window in parse_scrolling_args, and fix both PRs that way. Tested on x86_64-linux. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34772 [1] https://sourceware.org/bugzilla/show_bug.cgi?id=34773 --- gdb/testsuite/gdb.tui/cmd-layout.exp | 46 ++++++++++++++++++++++++++++ gdb/tui/tui-win.c | 9 +++++- 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 gdb/testsuite/gdb.tui/cmd-layout.exp diff --git a/gdb/testsuite/gdb.tui/cmd-layout.exp b/gdb/testsuite/gdb.tui/cmd-layout.exp new file mode 100644 index 00000000000..d83b951b884 --- /dev/null +++ b/gdb/testsuite/gdb.tui/cmd-layout.exp @@ -0,0 +1,46 @@ +# Copyright 2026 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Check layout with only a command window. + +require allow_tui_tests + +tuiterm_env + +Term::clean_restart 24 80 + +# Use a layout with just a command window. +gdb_test_no_output "tui new-layout command-layout cmd 1" + +if {![Term::prepare_for_tui]} { + unsupported "TUI not supported" + return +} + +# Enter TUI. +gdb_assert {[Term::command_no_prompt_prefix "layout command-layout"]} \ + "activated layout" + +foreach op {+ - < >} { + gdb_assert {[Term::command "$op"]} \ + "scroll command: $op" + + gdb_assert {[Term::command "$op 1"]} \ + "scroll command: $op 1" + + # Regression test for PR34772. This used to trigger a segfault. + gdb_assert {[Term::command "$op 1 cmd"]} \ + "scroll command: $op 1 cmd" +} diff --git a/gdb/tui/tui-win.c b/gdb/tui/tui-win.c index 7b174b13913..8f9c4ab443d 100644 --- a/gdb/tui/tui-win.c +++ b/gdb/tui/tui-win.c @@ -1073,7 +1073,14 @@ parse_scrolling_args (const char *arg, if (!(*win_to_scroll)->is_visible ()) error (_("Window is not visible")); else if (*win_to_scroll == tui_cmd_win ()) - *win_to_scroll = *(tui_source_windows ().begin ()); + { + /* If there's a source window, pick the first one. + Otherwise, let the command window ignore the scroll. */ + auto range = tui_source_windows (); + auto first = range.begin (); + if (first != range.end ()) + *win_to_scroll = *first; + } } } } base-commit: cfd8ea4e101d9793895d9b8b016da5c2ec6a672a -- 2.51.0