From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id cXAGAJPlMWlhfBkAWB0awg (envelope-from ) for ; Thu, 04 Dec 2025 14:48:35 -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=YhxcHTXs; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id EF74B1E08D; Thu, 04 Dec 2025 14:48:34 -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 A43791E08D for ; Thu, 04 Dec 2025 14:48:33 -0500 (EST) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3B5424B1A2BB for ; Thu, 4 Dec 2025 19:48:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3B5424B1A2BB 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=YhxcHTXs Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 02D374BC7EE0 for ; Thu, 4 Dec 2025 19:47:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 02D374BC7EE0 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 02D374BC7EE0 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1764877658; cv=none; b=qKE5vO5nEbAiR1VeBa/ynKwseE9fUDrR3KcUrOBj0o+Ui5NlAusGUDRkRcyqeBOran7V34FXR8fJGnPBhnG5D11nz7pbnWmSOUetCHt1YBE4uX/lO9atFMbpVh8mPL8RfcU8h7yBmhJrh3G2gFXR4ikV4Hq4YvobBsglr6L36fI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1764877658; c=relaxed/simple; bh=FMOJKbGY+FXWMQ7qj9R7u22bXjJIPf2wyPAYJqkAV0w=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=RiNOuP/9qUMUhTKuIjFsFz3hwlrVKqIUxFkRB/ak+tWMU/ewukzUUD7XOu1hAkHY8xWAoq2Yiq61TXJFZb/MxTruTsovxoQtaLs9BNLc/sJUknfaAwoW+Zq4MhxtAgwJN4AQhwXa+vwrXQ01rp+vv66F1yqTFzZyrbo4MhcDKWE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 02D374BC7EE0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1764877657; 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=er8pj2B/2KhZOG088yTbG4Nia7JWtjxuGJHR1My94Ro=; b=YhxcHTXsi/Ae5oF4EPSzwgV0pWMMY6KzJlNB7F1uOQs6CdebTtx3n0WFahdXNbqfLxbWBb ato4+D3soyPDJN/AQTmj04SwggHW8O7r2DjOHZn5SCse9XCuC4nJn4lQ0HC9bpWFMBvozX mLUq7QpeLTPZOrKyV2Xfof/Gbd2KqR4= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-385-H5CUgaxJOhefzrmJM1FuxA-1; Thu, 04 Dec 2025 14:47:35 -0500 X-MC-Unique: H5CUgaxJOhefzrmJM1FuxA-1 X-Mimecast-MFC-AGG-ID: H5CUgaxJOhefzrmJM1FuxA_1764877655 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-42b2f79759bso865349f8f.2 for ; Thu, 04 Dec 2025 11:47:35 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764877654; x=1765482454; 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=er8pj2B/2KhZOG088yTbG4Nia7JWtjxuGJHR1My94Ro=; b=LtsXr8lOIrsCG4QnMw4wKUl2XyQWWGg7DPOfNhknF5l/jO/fYTa8g0QeDSh0ubIpev h4ifk5KnOp2bxO+qGBf9mO9opz8uS4w8vr6OiDuJElsSIuisR80NO7omFsUqWpvrzDYx tH/ZPpotMpjM9t4c94UFuNnkjW+HlKzcG5cA0jin7pKGDNtsKa1QFcw7ocfVyrR2JgmB ulCZlI4U+A0gcZASofDbe1skYxzl+4UaOwpccvXkjN3yggYmTmn1f841qgJkGnEFcxiG zfvqSnonUW4jLnr/9R6JeADwzgVuAJmMsDMrHsWJzSv6rp5UVZhxEd4UIfudF4UNfXOg JLmg== X-Gm-Message-State: AOJu0YzT7ZmC/79CTFbNxGMLUmbooEMqEw4djO0mS33ci2oV1d31Mh4a hn96+V1SbHURIFA4mxulkbqtU+qRCmlVdLHwFvigU7lOcN9p9VdG0VhQjppBXii6ikoV3TcHjox 2/ciMBjlwYyNfvZrPXTVoKdHOCSijDID1HFc8feenbjhTw/UH8Cu1bzhZrQiMusWEFtfwOAABWn 8ffY6pQzN4iLCJ3/as3DhhiWPqij7RRGmXToXf7xjlFrvopCA= X-Gm-Gg: ASbGncvS2I4lnsSX5FaVvCTBhwxpdYqNhIqzmGfD5Y0CSUkh2Zgtv9dX+R5dE0ZJUqN QUX1IONXLe4aTOKjbvx0l7p6AJrQ1yMM5f6H8rXcs75p8TDjiOFHULfij67mcDWzKRgeK5AOyqp VxT9s0htSr3lbf3DGvTGWlaNJqOQiQSBqT9ZL3JGp5DdB6T+63Iy/rcUa8Wss5beRcz4ukqWCl3 oBGpu0Z6KKBvXeIZmsJp5Y66lFK/A8iw4P26ueZwOzGzvs+26jpCPqhDEGOZUc74Bq8YrOTz8af nSntroeyPS/dhYG4YSODwDPyKiSZrnMSKaxj6FyC6nE/EULuY019ZzRgGB33TxJwm5DXqTCuyUX J5f76 X-Received: by 2002:a05:600c:5491:b0:45d:5c71:769a with SMTP id 5b1f17b1804b1-4792af3e01bmr70675545e9.26.1764877654081; Thu, 04 Dec 2025 11:47:34 -0800 (PST) X-Google-Smtp-Source: AGHT+IGQPty8cpudWzlS+UveLqNYE7F9RDb1XlSyuQD0KbJGI/MJ5sWpQTS3NdzlWdQkN81MX65DRQ== X-Received: by 2002:a05:600c:5491:b0:45d:5c71:769a with SMTP id 5b1f17b1804b1-4792af3e01bmr70675335e9.26.1764877653473; Thu, 04 Dec 2025 11:47:33 -0800 (PST) Received: from localhost ([31.111.84.207]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4792b150878sm54847775e9.3.2025.12.04.11.47.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Dec 2025 11:47:33 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , Guinevere Larsen Subject: [PATCH 2/2] gdb: fix crashes and weird output from new boxed hint text Date: Thu, 4 Dec 2025 19:47:25 +0000 Message-ID: <4b43725ed933401645977e62651334d7510390a5.1764877519.git.aburgess@redhat.com> 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: _52nJYUy4Dws8ybQNf_HgWhH-EKz_7RRswLz1-M6VDY_1764877655 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. Reviewed-By: Guinevere Larsen --- 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