From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id 8TgfDYi5MWnDQRkAWB0awg (envelope-from ) for ; Thu, 04 Dec 2025 11:40:40 -0500 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=W5ap929F; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 31EC81E0B3; Thu, 04 Dec 2025 11:40:40 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-1.1 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=no autolearn_force=no version=4.0.1 Received: from sourceware.org (vm01.sourceware.org [38.145.34.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 518761E08D for ; Thu, 04 Dec 2025 11:40:39 -0500 (EST) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E14E24C31829 for ; Thu, 4 Dec 2025 16:40:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E14E24C31829 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=W5ap929F Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id AB22F4B1A362 for ; Thu, 4 Dec 2025 16:38:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AB22F4B1A362 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AB22F4B1A362 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1764866311; cv=none; b=tA0/eGpPEZ0TFLJm2r3VEs017Wq3ixlB8TBjyC5AUbq0FMNc4H3LSahDvGQvyaNbiGl9P5ehR1npgYknG/NtZVQk1Htm53v4X3Ugd3mgoIJ+FVPUNLw6VYyH+xbgdxv2oosb1Re8vrD4XSuFVqzElz9spNUF1Frcu1LIZMDQbyA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1764866311; c=relaxed/simple; bh=wq70VhvK6JS+mNHrEzfoY2Xw1xQUlTxPl6O0Im70ZEk=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=B2IVU8meWHSUQFjJVxzr3X0F+FzAVLQ9AIbZCT8KB6nM0DhT0EppvqHfjkg2tlu6F1E8zsFpInoGvBLZ2V+VXy3AJgHd8pvhkRbHHkwJzexAV86gBtDSucIshTdpgm2fZyvdEYsv+7kFnmnajlWq6SBwEtTy1GlTv8Q3prodfyo= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AB22F4B1A362 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1764866311; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tiGZxuscPUF/N8e2e76KYB3hwELAUJp+JxTwYAzKAGU=; b=W5ap929Fz9Ppf00Smvv25dboRfOajKkIugSixAFH7VVSXyvwusdqcpe8gfGGTIZ/QeZcsv ZUPXM0uO1swyZvjmCU4EiA+Iqx5mMgsm8evCC+w/1BHCD0CvAtBa7GQDlQT+wLx8V1SyMD DNBiFRYlH1o4NSrGXCrwVvLxU92npDI= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-664-pFog0eBNMW2p6cx4EdnXuQ-1; Thu, 04 Dec 2025 11:38:30 -0500 X-MC-Unique: pFog0eBNMW2p6cx4EdnXuQ-1 X-Mimecast-MFC-AGG-ID: pFog0eBNMW2p6cx4EdnXuQ_1764866309 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-47797caba11so4872005e9.3 for ; Thu, 04 Dec 2025 08:38:29 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764866308; x=1765471108; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=tiGZxuscPUF/N8e2e76KYB3hwELAUJp+JxTwYAzKAGU=; b=Y0HMb/1IBUPNEpvvfuMxEHCkdgHyyMdgA7mOARhy4VyZJAjUCeKthmsfS07R7XXPA7 uUNHdHk4pXCObOQG/Y9ivzhAwS7T0zVpwtxLOh6zxGt13S4pYD5lPWR/D/BM3Jp9w5Nq K2eM/KHSSP+HKYyRtKH4E3nxGxp7Lj0C3atzGDN33ONdPDu+gr7pJdSHzADIDCHSnOxu p1j3NLyU3h5oWKPG5MtuWeQsvjULfSwYACatrymE8lWbj2VaDMlA94Okhn921xGY5ehe XqMbZp7u+t7j8zTgX0wYkQ+21AteQSCONIOmpo5NLTtOUUZcMZDRLFHqA82vHsyGt+4W ydjw== X-Gm-Message-State: AOJu0YzFzblsH7h57oKaXottzto8PYppyhF8o2k++kJVAK5M2zTf17hK Yp1AK+QPd4ta+QJFqEfZePhTBIGH7CAtRHoLkjmDvnamJN0/ZeGIjr7ZhVV6fodQVE7bH7LqOyX y0BzQgF+0SUzxpMrjFZIdWuSnpAkTeKPQ21f8HJSZMOGhf4hkifTlJDe/swZKeTfSrq8OAw0AlT 7dk7uSU3HXPXDIJt+3TFghJ2bb7QmrvN1557Wql73rQurIWMc= X-Gm-Gg: ASbGnctCZYdMcUXE+IElsyAcSPcNULJSZr6BKpaRSyVFCp70TSa+5UiFGVoh6fr3oEd MFLKznvmJGlmCCEZxpy3nIfWqZBj0Ci6x7UiM59/Iz7vKOlQUQwvoCWUNwbDQwIB8rlSzAwySCY K/2nreH+xnf5+/Q6AAAoK2v8baAz5T+GWL9lh5H6XHQdwoBrjecray6W5BKQOJxPxmUf47N8U2Q OD6k3yQqj8uOUzb83v9nJgRlzG/pvQjfCWi6wSkghKkpkLyPDOt99Gem+nG/LeU9CA2vqfy59CX 8xZH2/jcUqHO4GmCVXY+SVn5Z6DG8EuU5Qf5d27ExEptJ6aNU/XyYN21dq0tNWkL9dThgvqbpa0 Uouwo X-Received: by 2002:a05:600c:35c7:b0:477:7523:da8c with SMTP id 5b1f17b1804b1-4792aef09d2mr91954805e9.15.1764866307988; Thu, 04 Dec 2025 08:38:27 -0800 (PST) X-Google-Smtp-Source: AGHT+IGBHtqXgCsPj9/lUfKlCb4fmKpibpajHCGTTlS7TlRNH5GnNOQIFMm3AmKrM5cpGEWDrms9dA== X-Received: by 2002:a05:600c:35c7:b0:477:7523:da8c with SMTP id 5b1f17b1804b1-4792aef09d2mr91954045e9.15.1764866307230; Thu, 04 Dec 2025 08:38:27 -0800 (PST) Received: from localhost ([31.111.84.207]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-479310a6db3sm41632585e9.1.2025.12.04.08.38.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Dec 2025 08:38:26 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Guinevere Larsen , Andrew Burgess Subject: [PATCH 4/4] gdb: fix crashes and weird output from new boxed hint text Date: Thu, 4 Dec 2025 16:38:17 +0000 Message-ID: X-Mailer: git-send-email 2.47.1 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: OaQHG1e36l7sVieZtKE1IiqDC_vgUz9efgeRDQSu4P4_1764866309 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 After the commit: commit f6df8aa48f120b78f0670b429f8a3363020a47dc Date: Mon Sep 15 11:56:17 2025 -0300 gdb: Make startup message more user friendly I noticed, that when I start GDB with a file on the command line, I was seeing some stray '..'. Like this: $ gdb -nw -nh /tmp/hello.x GNU gdb (GDB) 18.0.50.20251202-git Copyright (C) 2025 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-pc-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Find the GDB manual online at: ┃ ┃ http://www.gnu.org/software/gdb/documentation/. ┃ ┃ For help, type "help". ┃ ┃ Type "apropos " to search for commands related to ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ .. Reading symbols from /tmp/hello.x... Notice the '..' after the boxed hint text, that's what I'm complaining about. Before the above commit these '..' used to appear after the line: Type "apropos " to search for commands related to The '..' are added to show that a file is being loaded, and that this might take some time. But we have the 'Reading symbols from ...' text to indicate this now, so I think these extra '..' are redundant. Lets just drop them. Looking at these I noticed that the line: Type "apropos " to search for commands related to is missing a period at the end, so I've added that in too. The above commit unfortunately, didn't include any tests, so I thought I'd write some to cover this fix.... and that uncovered a bug where the box around the startup hints could be corrupted: $ gdb -eiex 'set width 50' -nw -nh GNU gdb (GDB) 18.0.50.20251202-git Copyright (C) 2025 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-pc-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Find the GDB manual online at: ┃ ┃ http://www.gnu.org/software/gdb/documentation/. ┃ ┃ For help, type "help". ┃ ┃ Type "apropos " to ┃ ┃ search for commands related to ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ (gdb) This was caused by a mistake on the line where we choose whether to box or not. The line is currently: if (width - 3 <= docs_url.length ()) There are two problems here, the '3' should be '4'. The box adds 4 characters '| ' and ' |'. But also, the width can be very small, less than 4 even, which means that the width will wrap around and become very large. I plan to rewrite the line to: if (width < docs_url.length () + 1 + 4) The '+ 1' accounts for the period at the end of the URL line (which was previously handled by the '<=', and the '+ 4' accounts for the box borders. By making it a '+ 4' on the URL, rather than '- 4' from the width, we avoid underflow on the width. This is fine so long as the URL to our documentation doesn't approach UINT_MAX in length. Which I hope it never does. I've added a couple of asserts to print_gdb_hints to reflect things that must be true. The first is that get_chars_per_line never returns 0. And later on, I assert that 'width > 4' in a place where we are about to do 'width - 4'. If the assert triggers then underflow would have occurred. --- gdb/main.c | 5 +- gdb/testsuite/gdb.base/startup-hints.exp | 144 +++++++++++++++++++++++ gdb/top.c | 21 +++- 3 files changed, 161 insertions(+), 9 deletions(-) create mode 100644 gdb/testsuite/gdb.base/startup-hints.exp diff --git a/gdb/main.c b/gdb/main.c index 0fa2b0ecbe4..e4da715134b 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -1197,13 +1197,10 @@ captured_main_1 (struct captured_main_args *context) if (!quiet) { - /* Print all the junk at the top, with trailing "..." if we are - about to read a symbol file (possibly slowly). */ + /* Print the version, copyright information, and hint text. */ print_gdb_version (gdb_stdout, true); gdb_printf ("\n"); print_gdb_hints (gdb_stdout); - if (symarg) - gdb_printf (".."); gdb_printf ("\n"); gdb_flush (gdb_stdout); /* Force to screen during slow operations. */ diff --git a/gdb/testsuite/gdb.base/startup-hints.exp b/gdb/testsuite/gdb.base/startup-hints.exp new file mode 100644 index 00000000000..0addf3769a2 --- /dev/null +++ b/gdb/testsuite/gdb.base/startup-hints.exp @@ -0,0 +1,144 @@ +# Copyright 2025 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 . + +# Test the start up hint text. Check that it is boxed (or not) +# correctly. + +# Test assumes host == build. +require {!is_remote host} + +# Just use a simple empty 'main' function. +standard_testfile main.c + +if { [build_executable "build" $testfile $srcfile] != 0 } { + return +} + +# Return a single regexp string for the startup hint text when the +# terminal width is WIDTH. For narrow terminals GDB will just print +# the hint text. For wider terminals GDB places the hint into a box. +proc build_hint_re { width } { + # GDB imposes a maximum width of 80. + if { $width > 80 || $width == 0 } { + set width 80 + } + + if { $width > 50 } { + + # These lines are shorter than 50 characters, and so are never + # wrapped. + set msg { + {Find the GDB manual online at:} + {http://www.gnu.org/software/gdb/documentation/.} + {For help, type "help".} + } + + # The final line is wrapped based on the terminal width. + if { $width > 66 } { + lappend msg {Type "apropos " to search for commands related to .} + } elseif { $width > 58 } { + lappend msg {Type "apropos " to search for commands related to} {.} + } elseif { $width > 55 } { + lappend msg {Type "apropos " to search for commands related} {to .} + } elseif { $width > 47 } { + lappend msg {Type "apropos " to search for commands} { related to .} + } + + # Place the lines into a box, padding with whitespace so that + # the sides are correctly aligned. + set top_bottom "+[string repeat "-" [expr $width - 2]]+" + set lines [list $top_bottom] + foreach m $msg { + set space_count [expr $width - 4 - [string length $m]] + set spaces [string repeat " " $space_count] + lappend lines "| $m$spaces |" + } + lappend lines $top_bottom + } else { + # We tell GDB that the terminal width is WIDTH, but in reality + # the actual terminal width is unlimited. As such, GDB drops + # the box around the hint, but doesn't inject any additional + # newlines (it assumes the terminal will break the lines for + # us). This is why, despite the narrow terminal, we expect + # each line without any line breaks. + set lines {{Find the GDB manual online at:} \ + {http://www.gnu.org/software/gdb/documentation/.} \ + {For help, type "help".} \ + {Type "apropos " to search for commands related to .}} + } + + # Add blank line before and after current lines. + set lines [linsert $lines 0 ""] + lappend lines "" + + # Convert every line to a regexp. Also log the expected output + # for debugging. + set lines_re {} + verbose -log -- "Expected message format:" + foreach l $lines { + verbose -log -- "$l" + lappend lines_re [string_to_regexp $l] + } + + # Join the regexp together. + return [multi_line {*}$lines_re] +} + +# Tell GDB to start with a terminal width of WIDTH, then start GDB. +# Check that the hint text is formatted correctly. +proc_with_prefix test_for_hint_with_width { width load_exec } { + global GDBFLAGS + + save_vars { GDBFLAGS } { + append GDBFLAGS " -eiex \"set width $width\" -eiex \"set height 0\"" + if { $load_exec } { + append GDBFLAGS " \"$::binfile\"" + } + gdb_exit + gdb_spawn + } + + set hint_re [build_hint_re $width] + + if { $load_exec } { + append hint_re "\r\nReading symbols from [string_to_regexp $::binfile]\\.\\.\\." + } + + gdb_test "" $hint_re \ + "check for hint with width $width" +} + +save_vars { INTERNAL_GDBFLAGS } { + set INTERNAL_GDBFLAGS [string map {"-q" ""} $INTERNAL_GDBFLAGS] + + foreach_with_prefix load_exec { false true } { + + # Width 0 actually means unlimited. The other small sizes + # check that GDB doesn't trigger undefined behaviour by trying + # to create strings with a negative length. + for { set width 0 } { $width <= 5 } { incr width } { + test_for_hint_with_width $width $load_exec + } + + # These widths cover the point where we transition from using + # an unboxed hint to a boxed hint. + for { set width 45 } { $width <= 55 } { incr width } { + test_for_hint_with_width $width $load_exec + } + + # Very large widths are treated like a width of 80. + test_for_hint_with_width 100 $load_exec + } +} diff --git a/gdb/top.c b/gdb/top.c index 1aefe74b394..10366f98df1 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -1421,6 +1421,8 @@ print_gdb_hints (struct ui_file *stream) if (80 < width) width = 80; + gdb_assert (width > 0); + std::string docs_url = "http://www.gnu.org/software/gdb/documentation/"; std::array styled_msg { string_file (true), @@ -1435,20 +1437,29 @@ print_gdb_hints (struct ui_file *stream) gdb_printf (&styled_msg[2], _("For help, type \"%ps\"."), styled_string (command_style.style (), "help")); gdb_printf (&styled_msg[3], - _("Type \"%ps\" to search for commands related to "), + _("Type \"%ps\" to search for commands related to ."), styled_string (command_style.style (), "apropos ")); /* If there isn't enough space to display the longest URL in a boxed - style, use the simple styling of a singular visual break. The longest - URL is used because the other messages may be broken into multiple - lines, but URLs can't. */ - if (width - 3 <= docs_url.length ()) + style, then don't use the box, the terminal will break the output + where needed. The longest URL is used because the other messages may + be broken into multiple lines, but URLs can't. + + The ' + 1' after the URL accounts for the period that is placed after + the URL. + + The '+ 4' accounts for the box and inner white space. We add the 4 to + the string length rather than subtract from the width as the width + could be less than 4, and we want to avoid wrap around. */ + if (width < docs_url.length () + 1 + 4) { for (string_file &msg : styled_msg) gdb_printf (stream, "%s\n", msg.c_str ()); } else { + gdb_assert (width > 4); + std::string sep (width - 2, '-'); if (emojis_ok ()) -- 2.47.1