From patchwork Thu Jun 1 09:27:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 70440 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 47CCA385771D for ; Thu, 1 Jun 2023 09:29:02 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 47CCA385771D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1685611742; bh=8i0MQeYWdJkz2adWvsDAHblLrdWKqrmnbwWV2FHf2UM=; 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=GNPD8xDUCal8uXvIsi0bZRs3jGcR9OahqV7zZEz7w4j9xaiQ7ln81VZF2iYPtLoWM TQaB/8A7HWELoC73Bl7PNdbPKjzhPUsRQWjDAuTRIvZS+LjJoxyMiu3voU8Cgw0gma onY30LlK8USoJ80h0CMa7StJSSE6D9+nTvz1NHsI= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 04F643858C41 for ; Thu, 1 Jun 2023 09:28:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 04F643858C41 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-425-Qc3XZzw7PqOeHWVqCMZYzQ-1; Thu, 01 Jun 2023 05:28:03 -0400 X-MC-Unique: Qc3XZzw7PqOeHWVqCMZYzQ-1 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-30793c16c78so832496f8f.3 for ; Thu, 01 Jun 2023 02:28:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685611682; x=1688203682; 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=8i0MQeYWdJkz2adWvsDAHblLrdWKqrmnbwWV2FHf2UM=; b=cvEcadUEF8OGbIkMVtOR4MAnUPpVm3byBU+U2fdRvWKpEcJZ22Trpkv9dZu9UWvo76 KcGHkvtNXO+NXBgLV0KDkUw8o5v+DDYBsbVacu6ZQqkdy0wyM7rfyPVGT7UF5TXlrpum e6WI+SA7XqKMwv4eHXQgYoiM43D59nXG3ybyJDu7Xi5E2CFcmhQEwKsy7rZgOpUyzJyn NJtdIfdP3Ox21guIdSkUXicDm4FQAr081NKA3E4gLSvVc2gVTjTvFtBlctGMggXYseF1 dyoVRCDPdxKxz87q/gP4y1m4xtKPPe8Dt3WVhln3TQPlUvl0Uj6/FS77MGgai3WApYtd zKnA== X-Gm-Message-State: AC+VfDy+Du280yerLZpgCXQYu8ohtx4SFemMMWmVYuMdYtsMjQ5b+JZ2 AVVByzG01q5XirHiHHeL5rnwaNiATs7kVsv3QLyj0T8CkaKK2lCcsCAC0kg3lYQKoKeI15buSud 0iX4jBnCB3ceG6Wn50J2epR2LfMARb8JnE4HDiRDLPyZlXHJmq7vqsWCCc0W+LgGiK1eYBKSeeM /Wi1DA8Q== X-Received: by 2002:adf:f507:0:b0:30a:e9a9:a4f8 with SMTP id q7-20020adff507000000b0030ae9a9a4f8mr1831589wro.38.1685611682102; Thu, 01 Jun 2023 02:28:02 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4/mJJY1Dbp8WtvXMWJrnByWU5AAbpfIniZfW1WmKX3txpLaMEF5PK+A+mdilwb7mkVIf/FxA== X-Received: by 2002:adf:f507:0:b0:30a:e9a9:a4f8 with SMTP id q7-20020adff507000000b0030ae9a9a4f8mr1831574wro.38.1685611681740; Thu, 01 Jun 2023 02:28:01 -0700 (PDT) Received: from localhost (11.72.115.87.dyn.plus.net. [87.115.72.11]) by smtp.gmail.com with ESMTPSA id h17-20020a5d4fd1000000b003095bd71159sm9770306wrw.7.2023.06.01.02.28.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Jun 2023 02:28:01 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Simon Marchi , Andrew Burgess Subject: [PATCH 1/4] gdb: fix printf of wchar_t early in a gdb session Date: Thu, 1 Jun 2023 10:27:50 +0100 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Given this test program: #include const wchar_t wide_str[] = L"wide string"; int main (void) { return 0; } I observed this GDB behaviour: $ gdb -q /tmp/printf-wchar_t Reading symbols from /tmp/printf-wchar_t... (gdb) start Temporary breakpoint 1 at 0x40110a: file /tmp/printf-wchar_t.c, line 8. Starting program: /tmp/printf-wchar_t Temporary breakpoint 1, main () at /tmp/printf-wchar_t.c:8 25 return 0; (gdb) printf "%ls\n", wide_str (gdb) Notice that the printf results in a blank line rather than the expected 'wide string' output. I tracked the problem down to printf_wide_c_string (in printcmd.c), in this function we do this: struct type *wctype = lookup_typename (current_language, "wchar_t", NULL, 0); int wcwidth = wctype->length (); the problem here is that 'wchar_t' is a typedef. If we look at the comment on type::length() we see this: /* Note that if thistype is a TYPEDEF type, you have to call check_typedef. But check_typedef does set the TYPE_LENGTH of the TYPEDEF type, so you only have to call check_typedef once. Since value::allocate calls check_typedef, X->type ()->length () is safe. */ What this means is that after calling lookup_typename we should call check_typedef in order to ensure that the length of the typedef has been setup correctly. We are not doing this in printf_wide_c_string, and so wcwidth is incorrectly calculated as 0. This is what leads GDB to print an empty string. We can see in c_string_operation::evaluate (in c-lang.c) an example of calling check_typedef specifically to fix this exact issue. Initially I did fix this problem by adding a check_typedef call into printf_wide_c_string, but then I figured why not move the check_typedef call up into lookup_typename itself, that feels like it should be harmless when looking up a non-typedef type, but will avoid bugs like this when looking up a typedef. So that's what I did. I can then remove the extra check_typedef call from c-lang.c, I don't see any other places where we had extra check_typedef calls. This doesn't mean we definitely had bugs -- so long as we never checked the length, or, if we knew that check_typedef had already been called, then we would be fine. I don't see any test regressions after this change, and my new test case is now passing. Reviewed-By: Tom Tromey --- gdb/c-lang.c | 3 --- gdb/gdbtypes.c | 11 ++++++---- gdb/gdbtypes.h | 14 ++++++++++-- gdb/testsuite/gdb.base/printf-wchar_t.c | 26 +++++++++++++++++++++++ gdb/testsuite/gdb.base/printf-wchar_t.exp | 26 +++++++++++++++++++++++ 5 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 gdb/testsuite/gdb.base/printf-wchar_t.c create mode 100644 gdb/testsuite/gdb.base/printf-wchar_t.exp diff --git a/gdb/c-lang.c b/gdb/c-lang.c index 484f81e455b..677e76ee71b 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -615,9 +615,6 @@ c_string_operation::evaluate (struct type *expect_type, internal_error (_("unhandled c_string_type")); } - /* Ensure TYPE_LENGTH is valid for TYPE. */ - check_typedef (type); - /* If the caller expects an array of some integral type, satisfy them. If something odder is expected, rely on the caller to cast. */ diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 10e585066f7..9eecf357152 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1648,9 +1648,7 @@ type_name_or_error (struct type *type) objfile ? objfile_name (objfile) : ""); } -/* Lookup a typedef or primitive type named NAME, visible in lexical - block BLOCK. If NOERR is nonzero, return zero if NAME is not - suitably defined. */ +/* See gdbtypes.h. */ struct type * lookup_typename (const struct language_defn *language, @@ -1662,7 +1660,12 @@ lookup_typename (const struct language_defn *language, sym = lookup_symbol_in_language (name, block, VAR_DOMAIN, language->la_language, NULL).symbol; if (sym != NULL && sym->aclass () == LOC_TYPEDEF) - return sym->type (); + { + struct type *type = sym->type (); + /* Ensure the length of TYPE is valid. */ + check_typedef (type); + return type; + } if (noerr) return NULL; diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 319a7731bca..f56de4544b5 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -2586,8 +2586,18 @@ extern void check_stub_method_group (struct type *, int); extern char *gdb_mangle_name (struct type *, int, int); -extern struct type *lookup_typename (const struct language_defn *, - const char *, const struct block *, int); +/* Lookup a typedef or primitive type named NAME, visible in lexical block + BLOCK. If NOERR is nonzero, return zero if NAME is not suitably + defined. + + If this function finds a suitable type then check_typedef is called on + the type, this ensures that if the type being returned is a typedef + then the length of the type will be correct. The original typedef will + still be returned, not the result of calling check_typedef. */ + +extern struct type *lookup_typename (const struct language_defn *language, + const char *name, + const struct block *block, int noerr); extern struct type *lookup_template_type (const char *, struct type *, const struct block *); diff --git a/gdb/testsuite/gdb.base/printf-wchar_t.c b/gdb/testsuite/gdb.base/printf-wchar_t.c new file mode 100644 index 00000000000..4d13fd3c961 --- /dev/null +++ b/gdb/testsuite/gdb.base/printf-wchar_t.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2023 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 . */ + +#include + +const wchar_t wide_str[] = L"wide string"; + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/printf-wchar_t.exp b/gdb/testsuite/gdb.base/printf-wchar_t.exp new file mode 100644 index 00000000000..85c6edf292c --- /dev/null +++ b/gdb/testsuite/gdb.base/printf-wchar_t.exp @@ -0,0 +1,26 @@ +# Copyright 2023 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 . + +standard_testfile + +if {[prepare_for_testing "failed to prepare" $testfile $srcfile]} { + return -1 +} + +if {![runto_main]} { + return -1 +} + +gdb_test {printf "%ls\n", wide_str} "^wide string" From patchwork Thu Jun 1 09:27:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 70438 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 5B0853857739 for ; Thu, 1 Jun 2023 09:28:35 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5B0853857739 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1685611715; bh=U+wjB5kfHv92vGXbc+EDlVvgLFohzLbpVXu7qzssSK8=; 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=DmYd1bHGvVGR4aT8SFPMhamQovnPnjmoalEklBNRqFb6/TPmvY/BTdbtVTNQBAt2O YNQN9KpZCYb/qeWpqlJUL2XjgdOyXje1FcnO29MwJoUBcsMn/DsDRkTeVX3SQ6OBaf jKpGrkIqTEffcsdMwIS6RplRhSgQ2JIbeKjYE50A= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 57DC53857707 for ; Thu, 1 Jun 2023 09:28:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 57DC53857707 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-39-x_RD9Dg6OCS36qxJezPqkQ-1; Thu, 01 Jun 2023 05:28:04 -0400 X-MC-Unique: x_RD9Dg6OCS36qxJezPqkQ-1 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-3f6089a9689so4343305e9.1 for ; Thu, 01 Jun 2023 02:28:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685611683; x=1688203683; 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=U+wjB5kfHv92vGXbc+EDlVvgLFohzLbpVXu7qzssSK8=; b=Hw/PUtAFo2bQHe6KGWROimo8qcUqsmZKaMZ31wMUgVA4G/NL0VVD1FI7ZZWI2Rw0Nm Tj8dBKpmO+OCfa8WW+AMBCH0o0obmBWyeQ+TwWy2AfcRnKwtkPyDiO34cB5XEKmUzftR 8aS82oy7kbEzo/f4ZxvpaG0SpKm2M7V/leiLKr6PSiIA/Jlztb3lBP4WBFVQvKn2e6Tm m/dmLbIVZKVA9k/MdKw2o8mXDxmMmUxcq3gnG/mL2QdwWh+0qGx/RzgAx9+Ag+k2YHWu xWcroOZ4I1sivprAj3kF7eUfqsIB6NgsY16UtGUoMELTO62eJ9jD1zYOtbT49foMVV0+ ZXqA== X-Gm-Message-State: AC+VfDwH+pMBtGbEdKj5rDcoLj2A9XoY4U9w2THiliTiFvNmEMEPM+7p 3ZoEqPmzG8F54OGT7J/cofv4+I/Mh6zUeoRBlWMcgVDxLl8+3Cu01sfoSv9iX3WCam/CMx2ZPu1 +2Pcr52ButhYjrQdR5LFJ7PH0u5BX2k8FeiRBT4o1bjhtML2AkIffRsNATr3KOynGylaI8Fz/lV hGBY+GeA== X-Received: by 2002:a7b:ce0a:0:b0:3f4:d18f:b2fb with SMTP id m10-20020a7bce0a000000b003f4d18fb2fbmr1374114wmc.8.1685611683482; Thu, 01 Jun 2023 02:28:03 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ73KXcvloiPMJ/bRpvWAzbk8sozc7n/YLERaoY9hOR67CPaMzK0q+eJn3R8dncW5QEzJDXcHA== X-Received: by 2002:a7b:ce0a:0:b0:3f4:d18f:b2fb with SMTP id m10-20020a7bce0a000000b003f4d18fb2fbmr1374096wmc.8.1685611683206; Thu, 01 Jun 2023 02:28:03 -0700 (PDT) Received: from localhost (11.72.115.87.dyn.plus.net. [87.115.72.11]) by smtp.gmail.com with ESMTPSA id t4-20020a5d5344000000b00307acec258esm9632973wrv.3.2023.06.01.02.28.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Jun 2023 02:28:02 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Simon Marchi , Andrew Burgess Subject: [PATCH 2/4] gdb: remove two uses of alloca from printcmd.c Date: Thu, 1 Jun 2023 10:27:51 +0100 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Remove a couple of uses of alloca from printcmd.c, and replace them with gdb::byte_vector. An earlier variant of this patch was proposed in this thread: https://inbox.sourceware.org/gdb-patches/cover.1677533215.git.aburgess@redhat.com/ however, there was push back on that thread due to it adding extra dynamic allocation, i.e. moving the memory buffers off the stack on to the heap. However, of all the patches originally proposed, I think in these two cases moving off the stack is the correct thing to do. Unlike all the other patches in the original series, where the data being read was (mostly) small in size, a register, or a couple of registers, in this case we are reading an arbitrary string from the inferior. This could be any size, and so should not be placed on the stack. So in this commit I replace the use of alloca with std::byte_vector and simplify the logic a little (I think) to take advantage of the ability of std::byte_vector to dynamically grow in size. Of course, really, we should probably be checking the max-value-size setting as we load the string to stop GDB crashing if a corrupted inferior causes GDB to try read a stupidly large amount of memory... but I'm leaving that for a follow on patch. There should be no user visible changes after this commit. --- gdb/printcmd.c | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/gdb/printcmd.c b/gdb/printcmd.c index f9517e6e086..6f8a7f1420a 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -2447,7 +2447,7 @@ static void printf_c_string (struct ui_file *stream, const char *format, struct value *value) { - const gdb_byte *str; + gdb::byte_vector str; if (((value->type ()->code () != TYPE_CODE_PTR && value->lval () == lval_internalvar) || value->type ()->code () == TYPE_CODE_ARRAY) @@ -2459,11 +2459,10 @@ printf_c_string (struct ui_file *stream, const char *format, character. This protects against corrupted C-style strings that lack the terminating null char. It also allows Ada-style strings (not null terminated) to be printed without problems. */ - gdb_byte *tem_str = (gdb_byte *) alloca (len + 1); + str.resize (len + 1); - memcpy (tem_str, value->contents ().data (), len); - tem_str [len] = 0; - str = tem_str; + memcpy (str.data (), value->contents ().data (), len); + str [len] = 0; } else { @@ -2478,31 +2477,30 @@ printf_c_string (struct ui_file *stream, const char *format, return; } - /* This is a %s argument. Find the length of the string. */ - size_t len; - - for (len = 0;; len++) + /* This is a %s argument. Build the string in STR which is + currently empty. */ + gdb_assert (str.size () == 0); + for (size_t len = 0;; len++) { gdb_byte c; QUIT; read_memory (tem + len, &c, 1); + str.push_back (c); if (c == 0) break; } - /* Copy the string contents into a string inside GDB. */ - gdb_byte *tem_str = (gdb_byte *) alloca (len + 1); - - if (len != 0) - read_memory (tem, tem_str, len); - tem_str[len] = 0; - str = tem_str; + /* We will have passed through the above loop at least once, and will + only exit the loop when we have pushed a zero byte onto the end of + STR. */ + gdb_assert (str.size () > 0); + gdb_assert (str.back () == 0); } DIAGNOSTIC_PUSH DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL - gdb_printf (stream, format, (char *) str); + gdb_printf (stream, format, (char *) str.data ()); DIAGNOSTIC_POP } @@ -2521,6 +2519,7 @@ printf_wide_c_string (struct ui_file *stream, const char *format, struct type *wctype = lookup_typename (current_language, "wchar_t", NULL, 0); int wcwidth = wctype->length (); + gdb::optional tem_str; if (value->lval () == lval_internalvar && c_is_string_type_p (value->type ())) @@ -2543,23 +2542,19 @@ printf_wide_c_string (struct ui_file *stream, const char *format, /* This is a %s argument. Find the length of the string. */ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - gdb_byte *buf = (gdb_byte *) alloca (wcwidth); + tem_str.emplace (); for (len = 0;; len += wcwidth) { QUIT; - read_memory (tem + len, buf, wcwidth); - if (extract_unsigned_integer (buf, wcwidth, byte_order) == 0) + tem_str->resize (tem_str->size () + wcwidth); + gdb_byte *dst = tem_str->data () + len; + read_memory (tem + len, dst, wcwidth); + if (extract_unsigned_integer (dst, wcwidth, byte_order) == 0) break; } - /* Copy the string contents into a string inside GDB. */ - gdb_byte *tem_str = (gdb_byte *) alloca (len + wcwidth); - - if (len != 0) - read_memory (tem, tem_str, len); - memset (&tem_str[len], 0, wcwidth); - str = tem_str; + str = tem_str->data (); } auto_obstack output; From patchwork Thu Jun 1 09:27:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 70439 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 C3BF93856632 for ; Thu, 1 Jun 2023 09:28:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C3BF93856632 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1685611731; bh=eTFI7WAByLniVt2XIx26IN6AGBqFnpUCCL0yDNsjJKs=; 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=jI7wxQhq5ZLEG0h6UEBhfj5mnJRBPeyyYdbtXCCH4LrvFxuAqGE2Le2dLTzjq+7/y slkKIR1DDihE1GmIHDZKt+CAraUby2UYU2fF8UlcQZrR6LyuN+x+fRUau8ogpS/sy7 HisnjFGFdObR7lHMz+HccdRRfY5+brN+I2bv1Rb0= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 78E383858291 for ; Thu, 1 Jun 2023 09:28:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 78E383858291 Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-490-mMpbd-YIMkacnxpwXSqWIw-1; Thu, 01 Jun 2023 05:28:06 -0400 X-MC-Unique: mMpbd-YIMkacnxpwXSqWIw-1 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-3f604260ef3so11778885e9.3 for ; Thu, 01 Jun 2023 02:28:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685611685; x=1688203685; 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=eTFI7WAByLniVt2XIx26IN6AGBqFnpUCCL0yDNsjJKs=; b=kJefwMu9JY8IF91uNp510NbxLmLgMYZ3O9goZpjq0LV7b+OaYxZ2lqf6xKHspAn8Cg 80UTo/kJCB8hvjhItBLcOVbrC+7rzbtXjP5yeClIHW4drUukySqxa8AI1TDIAyuvcl76 afK1oR3vtmPyISLI26qWajPZ9p/12F2SFq4ri6kqNDTC7gwK7oL1NQECwWrRVoAMFEV9 HiR+Fz3zG5ErXbRwlxquNjIlzRPk0HW+KprUK4Ob4Iiii6JkcfpC5NNblz/x1+tJBkx4 ZMg9JHawoaxujO73TuvF2n7L47ELswSLQ5n9IvkTh82l3xOsc8Rx0QDQROt1buZnXEhg 6J5g== X-Gm-Message-State: AC+VfDy8u736kUgTE9GfMfDMcMH+GblMluOq2hLR1eqbZKqk5dfNx0t+ pY/2bjkxqJLNR1t1/uJvhsJa5HgozSeaK+JaINJup5GTQgizry3MCQYm9wJK1CB/JXwE+JH76e6 ugghRswc9+qosAMiljTFGreZYs81RJM3qpE1BaPAXcVmbAhI5BJZ4aT4qrtWRzO5iGrqwfayyB2 94JsmL6Q== X-Received: by 2002:a05:600c:a391:b0:3f6:e79:3a8e with SMTP id hn17-20020a05600ca39100b003f60e793a8emr1878709wmb.12.1685611684952; Thu, 01 Jun 2023 02:28:04 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7nhmiBcpvZLKk8WgF+G48glfVrM7AGZxZdeggomiHXWI2dkT3mYcLS2kB+ZmJRay8BBlgrCw== X-Received: by 2002:a05:600c:a391:b0:3f6:e79:3a8e with SMTP id hn17-20020a05600ca39100b003f60e793a8emr1878695wmb.12.1685611684679; Thu, 01 Jun 2023 02:28:04 -0700 (PDT) Received: from localhost (11.72.115.87.dyn.plus.net. [87.115.72.11]) by smtp.gmail.com with ESMTPSA id p17-20020a05600c205100b003f604ca479esm1672312wmg.3.2023.06.01.02.28.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Jun 2023 02:28:04 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Simon Marchi , Andrew Burgess Subject: [PATCH 3/4] gdb: remove last alloca call from printcmd.c Date: Thu, 1 Jun 2023 10:27:52 +0100 Message-Id: <35bd5c487f6cda38f1668a3ad815b7d382113a6f.1685611213.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This commit removes the last alloca call from printcmd.c. This is similar to the patches I originally posted here: https://inbox.sourceware.org/gdb-patches/cover.1677533215.git.aburgess@redhat.com/ However, this change was not included in that original series. The original series received push back because it was thought that replacing alloca with a C++ container type would introduce unnecessary malloc/free overhead. However, in this case we are building a string, and (at least for GCC), the std::string type has a small string optimisation, where small strings are stored on the stack. And in this case we are building what will usually be a very small string, we're just constructing a printf format specifier for a hex value, so it'll be something like '%#x' -- though it could also have a width in there too -- but still, it should normally fit within GCCs small string buffer. So, in this commit, I propose replacing the use of alloca with a std::string. This shouldn't result (normally) in any additional malloc or free calls, so should be similar in performance to the original approach. There should be no user visible differences after this commit. --- gdb/printcmd.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 6f8a7f1420a..61b009fb7f2 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -2653,62 +2653,58 @@ printf_pointer (struct ui_file *stream, const char *format, modifier for %p is a width; extract that, and then handle %p as glibc would: %#x or a literal "(nil)". */ - const char *p; - char *fmt, *fmt_p; #ifdef PRINTF_HAS_LONG_LONG long long val = value_as_long (value); #else long val = value_as_long (value); #endif - fmt = (char *) alloca (strlen (format) + 5); + /* Build the new output format in FMT. */ + std::string fmt; /* Copy up to the leading %. */ - p = format; - fmt_p = fmt; + const char *p = format; while (*p) { int is_percent = (*p == '%'); - *fmt_p++ = *p++; + fmt.push_back (*p++); if (is_percent) { if (*p == '%') - *fmt_p++ = *p++; + fmt.push_back (*p++); else break; } } if (val != 0) - *fmt_p++ = '#'; + fmt.push_back ('#'); /* Copy any width or flags. Only the "-" flag is valid for pointers -- see the format_pieces constructor. */ while (*p == '-' || (*p >= '0' && *p < '9')) - *fmt_p++ = *p++; + fmt.push_back (*p++); gdb_assert (*p == 'p' && *(p + 1) == '\0'); if (val != 0) { #ifdef PRINTF_HAS_LONG_LONG - *fmt_p++ = 'l'; + fmt.push_back ('l'); #endif - *fmt_p++ = 'l'; - *fmt_p++ = 'x'; - *fmt_p++ = '\0'; + fmt.push_back ('l'); + fmt.push_back ('x'); DIAGNOSTIC_PUSH DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL - gdb_printf (stream, fmt, val); + gdb_printf (stream, fmt.c_str (), val); DIAGNOSTIC_POP } else { - *fmt_p++ = 's'; - *fmt_p++ = '\0'; + fmt.push_back ('s'); DIAGNOSTIC_PUSH DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL - gdb_printf (stream, fmt, "(nil)"); + gdb_printf (stream, fmt.c_str (), "(nil)"); DIAGNOSTIC_POP } } From patchwork Thu Jun 1 09:27:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 70441 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 649563858C30 for ; Thu, 1 Jun 2023 09:29:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 649563858C30 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1685611747; bh=MApuv9qs+Vv33268UIrR35Iy2H2R8Tam6MEYG2OmfFA=; 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=acCVJkilWesXIz1ra12xXH4bhSndFx7lpXWsN/iDu+9eDGX0DaRhrw96E2kjAWVq1 LhgwqgMHwGR8/OkWlckeCjbZJRt9Cqkx8VLAUKficHPstbPUj/QD8ISNeU0pA05XMf 09k0T5oFv4n5rHxkGzEYmilmvO71z4GpMYZ0L5hU= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id D83713857738 for ; Thu, 1 Jun 2023 09:28:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D83713857738 Received: from mail-lj1-f198.google.com (mail-lj1-f198.google.com [209.85.208.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-180-XhrBoKAMNT2CAyAp-ba4Wg-1; Thu, 01 Jun 2023 05:28:08 -0400 X-MC-Unique: XhrBoKAMNT2CAyAp-ba4Wg-1 Received: by mail-lj1-f198.google.com with SMTP id 38308e7fff4ca-2af1a18584bso4830511fa.2 for ; Thu, 01 Jun 2023 02:28:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685611687; x=1688203687; 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=MApuv9qs+Vv33268UIrR35Iy2H2R8Tam6MEYG2OmfFA=; b=ZR7dRXqJadrW6KPjuf8tUJ06KJoYXoSueluqDQukA5KEOR00kWm+Poee90wN0H5eGk pgVgxhUq/z219oLiZIGtOaln4A3F/WHgRN9yC2zXkBdJKSYsPqI7cK+QShPBtuGP/2Q0 ino+9Y4QOqThOdbkyLBGucTnElBMF/fx8xiNCAcrCn9G5Jgo4nhdXmNqgEjNCYdef9Mc R3WlcU6jSkssUSEm6O2H12cVMmSQ5h0/8HeteT/O2zUz8NGl9svHBuNCJF/mEGfXCvfW O0gZhOph2XUdmycYuJdOOh5IJWztbGm4Ov+n6mgwTnTSx9aBA5GgzrBMpjXYvE4Lq+YG 1i/w== X-Gm-Message-State: AC+VfDxNKyejFZFA3s1dk7ejNKQDuCNYHN11rI//7PlAJ+u/E1m0Y82I wjeiP3K+DQjfq7gQZFmZWEkF6iyrgDBnq+jRGbzM0XHj/Yh+CXD9pZ6pAHkuvYp1Co4VaEAG0zN PpVNYnA6vus4rlIm9eRP4lk6ViPCsMxdEhfCz32NXwI9ZkcZMYns8v5vE0e3IpyYwB5tj5DcXuQ yRtaYlMw== X-Received: by 2002:a2e:9bd9:0:b0:2a9:f94f:d304 with SMTP id w25-20020a2e9bd9000000b002a9f94fd304mr4194934ljj.19.1685611686707; Thu, 01 Jun 2023 02:28:06 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5AFfoQDVzCpx6cupOz6/gYQ+z+AxpNJtzGpeDA+mTboyBSIJ9Xk9vK544EcCVegpINg4ndeg== X-Received: by 2002:a2e:9bd9:0:b0:2a9:f94f:d304 with SMTP id w25-20020a2e9bd9000000b002a9f94fd304mr4194914ljj.19.1685611686172; Thu, 01 Jun 2023 02:28:06 -0700 (PDT) Received: from localhost (11.72.115.87.dyn.plus.net. [87.115.72.11]) by smtp.gmail.com with ESMTPSA id 9-20020a05600c028900b003f60482024fsm1653013wmk.30.2023.06.01.02.28.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Jun 2023 02:28:05 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Simon Marchi , Andrew Burgess Subject: [PATCH 4/4] gdb: check max-value-size when reading strings for printf Date: Thu, 1 Jun 2023 10:27:53 +0100 Message-Id: <3166d8c1916f3d92550c436cf47c70ceece0e0ea.1685611213.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" I noticed that the printf code for strings, printf_c_string and printf_wide_c_string, don't take max-value-size into account, but do load a complete string from the inferior into a GDB buffer. As such it would be possible for an badly behaved inferior to cause GDB to try and allocate an excessively large buffer, potentially crashing GDB, or at least causing GDB to swap lots, which isn't great. We already have a setting to protect against this sort of thing, the 'max-value-size'. So this commit updates the two function mentioned above to check the max-value-size and give an error if the max-value-size is exceeded. If the max-value-size is exceeded, I chose to continue reading inferior memory to figure out how long the string actually is, we just don't store the results. The benefit of this is that when we give the user an error we can tell the user how big the string actually is, which would allow them to correctly adjust max-value-size, if that's what they choose to do. The default for max-value-size is 64k so there should be no user visible changes after this commit, unless the user was previously printing very large strings. If that is the case then the user will now need to increase max-value-size. --- gdb/printcmd.c | 39 ++++++++++++++++++++--- gdb/testsuite/gdb.base/printcmds.c | 2 ++ gdb/testsuite/gdb.base/printcmds.exp | 5 +++ gdb/testsuite/gdb.base/printf-wchar_t.c | 2 ++ gdb/testsuite/gdb.base/printf-wchar_t.exp | 6 ++++ gdb/testsuite/lib/gdb.exp | 30 +++++++++++++++++ gdb/value.c | 10 +++++- gdb/value.h | 5 +++ 8 files changed, 94 insertions(+), 5 deletions(-) diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 61b009fb7f2..4bfdaa2c7d7 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -2480,17 +2480,24 @@ printf_c_string (struct ui_file *stream, const char *format, /* This is a %s argument. Build the string in STR which is currently empty. */ gdb_assert (str.size () == 0); - for (size_t len = 0;; len++) + size_t len; + for (len = 0;; len++) { gdb_byte c; QUIT; + read_memory (tem + len, &c, 1); - str.push_back (c); + if (!exceeds_max_value_size (len + 1)) + str.push_back (c); if (c == 0) break; } + if (exceeds_max_value_size (len + 1)) + error (_("printed string requires %s bytes, which is more than " + "max-value-size"), plongest (len + 1)); + /* We will have passed through the above loop at least once, and will only exit the loop when we have pushed a zero byte onto the end of STR. */ @@ -2547,13 +2554,37 @@ printf_wide_c_string (struct ui_file *stream, const char *format, for (len = 0;; len += wcwidth) { QUIT; - tem_str->resize (tem_str->size () + wcwidth); - gdb_byte *dst = tem_str->data () + len; + gdb_byte *dst; + if (!exceeds_max_value_size (len + wcwidth)) + { + tem_str->resize (tem_str->size () + wcwidth); + dst = tem_str->data () + len; + } + else + { + /* We still need to check for the null-character, so we need + somewhere to place the data read from the inferior. We + can't keep growing TEM_STR, it's gotten too big, so + instead just read the new character into the start of + TEMS_STR. This will corrupt the previously read contents, + but we're not going to print this string anyway, we just + want to know how big it would have been so we can tell the + user in the error message (see below). + + And we know there will be space in this buffer so long as + WCWIDTH is smaller than our LONGEST type, the + max-value-size can't be smaller than a LONGEST. */ + dst = tem_str->data (); + } read_memory (tem + len, dst, wcwidth); if (extract_unsigned_integer (dst, wcwidth, byte_order) == 0) break; } + if (exceeds_max_value_size (len + wcwidth)) + error (_("printed string requires %s bytes, which is more than " + "max-value-size"), plongest (len + wcwidth)); + str = tem_str->data (); } diff --git a/gdb/testsuite/gdb.base/printcmds.c b/gdb/testsuite/gdb.base/printcmds.c index fa3a62d6cdd..8445fcc1aa2 100644 --- a/gdb/testsuite/gdb.base/printcmds.c +++ b/gdb/testsuite/gdb.base/printcmds.c @@ -75,6 +75,8 @@ char *teststring = (char*)"teststring contents"; typedef char *charptr; charptr teststring2 = "more contents"; +const char *teststring3 = "this is a longer test string that we can use"; + /* Test printing of a struct containing character arrays. */ struct some_arrays { diff --git a/gdb/testsuite/gdb.base/printcmds.exp b/gdb/testsuite/gdb.base/printcmds.exp index 73f145c9586..eab0264af63 100644 --- a/gdb/testsuite/gdb.base/printcmds.exp +++ b/gdb/testsuite/gdb.base/printcmds.exp @@ -901,6 +901,11 @@ proc test_printf {} { # PR cli/14977. gdb_test "printf \"%s\\n\", 0" "\\(null\\)" + + with_max_value_size 20 { + gdb_test {printf "%s", teststring3} \ + "^printed string requires 45 bytes, which is more than max-value-size" + } } #Test printing DFP values with printf diff --git a/gdb/testsuite/gdb.base/printf-wchar_t.c b/gdb/testsuite/gdb.base/printf-wchar_t.c index 4d13fd3c961..2635932c780 100644 --- a/gdb/testsuite/gdb.base/printf-wchar_t.c +++ b/gdb/testsuite/gdb.base/printf-wchar_t.c @@ -18,6 +18,8 @@ #include const wchar_t wide_str[] = L"wide string"; +const wchar_t long_wide_str[] + = L"this is a much longer wide string that we can use if needed"; int main (void) diff --git a/gdb/testsuite/gdb.base/printf-wchar_t.exp b/gdb/testsuite/gdb.base/printf-wchar_t.exp index 85c6edf292c..8a6003d5785 100644 --- a/gdb/testsuite/gdb.base/printf-wchar_t.exp +++ b/gdb/testsuite/gdb.base/printf-wchar_t.exp @@ -24,3 +24,9 @@ if {![runto_main]} { } gdb_test {printf "%ls\n", wide_str} "^wide string" + +# Check that if the max-value-size will kick in when using printf on strings. +with_max_value_size 20 { + gdb_test {printf "%ls\n", long_wide_str} \ + "^printed string requires 240 bytes, which is more than max-value-size" +} diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 294d136a547..c8d0aa6d3b8 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -3192,6 +3192,36 @@ proc with_target_charset { target_charset body } { } } +# Run tests in BODY with max-value-size set to SIZE. When BODY is +# finished restore max-value-size. + +proc with_max_value_size { size body } { + global gdb_prompt + + set saved "" + gdb_test_multiple "show max-value-size" "" { + -re -wrap "Maximum value size is ($::decimal) bytes\\." { + set saved $expect_out(1,string) + } + -re ".*$gdb_prompt " { + fail "get max-value-size" + } + } + + gdb_test_no_output -nopass "set max-value-size $size" + + set code [catch {uplevel 1 $body} result] + + gdb_test_no_output -nopass "set max-value-size $saved" + + if {$code == 1} { + global errorInfo errorCode + return -code $code -errorinfo $errorInfo -errorcode $errorCode $result + } else { + return -code $code $result + } +} + # Switch the default spawn id to SPAWN_ID, so that gdb_test, # mi_gdb_test etc. default to using it. diff --git a/gdb/value.c b/gdb/value.c index 980722a6dd7..05e5d10ab38 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -804,7 +804,7 @@ check_type_length_before_alloc (const struct type *type) { ULONGEST length = type->length (); - if (max_value_size > -1 && length > max_value_size) + if (exceeds_max_value_size (length)) { if (type->name () != NULL) error (_("value of type `%s' requires %s bytes, which is more " @@ -815,6 +815,14 @@ check_type_length_before_alloc (const struct type *type) } } +/* See value.h. */ + +bool +exceeds_max_value_size (ULONGEST length) +{ + return max_value_size > -1 && length > max_value_size; +} + /* When this has a value, it is used to limit the number of array elements of an array that are loaded into memory when an array value is made non-lazy. */ diff --git a/gdb/value.h b/gdb/value.h index 508367a4159..cca356a93ea 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1575,6 +1575,11 @@ extern void finalize_values (); of floating-point, fixed-point, or integer type. */ extern gdb_mpq value_to_gdb_mpq (struct value *value); +/* Return true if LEN (in bytes) exceeds the max-value-size setting, + otherwise, return false. If the user has disabled (set to unlimited) + the max-value-size setting then this function will always return false. */ +extern bool exceeds_max_value_size (ULONGEST length); + /* While an instance of this class is live, and array values that are created, that are larger than max_value_size, will be restricted in size to a particular number of elements. */