From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-io1-xd34.google.com (mail-io1-xd34.google.com [IPv6:2607:f8b0:4864:20::d34]) by sourceware.org (Postfix) with ESMTPS id 683833858C78 for ; Tue, 5 Sep 2023 19:47:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 683833858C78 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com Received: by mail-io1-xd34.google.com with SMTP id ca18e2360f4ac-7927952ca67so97436639f.2 for ; Tue, 05 Sep 2023 12:47:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1693943226; x=1694548026; darn=sourceware.org; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=XyjSmjgZUasuyAWE8stwSMLVJgjoXAqTZghRRLGxFOQ=; b=gluJAqGs8OnTUDNqA+7VZA4HHepgZgJtc9N6piJFJw66m5hS/Ye6WX9FhgUUWaWfuO ZoJf6DLvoEZIPN5ucDyzqQpayQ0rS8qHjkGGy6gVV+0NUeEAjPpYkpFT5Mg+NsY5mEuc 8Lm38OiaTmARemtCEHOK5MYeslF6Dbvk0vbWf0IK4yZAWJe328zq49GS2WyoVI3eDUTy 4zdjiY8j/J6nweolseOlFAZjuRax1lRoRIKL4WtlmeJBvsS9aHMyjDNng2twXRxeljlJ //q3ZOeKfp37yf2CbxftaBLTjRt1e6pTc08jXchWbO9hnQddLz7F5/rAhhzjntEQJ/DR xERg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693943226; x=1694548026; h=to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XyjSmjgZUasuyAWE8stwSMLVJgjoXAqTZghRRLGxFOQ=; b=KNkUm45n6Iu6iIPmOxjcjgjXwR82JrbqdEr1Q0VRIPsOiltAXIELAmOahgEudHhH+u 3iXDoXR4KL5PJuEJbovLr7RsTZq/gRchTA1705egXHHjzGL3IEseR3puDLI3kAxFxvqS UMek3uWEiA2HPXix2sfwtgDgleY/LVX8tIaPFYit5Bt12Faj4vE0LqZnLIXGelHoRIbd JnOpxZ7RmU8sZ6cEOMGsX5PoWeSGpPTvOnU+4wv23+zgNmMl36mSMXVXwtkoW9bs3nrW Kws1QK5M3d9zRRjKbiReD03ujvVuPk35Hjr/PUBx9PrLAYv4gJXgv/SJCSA5vjzJnTQY QZCA== X-Gm-Message-State: AOJu0Yzftee+5hszIX6EsEY+9Ft57/2gNietBGrbo9A52tqT5dENzbxy vzmtnA/RUABNAzHGZ3vcpq57+bi5A2xVoQd6ch4vqw== X-Google-Smtp-Source: AGHT+IH/cbqvX2kmZljh/lJ4LKIRSsgapy/M6aRZMOgUPBF4HSqWTkUUsZjMa43T2zbGS/BpSLxTQQ== X-Received: by 2002:a05:6602:2118:b0:792:96e5:962 with SMTP id x24-20020a056602211800b0079296e50962mr14472240iox.6.1693943226639; Tue, 05 Sep 2023 12:47:06 -0700 (PDT) Received: from localhost.localdomain (75-166-150-212.hlrn.qwest.net. [75.166.150.212]) by smtp.gmail.com with ESMTPSA id y9-20020a02a389000000b0042b144abf71sm4294910jak.179.2023.09.05.12.47.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Sep 2023 12:47:06 -0700 (PDT) From: Tom Tromey Date: Tue, 05 Sep 2023 13:47:05 -0600 Subject: [PATCH 5/5] Handle pointers and references correctly in DAP MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20230905-dap-30821-pointers-v1-5-0d7323327678@adacore.com> References: <20230905-dap-30821-pointers-v1-0-0d7323327678@adacore.com> In-Reply-To: <20230905-dap-30821-pointers-v1-0-0d7323327678@adacore.com> To: gdb-patches@sourceware.org X-Mailer: b4 0.12.3 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_SHORT,RCVD_IN_DNSWL_NONE,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 List-Id: A user pointed out that the current DAP variable code does not let the client deference a pointer. Oops! Fixing this oversight is simple enough -- adding a new no-op pretty-printer for pointers and references is quite simple. However, doing this naive caused a regession in scopes.exp, which expected there to be no children of a 'const char *' variable. This problem was fixed by the preceding patches in the series, which ensure that a C type of this kind is recognized as a string. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30821 --- gdb/python/lib/gdb/printing.py | 16 ++++++ gdb/testsuite/gdb.dap/ptrref.cc | 34 +++++++++++++ gdb/testsuite/gdb.dap/ptrref.exp | 103 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) diff --git a/gdb/python/lib/gdb/printing.py b/gdb/python/lib/gdb/printing.py index 1a761a6aa57..223a69929d2 100644 --- a/gdb/python/lib/gdb/printing.py +++ b/gdb/python/lib/gdb/printing.py @@ -280,6 +280,20 @@ class NoOpScalarPrinter: return self.value.format_string(raw=True) +class NoOpPointerReferencePrinter: + """A no-op pretty printer that wraps a pointer or reference.""" + + def __init__(self, value): + self.value = value + self.num_children = 1 + + def to_string(self): + return self.value.format_string(deref_refs=False) + + def children(self): + yield "value", self.value.referenced_value() + + class NoOpArrayPrinter: """A no-op pretty printer that wraps an array value.""" @@ -354,6 +368,8 @@ def make_visualizer(value): result = gdb.printing.NoOpArrayPrinter(ty, value) elif ty.code in (gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION): result = gdb.printing.NoOpStructPrinter(ty, value) + elif ty.code in (gdb.TYPE_CODE_PTR, gdb.TYPE_CODE_REF, gdb.TYPE_CODE_RVALUE_REF): + result = NoOpPointerReferencePrinter(value) else: result = gdb.printing.NoOpScalarPrinter(value) return result diff --git a/gdb/testsuite/gdb.dap/ptrref.cc b/gdb/testsuite/gdb.dap/ptrref.cc new file mode 100644 index 00000000000..bfb1afe3d17 --- /dev/null +++ b/gdb/testsuite/gdb.dap/ptrref.cc @@ -0,0 +1,34 @@ +/* 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 . */ + +void +func () +{ + int value = 23; + + int *ptr = &value; + int &ref = value; + + return; /* BREAK */ +} + +int +main (int argc, char *argv[]) +{ + func (); + return 0; +} diff --git a/gdb/testsuite/gdb.dap/ptrref.exp b/gdb/testsuite/gdb.dap/ptrref.exp new file mode 100644 index 00000000000..e0cc74529ab --- /dev/null +++ b/gdb/testsuite/gdb.dap/ptrref.exp @@ -0,0 +1,103 @@ +# 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 . + +require allow_dap_tests + +load_lib dap-support.exp + +standard_testfile .cc + +if {[build_executable ${testfile}.exp $testfile $srcfile {debug c++}] == -1} { + return +} + +if {[dap_launch $testfile] == ""} { + return +} + +set line [gdb_get_line_number "BREAK"] +set obj [dap_check_request_and_response "set breakpoint by line number" \ + setBreakpoints \ + [format {o source [o path [%s]] breakpoints [a [o line [i %d]]]} \ + [list s $srcfile] $line]] +set line_bpno [dap_get_breakpoint_number $obj] + +dap_check_request_and_response "start inferior" configurationDone +dap_wait_for_event_and_check "inferior started" thread "body reason" started + +dap_wait_for_event_and_check "stopped at line breakpoint" stopped \ + "body reason" breakpoint \ + "body hitBreakpointIds" $line_bpno + +set bt [lindex [dap_check_request_and_response "backtrace" stackTrace \ + {o threadId [i 1]}] \ + 0] +set frame_id [dict get [lindex [dict get $bt body stackFrames] 0] id] + +set scopes [dap_check_request_and_response "get scopes" scopes \ + [format {o frameId [i %d]} $frame_id]] +set scopes [dict get [lindex $scopes 0] body scopes] + +gdb_assert {[llength $scopes] == 2} "two scopes" + +lassign $scopes scope reg_scope +gdb_assert {[dict get $scope name] == "Locals"} "scope is locals" + +gdb_assert {[dict get $scope namedVariables] == 3} "three vars in scope" + +set num [dict get $scope variablesReference] +set refs [lindex [dap_check_request_and_response "fetch variables" \ + "variables" \ + [format {o variablesReference [i %d] count [i 3]} \ + $num]] \ + 0] + +proc fetch_pointer {name var} { + set num [dict get $var variablesReference] + set refs [lindex [dap_check_request_and_response "fetch children of $name" \ + "variables" \ + [format {o variablesReference [i %d] count [i 1]} \ + $num]] \ + 0] + set var [lindex [dict get $refs body variables] 0] + gdb_assert {[dict get $var value] == 23} \ + "value of child of $name" + gdb_assert {[dict get $var variablesReference] == 0} \ + "no children for child of $name" +} + +foreach var [dict get $refs body variables] { + set name [dict get $var name] + + switch $name { + "value" { + gdb_assert {[dict get $var value] == "23"} "check value of value" + gdb_assert {[dict get $var variablesReference] == 0} \ + "$name does not have child" + } + "ptr" - + "ref" { + gdb_assert {[dict get $var variablesReference] != 0} \ + "$name has children" + # The implementation somewhat arbitrarily chooses "named" + # children here. + gdb_assert {[dict get $var namedVariables] == 1} \ + "$name has exactly one child" + fetch_pointer $name $var + } + } +} + +dap_shutdown -- 2.40.1