From patchwork Thu Mar 30 12:10:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 67116 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 5B4DA38582A3 for ; Thu, 30 Mar 2023 12:11:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5B4DA38582A3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1680178260; bh=c69GpLZ40iYiwG7wn0qsdMydiLH7tjGv+kfhFamiueM=; 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=RlSNo0COENCodMO+95OC+f7q+fTb4TkT0GI0ReRJqVMeYa6sNNO/WhabZhIOETd5I BRHWU9SUBfHGSpXAajmFNj7W5W0lYX9tBdHnpH/E8ka466pTubbMD4hMmzzSo0y1eq SS8+61ntPEr5ay+fdH2OzFcfK2KrGIglqBp9uDOo= 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 14D653858CDA for ; Thu, 30 Mar 2023 12:10:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 14D653858CDA 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-296-nw1J-jUVMdCixmlkKbD5SQ-1; Thu, 30 Mar 2023 08:10:30 -0400 X-MC-Unique: nw1J-jUVMdCixmlkKbD5SQ-1 Received: by mail-wm1-f69.google.com with SMTP id r11-20020a05600c458b00b003eea8d25f06so9721334wmo.1 for ; Thu, 30 Mar 2023 05:10:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680178228; 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=c69GpLZ40iYiwG7wn0qsdMydiLH7tjGv+kfhFamiueM=; b=lUMt1XVYVkOpxUBU6Ue3nEZtB+9rhL/e2ycmuTRtCyWcwzzBy87+CzMbADVJEcfVkc TPSly9lljV5noMve+T4h+OwbY6aI9d75aJ5rTzzfbobyN6AsjmKtXGiejfW5+coM8Ilg swsFfHLulkxGZj3aZgVxUf28xcZJRr4k0v4QtY4vj2dT9pwqN4ZZdx4G9uIu56RyjShD cddLLpM8OJ7CMtFi5ClK4zikIAl8KBXiiuW5Ze983INfhgs47cdGwlHNq5R1UrrI0tPB d/kgR1VH8JqUiT7em3MzrTOaTqXcGQ94spmHcSWnm3dHyJukubloaKz6tBMtkRQ9hrsK 9YHA== X-Gm-Message-State: AO0yUKU4R31g8KOMPy0m48iDAXyzJUmmpOlnlM5+uRJaGK2FHYMpo73z xT4Ai3jH1fUaU4lWM4dbvjStVgozTNoCnM8b182yo/zEM1G1cfqGXfn0kANfQ7TDE25ZjOeXIHw dBCTxNmchUoMBjrto0BGx33PKrBRE9hZSoFc6WIbFxiSgJD0nWVLSIRlUwczOcVXCMJA6RgtgZ3 +qbSP5gA== X-Received: by 2002:a05:600c:218d:b0:3ed:9576:34ce with SMTP id e13-20020a05600c218d00b003ed957634cemr17454197wme.9.1680178228447; Thu, 30 Mar 2023 05:10:28 -0700 (PDT) X-Google-Smtp-Source: AK7set9KLfdp+s4I+CJow3rC/UTpsI1s+sb9qJd8HR4ksOpqcLgRUfqKAaGHSuKeCq0PHEl0KCYMuQ== X-Received: by 2002:a05:600c:218d:b0:3ed:9576:34ce with SMTP id e13-20020a05600c218d00b003ed957634cemr17454178wme.9.1680178228019; Thu, 30 Mar 2023 05:10:28 -0700 (PDT) Received: from localhost (95.72.115.87.dyn.plus.net. [87.115.72.95]) by smtp.gmail.com with ESMTPSA id o5-20020a05600c510500b003ef5bb63f13sm6109255wms.10.2023.03.30.05.10.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Mar 2023 05:10:27 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 1/4] gdb/python: have UnwindInfo.add_saved_register accept named args Date: Thu, 30 Mar 2023 13:10:20 +0100 Message-Id: <0d08cca8737eff64400b5bb973bed259e4affa7e.1680177890.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.7 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, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, 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 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" Update gdb.UnwindInfo.add_saved_register to accept named keyword arguments. As part of this update we now use gdb_PyArg_ParseTupleAndKeywords instead of PyArg_UnpackTuple to parse the function arguments. By switching to gdb_PyArg_ParseTupleAndKeywords, we can now use 'O!' as the argument format for the function's value argument. This means that we can check the argument type (is gdb.Value) as part of the argument processing rather than manually performing the check later in the function. One result of this is that we now get a better error message (at least, I think so). Previously we would get something like: ValueError: Bad register value Now we get: TypeError: argument 2 must be gdb.Value, not XXXX It's unfortunate that the exception type changed, but I think the new exception type actually makes more sense. For existing unwinder code that doesn't throw any exceptions nothing should change with this commit. It is possible that a user has some code that throws and catches the ValueError, and this code will break after this commit, but I think this is going to be sufficiently rare that we can take the risk here. Reviewed-By: Eli Zaretskii --- gdb/doc/python.texi | 4 +- gdb/python/py-unwind.c | 84 +++++++++++++------------- gdb/testsuite/gdb.python/py-unwind.exp | 15 +++-- gdb/testsuite/gdb.python/py-unwind.py | 28 ++++++--- 4 files changed, 75 insertions(+), 56 deletions(-) diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index c74d586ef39..ef50e6dbe7b 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -2882,8 +2882,8 @@ create a @code{gdb.UnwindInfo} instance. Use the following method to specify caller registers that have been saved in this frame: -@defun gdb.UnwindInfo.add_saved_register (reg, value) -@var{reg} identifies the register, for a description of the acceptable +@defun gdb.UnwindInfo.add_saved_register (@var{register}, @var{value}) +@var{register} identifies the register, for a description of the acceptable values see @ref{gdbpy_frame_read_register,,Frame.read_register}. @var{value} is a register value (a @code{gdb.Value} object). @end defun diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c index 409dbd3a470..2e13b84eb12 100644 --- a/gdb/python/py-unwind.c +++ b/gdb/python/py-unwind.c @@ -292,7 +292,7 @@ pyuw_create_unwind_info (PyObject *pyo_pending_frame, gdb.UnwindInfo.add_saved_register (REG, VALUE) -> None. */ static PyObject * -unwind_infopy_add_saved_register (PyObject *self, PyObject *args) +unwind_infopy_add_saved_register (PyObject *self, PyObject *args, PyObject *kw) { unwind_info_object *unwind_info = (unwind_info_object *) self; pending_frame_object *pending_frame @@ -305,11 +305,15 @@ unwind_infopy_add_saved_register (PyObject *self, PyObject *args) { PyErr_SetString (PyExc_ValueError, "UnwindInfo instance refers to a stale PendingFrame"); - return NULL; + return nullptr; } - if (!PyArg_UnpackTuple (args, "previous_frame_register", 2, 2, - &pyo_reg_id, &pyo_reg_value)) - return NULL; + + static const char *keywords[] = { "register", "value", nullptr }; + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO!", keywords, + &pyo_reg_id, &value_object_type, + &pyo_reg_value)) + return nullptr; + if (!gdbpy_parse_register_id (pending_frame->gdbarch, pyo_reg_id, ®num)) return nullptr; @@ -332,43 +336,38 @@ unwind_infopy_add_saved_register (PyObject *self, PyObject *args) } } - { - struct value *value; - size_t data_size; + /* The argument parsing above guarantees that PYO_REG_VALUE will be a + gdb.Value object, as a result the value_object_to_value call should + succeed. */ + gdb_assert (pyo_reg_value != nullptr); + struct value *value = value_object_to_value (pyo_reg_value); + gdb_assert (value != nullptr); + + ULONGEST reg_size = register_size (pending_frame->gdbarch, regnum); + if (reg_size != value->type ()->length ()) + { + PyErr_Format (PyExc_ValueError, + "The value of the register returned by the Python " + "sniffer has unexpected size: %s instead of %s.", + pulongest (value->type ()->length ()), + pulongest (reg_size)); + return nullptr; + } + + gdbpy_ref<> new_value = gdbpy_ref<>::new_reference (pyo_reg_value); + bool found = false; + for (saved_reg ® : *unwind_info->saved_regs) + { + if (regnum == reg.number) + { + found = true; + reg.value = std::move (new_value); + break; + } + } + if (!found) + unwind_info->saved_regs->emplace_back (regnum, std::move (new_value)); - if (pyo_reg_value == NULL - || (value = value_object_to_value (pyo_reg_value)) == NULL) - { - PyErr_SetString (PyExc_ValueError, "Bad register value"); - return NULL; - } - data_size = register_size (pending_frame->gdbarch, regnum); - if (data_size != value->type ()->length ()) - { - PyErr_Format ( - PyExc_ValueError, - "The value of the register returned by the Python " - "sniffer has unexpected size: %u instead of %u.", - (unsigned) value->type ()->length (), - (unsigned) data_size); - return NULL; - } - } - { - gdbpy_ref<> new_value = gdbpy_ref<>::new_reference (pyo_reg_value); - bool found = false; - for (saved_reg ® : *unwind_info->saved_regs) - { - if (regnum == reg.number) - { - found = true; - reg.value = std::move (new_value); - break; - } - } - if (!found) - unwind_info->saved_regs->emplace_back (regnum, std::move (new_value)); - } Py_RETURN_NONE; } @@ -1087,7 +1086,8 @@ PyTypeObject pending_frame_object_type = static PyMethodDef unwind_info_object_methods[] = { { "add_saved_register", - unwind_infopy_add_saved_register, METH_VARARGS, + (PyCFunction) unwind_infopy_add_saved_register, + METH_VARARGS | METH_KEYWORDS, "add_saved_register (REG, VALUE) -> None\n" "Set the value of the REG in the previous frame to VALUE." }, { NULL } /* Sentinel */ diff --git a/gdb/testsuite/gdb.python/py-unwind.exp b/gdb/testsuite/gdb.python/py-unwind.exp index fddf4f15393..37c8fd8fbb1 100644 --- a/gdb/testsuite/gdb.python/py-unwind.exp +++ b/gdb/testsuite/gdb.python/py-unwind.exp @@ -131,10 +131,17 @@ gdb_test "disable unwinder global \"test unwinder\"" \ check_for_broken_backtrace "stack is broken after command disabling" check_info_unwinder "info unwinder after command disabling" off -# Check that invalid register names cause errors. -gdb_test "python print(add_saved_register_error)" "True" \ - "add_saved_register error" -gdb_test "python print(read_register_error)" "True" \ +# Check that invalid register names and values cause errors. +gdb_test "python print(add_saved_register_errors\[\"unknown_name\"\])" \ + "Bad register" \ + "add_saved_register error when an unknown register name is used" +gdb_test "python print(add_saved_register_errors\[\"unknown_number\"\])" \ + "Bad register" \ + "add_saved_register error when an unknown register number is used" +gdb_test "python print(add_saved_register_errors\[\"bad_value\"\])" \ + "argument 2 must be gdb.Value, not int" \ + "add_saved_register error when invalid register value is used" +gdb_test "python print(read_register_error)" "Bad register" \ "read_register error" # Try to create an unwinder object with a non-string name. diff --git a/gdb/testsuite/gdb.python/py-unwind.py b/gdb/testsuite/gdb.python/py-unwind.py index 4e110c51e3b..5853abc7486 100644 --- a/gdb/testsuite/gdb.python/py-unwind.py +++ b/gdb/testsuite/gdb.python/py-unwind.py @@ -18,7 +18,7 @@ from gdb.unwinder import Unwinder, FrameId # These are set to test whether invalid register names cause an error. -add_saved_register_error = False +add_saved_register_errors = {} read_register_error = False @@ -94,9 +94,9 @@ class TestUnwinder(Unwinder): try: pending_frame.read_register("nosuchregister") - except ValueError: + except ValueError as ve: global read_register_error - read_register_error = True + read_register_error = str(ve) frame_id = FrameId( pending_frame.read_register(TestUnwinder.AMD64_RSP), @@ -104,13 +104,25 @@ class TestUnwinder(Unwinder): ) unwind_info = pending_frame.create_unwind_info(frame_id) unwind_info.add_saved_register(TestUnwinder.AMD64_RBP, previous_bp) - unwind_info.add_saved_register("rip", previous_ip) - unwind_info.add_saved_register("rsp", previous_sp) + unwind_info.add_saved_register(value=previous_ip, register="rip") + unwind_info.add_saved_register(register="rsp", value=previous_sp) + + global add_saved_register_errors try: unwind_info.add_saved_register("nosuchregister", previous_sp) - except ValueError: - global add_saved_register_error - add_saved_register_error = True + except ValueError as ve: + add_saved_register_errors["unknown_name"] = str(ve) + + try: + unwind_info.add_saved_register(999, previous_sp) + except ValueError as ve: + add_saved_register_errors["unknown_number"] = str(ve) + + try: + unwind_info.add_saved_register("rsp", 1234) + except TypeError as ve: + add_saved_register_errors["bad_value"] = str(ve) + return unwind_info except (gdb.error, RuntimeError): return None From patchwork Thu Mar 30 12:10:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 67118 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 EE4A53854830 for ; Thu, 30 Mar 2023 12:11:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EE4A53854830 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1680178290; bh=FhS9FfB17Fjr0lZuTzHxadBmFfsJUEfyMDd8HkH3aiY=; 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=fcQmVHRZeaNuk5O2ttQqJ2526ar0U88/Yl0HCedi/w5J8UvBwcH+AtnagoxOonFAW LY+FVQjcOqFMy/0rwaQZyRDQh8q14shAY3DXbp79Zo25T/0LCHCAQqDdx79Qz9rqJo DwuvtvlZ4NSr1gEABemUFZmwPmTZnohwcpF+5xxU= 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 CA27E3858C53 for ; Thu, 30 Mar 2023 12:10:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CA27E3858C53 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-508-n-BwZvh5PSmHWxum-cz_CQ-1; Thu, 30 Mar 2023 08:10:31 -0400 X-MC-Unique: n-BwZvh5PSmHWxum-cz_CQ-1 Received: by mail-wm1-f72.google.com with SMTP id k1-20020a05600c1c8100b003ee6dbceb81so9720791wms.5 for ; Thu, 30 Mar 2023 05:10:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680178230; 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=FhS9FfB17Fjr0lZuTzHxadBmFfsJUEfyMDd8HkH3aiY=; b=N0zd4kkhq0ERzjF9o3IjFN2PoKx4K8jdRSFpDGzsSDTKrEE1oIXd7wxG3e2VKW/qg0 GufsbNxS/o6Qznn7LdvVrP8/jrANOQ7wWrLJ+8SVDcIt+jhrgTkYjwG8lDhcQVs2fd2m vjdvhAfEZxN/v/aM+fFrVwdzo74p5VJKbaYHXggTVGQ/jiqSJR0KqUVtvu9suu+BH7lf 9X0bkKBdkfTzNBe0x/G9sTGi1uoq0g4RxFTWbxAvezSZaK+g3CkHDOV+rN6dt692/iC8 4pZ/mzThQJ9SrXp5FP2edI0xGwpKcgfS5pLX5bPwm1rFxnjWemOmhg/3lKWeedkNwfD0 MjDQ== X-Gm-Message-State: AAQBX9d1amQqEWA9pZvDCeG/151GXJek2c0WZX8cPUDaW/jb6uOZB3pb Wd7Nx7wA7gqmkBt48I7LA5t9WRqu57vQ+UbSvI6xDjOGiBkVv7Gqz6UL5QYctDl0cg1WMTbid0a nxLsMvpPOHlAjxVfBK0Ka1Za2PdFrzzTmi4gGKrsBBlx3D06St4av7fTgrD+pcScs4UZE57LDYZ JrqaCPSg== X-Received: by 2002:a5d:4a51:0:b0:2d3:33d4:1cfb with SMTP id v17-20020a5d4a51000000b002d333d41cfbmr18189530wrs.36.1680178229797; Thu, 30 Mar 2023 05:10:29 -0700 (PDT) X-Google-Smtp-Source: AKy350Zhq5YnXd2Y1r2rkSlDPGVTcdXNTcYdaELIqPf0DqHVgw68jjQepAQ9KpjpPOz0V0NPav/Bkg== X-Received: by 2002:a5d:4a51:0:b0:2d3:33d4:1cfb with SMTP id v17-20020a5d4a51000000b002d333d41cfbmr18189513wrs.36.1680178229413; Thu, 30 Mar 2023 05:10:29 -0700 (PDT) Received: from localhost (95.72.115.87.dyn.plus.net. [87.115.72.95]) by smtp.gmail.com with ESMTPSA id p5-20020a5d4e05000000b002d75909c76esm25871959wrt.73.2023.03.30.05.10.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Mar 2023 05:10:29 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 2/4] gdb/python: have PendingFrame methods accept keyword arguments Date: Thu, 30 Mar 2023 13:10:21 +0100 Message-Id: <2b2fd6d7cda91c3bd4f8ea3241041fe6ae44f584.1680177890.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.7 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, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, 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 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" Update the two gdb.PendingFrame methods gdb.PendingFrame.read_register and gdb.PendingFrame.create_unwind_info accept keyword arguments. There's no huge benefit for making this change, both of these methods only take a single argument, so it is (maybe) less likely that a user will take advantage of the keyword arguments in these cases, but I think it's nice to be consistent, and I don't see any particular draw backs to making this change. There should be no user visible changes (for existing code) after this commit. Reviewed-By: Eli Zaretskii --- gdb/doc/python.texi | 10 +++++----- gdb/python/py-unwind.c | 23 ++++++++++++++--------- gdb/testsuite/gdb.python/py-unwind.py | 4 ++-- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index ef50e6dbe7b..4f62ca7d95e 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -2756,11 +2756,11 @@ An object passed to an unwinder (a @code{gdb.PendingFrame} instance) provides a method to read frame's registers: -@defun PendingFrame.read_register (reg) -This method returns the contents of the register @var{reg} in the +@defun PendingFrame.read_register (@var{register}) +This method returns the contents of the register @var{register} in the frame as a @code{gdb.Value} object. For a description of the -acceptable values of @var{reg} see -@ref{gdbpy_frame_read_register,,Frame.read_register}. If @var{reg} +acceptable values of @var{register} see +@ref{gdbpy_frame_read_register,,Frame.read_register}. If @var{register} does not name a register for the current architecture, this method will throw an exception. @@ -2783,7 +2783,7 @@ instance to be returned to @value{GDBN}: @anchor{gdb.PendingFrame.create_unwind_info} -@defun PendingFrame.create_unwind_info (frame_id) +@defun PendingFrame.create_unwind_info (@var{frame_id}) Returns a new @code{gdb.UnwindInfo} instance identified by given @var{frame_id}. The @var{frame_id} is used internally by @value{GDBN} to identify the frames within the current thread's stack. The diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c index 2e13b84eb12..d83979bed2b 100644 --- a/gdb/python/py-unwind.c +++ b/gdb/python/py-unwind.c @@ -443,16 +443,17 @@ pending_framepy_repr (PyObject *self) Returns the value of register REG as gdb.Value instance. */ static PyObject * -pending_framepy_read_register (PyObject *self, PyObject *args) +pending_framepy_read_register (PyObject *self, PyObject *args, PyObject *kw) { pending_frame_object *pending_frame = (pending_frame_object *) self; PENDING_FRAMEPY_REQUIRE_VALID (pending_frame); - int regnum; PyObject *pyo_reg_id; + static const char *keywords[] = { "register", nullptr }; + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &pyo_reg_id)) + return nullptr; - if (!PyArg_UnpackTuple (args, "read_register", 1, 1, &pyo_reg_id)) - return NULL; + int regnum; if (!gdbpy_parse_register_id (pending_frame->gdbarch, pyo_reg_id, ®num)) return nullptr; @@ -681,7 +682,8 @@ pending_framepy_function (PyObject *self, PyObject *args) PendingFrame.create_unwind_info (self, frameId) -> UnwindInfo. */ static PyObject * -pending_framepy_create_unwind_info (PyObject *self, PyObject *args) +pending_framepy_create_unwind_info (PyObject *self, PyObject *args, + PyObject *kw) { PyObject *pyo_frame_id; CORE_ADDR sp; @@ -690,7 +692,9 @@ pending_framepy_create_unwind_info (PyObject *self, PyObject *args) PENDING_FRAMEPY_REQUIRE_VALID ((pending_frame_object *) self); - if (!PyArg_ParseTuple (args, "O:create_unwind_info", &pyo_frame_id)) + static const char *keywords[] = { "frame_id", nullptr }; + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, + &pyo_frame_id)) return nullptr; pyuw_get_attr_code code @@ -1002,11 +1006,12 @@ gdbpy_initialize_unwind (void) static PyMethodDef pending_frame_object_methods[] = { - { "read_register", pending_framepy_read_register, METH_VARARGS, + { "read_register", (PyCFunction) pending_framepy_read_register, + METH_VARARGS | METH_KEYWORDS, "read_register (REG) -> gdb.Value\n" "Return the value of the REG in the frame." }, - { "create_unwind_info", - pending_framepy_create_unwind_info, METH_VARARGS, + { "create_unwind_info", (PyCFunction) pending_framepy_create_unwind_info, + METH_VARARGS | METH_KEYWORDS, "create_unwind_info (FRAME_ID) -> gdb.UnwindInfo\n" "Construct UnwindInfo for this PendingFrame, using FRAME_ID\n" "to identify it." }, diff --git a/gdb/testsuite/gdb.python/py-unwind.py b/gdb/testsuite/gdb.python/py-unwind.py index 5853abc7486..201b629f9fe 100644 --- a/gdb/testsuite/gdb.python/py-unwind.py +++ b/gdb/testsuite/gdb.python/py-unwind.py @@ -99,7 +99,7 @@ class TestUnwinder(Unwinder): read_register_error = str(ve) frame_id = FrameId( - pending_frame.read_register(TestUnwinder.AMD64_RSP), + pending_frame.read_register(register=TestUnwinder.AMD64_RSP), pending_frame.read_register(TestUnwinder.AMD64_RIP), ) unwind_info = pending_frame.create_unwind_info(frame_id) @@ -156,7 +156,7 @@ class simple_unwinder(Unwinder): captured_pending_frame = pending_frame captured_pending_frame_repr = repr(pending_frame) fid = FrameId(self._sp, self._pc) - uw = pending_frame.create_unwind_info(fid) + uw = pending_frame.create_unwind_info(frame_id=fid) uw.add_saved_register("rip", gdb.Value(0x123)) uw.add_saved_register("rbp", gdb.Value(0x456)) uw.add_saved_register("rsp", gdb.Value(0x789)) From patchwork Thu Mar 30 12:10:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 67117 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 A6A49385B50D for ; Thu, 30 Mar 2023 12:11:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A6A49385B50D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1680178287; bh=mDNe1QP8m1F8VqumoAt/TtWWc/8hr6Yw98yvnyvYyEw=; 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=GDNOvQ+W5ZhaDPurN5KEKgRMduZMZMRxxcOuUcF0ZbulRkBHI1TP7jrR+RhDegvEj CZHh4cqqCUHi/9z1ZApvbdx0YfMfIX+sgObfdc6dFpjtGlb4OEZ8s7ChIAdca7rlhU HpKDFF4HbNrovc65wN1a+Xt3tX43efBLXmePRTcY= 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 DFB41385840F for ; Thu, 30 Mar 2023 12:10:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DFB41385840F Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-629-L3LAeMXQNnGxs0tW_Z-AZg-1; Thu, 30 Mar 2023 08:10:32 -0400 X-MC-Unique: L3LAeMXQNnGxs0tW_Z-AZg-1 Received: by mail-wr1-f71.google.com with SMTP id s28-20020adfa29c000000b002d92bb99383so1963937wra.23 for ; Thu, 30 Mar 2023 05:10:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680178231; 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=mDNe1QP8m1F8VqumoAt/TtWWc/8hr6Yw98yvnyvYyEw=; b=JhoNTKGnKdDxly19KcBUz+bwMfHNDUev4+WpPb3vjHCBXaPfAiUaEvfG4QG8lFSSz8 qW6WPfpp0Ze5Fs+iCx27NVfIRqAv80Hj53/BfZySa35P6Ib4C0ryriET5rvMuc72WY7L 5emWX3mNzVQ8sc5rPRai3fkcwv5dVnRhM1ozGGw3tVrKQOvcPGrW8oX41e1WLfvyFByx ngTTpZQ84k0sAQzCYg9en5tBd9gzjHWf1dfVW7gFHGHjiYshQdRc1rGUfr+bD+qPjaks y5wzKVskCfZCABSw/RK4euum3TnEVypScOLagaTQBdkpzRa/zPCknX74DcYpubc6HW5z RrsA== X-Gm-Message-State: AO0yUKXXwRDKID56aeC6hkBgW2XTeVYiOAshgcqtw/SMJxIAHdJJrNEX CA6UZ/rFZn8Gi9E1AZUXAsTNaeGvHBxKnTLccp9eZTyFY4GE7rBblk+JXTzD8gK+Ksr/s2Jvbt2 pnWLpJRjTn91ftp9tFWUwNjhCuM4pYZCP5O0gW6K81suuoA1G7X3QNWIB2mLKOXRfyfcP3l/uh/ j+JK5dwg== X-Received: by 2002:a1c:7206:0:b0:3ed:f5d4:3bff with SMTP id n6-20020a1c7206000000b003edf5d43bffmr17043014wmc.38.1680178230981; Thu, 30 Mar 2023 05:10:30 -0700 (PDT) X-Google-Smtp-Source: AK7set9UleP1GQ0Ro7703X046J2SACX9Nub6YLOkKXMPsE8MMhk7U7t2eyfg3LFjyi1SmeG/PCPEwA== X-Received: by 2002:a1c:7206:0:b0:3ed:f5d4:3bff with SMTP id n6-20020a1c7206000000b003edf5d43bffmr17042999wmc.38.1680178230686; Thu, 30 Mar 2023 05:10:30 -0700 (PDT) Received: from localhost (95.72.115.87.dyn.plus.net. [87.115.72.95]) by smtp.gmail.com with ESMTPSA id m6-20020a7bce06000000b003ef5b011b30sm5603521wmc.8.2023.03.30.05.10.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Mar 2023 05:10:30 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 3/4] gdb/python: convert Frame.read_register to take named arguments Date: Thu, 30 Mar 2023 13:10:22 +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.7 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, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, 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 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" Following on from the previous commit, this updates Frame.read_register to accept named arguments. As with the previous commit there's no huge benefit for the users in accepting named arguments here -- this function only takes a single argument after all. But I do think it is worth keeping Frame.read_register method in sync with the PendingFrame.read_register method, this allows for the possibility that the user has some code that can operate on either a Frame or a Pending frame. Minor update to allow for named arguments, and an extra test to check the new functionality. Reviewed-By: Eli Zaretskii --- gdb/doc/python.texi | 2 +- gdb/python/py-frame.c | 11 +++++++---- gdb/testsuite/gdb.python/py-frame.exp | 6 ++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 4f62ca7d95e..f54909cc05d 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -5380,7 +5380,7 @@ @end defun @anchor{gdbpy_frame_read_register} -@defun Frame.read_register (register) +@defun Frame.read_register (@var{register}) Return the value of @var{register} in this frame. Returns a @code{Gdb.Value} object. Throws an exception if @var{register} does not exist. The @var{register} argument must be one of the following: diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c index 00cd4bee492..3a033ac7570 100644 --- a/gdb/python/py-frame.c +++ b/gdb/python/py-frame.c @@ -238,13 +238,15 @@ frapy_pc (PyObject *self, PyObject *args) Returns the value of a register in this frame. */ static PyObject * -frapy_read_register (PyObject *self, PyObject *args) +frapy_read_register (PyObject *self, PyObject *args, PyObject *kw) { PyObject *pyo_reg_id; PyObject *result = nullptr; - if (!PyArg_UnpackTuple (args, "read_register", 1, 1, &pyo_reg_id)) - return NULL; + static const char *keywords[] = { "register", nullptr }; + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &pyo_reg_id)) + return nullptr; + try { scoped_value_mark free_values; @@ -766,7 +768,8 @@ Return the reason why it's not possible to find frames older than this." }, { "pc", frapy_pc, METH_NOARGS, "pc () -> Long.\n\ Return the frame's resume address." }, - { "read_register", frapy_read_register, METH_VARARGS, + { "read_register", (PyCFunction) frapy_read_register, + METH_VARARGS | METH_KEYWORDS, "read_register (register_name) -> gdb.Value\n\ Return the value of the register in the frame." }, { "block", frapy_block, METH_NOARGS, diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp index 5aebb6beb5f..07997326d09 100644 --- a/gdb/testsuite/gdb.python/py-frame.exp +++ b/gdb/testsuite/gdb.python/py-frame.exp @@ -115,6 +115,12 @@ gdb_test "python print ('result = %s' % (f0.read_register('pc') == f0.pc()))" \ " = True" \ "test Frame.read_register(pc)" +# Repeat the previous test, but this time use named arguments for the +# read_register method call. +gdb_test "python print ('result = %s' % (f0.read_register(register = 'pc') == f0.pc()))" \ + " = True" \ + "test Frame.read_register() using named arguments" + # Test arch-specific register name. set pc "" if {[is_amd64_regs_target]} { From patchwork Thu Mar 30 12:10:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 67119 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 759E33850218 for ; Thu, 30 Mar 2023 12:11:38 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 759E33850218 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1680178298; bh=X3JKmJOGXC0bE65p88k0KSWnDSor98zahXiR5cE1yYk=; 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=vTqkG/y8nymcETgUWgXzI/CHJuLghBFuguQP2a///uNdhIHC6FYy9/V4JQLiEi11H 8eeQlFnqSu4DaDVVu33ukN/uEId0seI/PoLEyyCLAEPsseqMGWBW6EulpfZ1BvwP0o f0Z11WAO0kQIDuKb9FDPZYbQOrTW8vrFeEUqf86Y= 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 DEA953858033 for ; Thu, 30 Mar 2023 12:10:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DEA953858033 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-265-NOGynzL4M5Ws0zKXA5a3jw-1; Thu, 30 Mar 2023 08:10:34 -0400 X-MC-Unique: NOGynzL4M5Ws0zKXA5a3jw-1 Received: by mail-wm1-f69.google.com with SMTP id m5-20020a05600c4f4500b003ee8db23ef9so10110738wmq.8 for ; Thu, 30 Mar 2023 05:10:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680178232; 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=X3JKmJOGXC0bE65p88k0KSWnDSor98zahXiR5cE1yYk=; b=uyU7U8ucrsq/FJIEjcQW1FNvYB6VPpHu7mOs1rmf9pa5qwvd2xohAdsu1fI9Nf43k+ v1ItuSBiG/jsX0oA3eAd3jEzDATEJHCZl120W5BxkK4ldCP5TqaNzExAypLS6LjUrdxM NqSOSs5ldIf5NptBpaUptOTqn+Uwt4Wg6OurefUifG459XxU+ra9BXifZghXxxreNFcN FDjcgjIrP0JaY8+A5ZQcMvGazBdzKknyLW7GalLrGCr4+19LRT3pJNVx1ftB8DcNJYKB 5KQ5+0J/tvWL0ldSU6YK5Tvov0c/YJds3NCJuOneIyxsOrCKAMfLwu1Aps6yg2/Cs/3L rXYQ== X-Gm-Message-State: AAQBX9dIlnixo+oJdbC32n6mqgigHcJnM5nA2Ij7usoN9Ft2c+n+5UOn wmV3Glfn6ZqMZbaqgYBKQD1uaqptvisu6HmjiUhDkOyKUtwrUmDaHNoAWlsrj8p4Vl7GLXEstiB BFCTwEiGGAEqp2mFr8yss9zbc4jJvJ3LaTTX2YoOcbjfJ4uM3lUt/eOXvEZxfNOslEIxautqCIb 1fqjXU2Q== X-Received: by 2002:a5d:4f82:0:b0:2d7:ef27:427 with SMTP id d2-20020a5d4f82000000b002d7ef270427mr16878145wru.67.1680178232348; Thu, 30 Mar 2023 05:10:32 -0700 (PDT) X-Google-Smtp-Source: AKy350bMdarWbFQgiWBf9UU2jbxruuipwGigykxtPazCewWwVigjXWKr7F2QJl0t60oieRXzf2D3sQ== X-Received: by 2002:a5d:4f82:0:b0:2d7:ef27:427 with SMTP id d2-20020a5d4f82000000b002d7ef270427mr16878129wru.67.1680178232004; Thu, 30 Mar 2023 05:10:32 -0700 (PDT) Received: from localhost (95.72.115.87.dyn.plus.net. [87.115.72.95]) by smtp.gmail.com with ESMTPSA id t3-20020a5d6903000000b002e105c017adsm9238017wru.44.2023.03.30.05.10.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Mar 2023 05:10:31 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 4/4] gdb/python: allow Frame.read_var to accept named arguments Date: Thu, 30 Mar 2023 13:10:23 +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.7 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, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, 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 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 allows Frame.read_var to accept named arguments, and also improves (I think) some of the error messages emitted when values of the wrong type are passed to this function. The read_var method takes two arguments, one a variable, which is either a gdb.Symbol or a string, while the second, optional, argument is always a gdb.Block. I'm now using 'O!' as the format specifier for the second argument, which allows the argument type to be checked early on. Currently, if the second argument is of the wrong type then we get this error: (gdb) python print(gdb.selected_frame().read_var("a1", "xxx")) Traceback (most recent call last): File "", line 1, in RuntimeError: Second argument must be block. Error while executing Python code. (gdb) After this commit, we now get an error like this: (gdb) python print(gdb.selected_frame().read_var("a1", "xxx")) Traceback (most recent call last): File "", line 1, in TypeError: argument 2 must be gdb.Block, not str Error while executing Python code. (gdb) Changes are: 1. Exception type is TypeError not RuntimeError, this is unfortunate as user code _could_ be relying on this, but I think the improvement is worth the risk, user code relying on the exact exception type is likely to be pretty rare, 2. New error message gives argument position and expected argument type, as well as the type that was passed. If the first argument, the variable, has the wrong type then the previous exception was already a TypeError, however, I've updated the text of the exception to more closely match the "standard" error message we see above. If the first argument has the wrong type then before this commit we saw this: (gdb) python print(gdb.selected_frame().read_var(123)) Traceback (most recent call last): File "", line 1, in TypeError: Argument must be a symbol or string. Error while executing Python code. (gdb) And after we see this: (gdb) python print(gdb.selected_frame().read_var(123)) Traceback (most recent call last): File "", line 1, in TypeError: argument 1 must be gdb.Symbol or str, not int Error while executing Python code. (gdb) For existing code that doesn't use named arguments and doesn't rely on exceptions, there will be no changes after this commit. Reviewed-By: Eli Zaretskii --- gdb/doc/python.texi | 2 +- gdb/python/py-frame.c | 28 ++++++++++++---------- gdb/testsuite/gdb.python/py-frame.exp | 34 +++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index f54909cc05d..881c743034e 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -5406,7 +5406,7 @@ object. @end defun -@defun Frame.read_var (variable @r{[}, block@r{]}) +@defun Frame.read_var (@var{variable} @r{[}, @var{block}@r{]}) Return the value of @var{variable} in this frame. If the optional argument @var{block} is provided, search for the variable from that block; otherwise start at the frame's current block (which is diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c index 3a033ac7570..082358effab 100644 --- a/gdb/python/py-frame.c +++ b/gdb/python/py-frame.c @@ -475,15 +475,18 @@ frapy_find_sal (PyObject *self, PyObject *args) gdb.Symbol. The block argument must be an instance of gdb.Block. Returns NULL on error, with a python exception set. */ static PyObject * -frapy_read_var (PyObject *self, PyObject *args) +frapy_read_var (PyObject *self, PyObject *args, PyObject *kw) { frame_info_ptr frame; PyObject *sym_obj, *block_obj = NULL; struct symbol *var = NULL; /* gcc-4.3.2 false warning. */ const struct block *block = NULL; - if (!PyArg_ParseTuple (args, "O|O", &sym_obj, &block_obj)) - return NULL; + static const char *keywords[] = { "variable", "block", nullptr }; + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O|O!", keywords, + &sym_obj, &block_object_type, + &block_obj)) + return nullptr; if (PyObject_TypeCheck (sym_obj, &symbol_object_type)) var = symbol_object_to_symbol (sym_obj); @@ -495,15 +498,13 @@ frapy_read_var (PyObject *self, PyObject *args) if (!var_name) return NULL; - if (block_obj) + if (block_obj != nullptr) { + /* This call should only fail if the type of BLOCK_OBJ is wrong, + and we ensure the type is correct when we parse the arguments, + so we can just assert the return value is not nullptr. */ block = block_object_to_block (block_obj); - if (!block) - { - PyErr_SetString (PyExc_RuntimeError, - _("Second argument must be block.")); - return NULL; - } + gdb_assert (block != nullptr); } try @@ -533,8 +534,9 @@ frapy_read_var (PyObject *self, PyObject *args) } else { - PyErr_SetString (PyExc_TypeError, - _("Argument must be a symbol or string.")); + PyErr_Format (PyExc_TypeError, + _("argument 1 must be gdb.Symbol or str, not %s"), + Py_TYPE (sym_obj)->tp_name); return NULL; } @@ -787,7 +789,7 @@ Return the frame called by this frame." }, { "find_sal", frapy_find_sal, METH_NOARGS, "find_sal () -> gdb.Symtab_and_line.\n\ Return the frame's symtab and line." }, - { "read_var", frapy_read_var, METH_VARARGS, + { "read_var", (PyCFunction) frapy_read_var, METH_VARARGS | METH_KEYWORDS, "read_var (variable) -> gdb.Value.\n\ Return the value of the variable in this frame." }, { "select", frapy_select, METH_NOARGS, diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp index 07997326d09..16177c8a5f8 100644 --- a/gdb/testsuite/gdb.python/py-frame.exp +++ b/gdb/testsuite/gdb.python/py-frame.exp @@ -45,6 +45,10 @@ gdb_test "python print (bf1.read_var(\"i\"))" "\"stuff\"" "test i" gdb_test "python print (bf1.read_var(\"f\"))" "\"foo\"" "test f" gdb_test "python print (bf1.read_var(\"b\"))" "\"bar\"" "test b" +# Check we can use a single named argument with read_var. +gdb_test "python print (bf1.read_var(variable = \"b\"))" "\"bar\"" \ + "test b using named arguments" + # Test the read_var function in another block other than the current # block (in this case, the super block). Test thar read_var is reading # the correct variables of i and f but they are the correct value and type. @@ -54,12 +58,42 @@ gdb_test "python print (bf1.read_var(\"i\", sb).type)" "double" "test double i" gdb_test "python print (bf1.read_var(\"f\", sb))" "2.2.*" "test f = 2.2" gdb_test "python print (bf1.read_var(\"f\", sb).type)" "double" "test double f" +# Now test read_var with a variable and block using named arguments. +gdb_test "python print (bf1.read_var(block = sb, variable = \"i\"))" "1.1.*" \ + "test i = 1.1 usign named arguments" +gdb_test "python print (bf1.read_var(block = sb, variable = \"f\"))" "2.2.*" \ + "test f = 2.2 using named arguments" + # And again test another outerblock, this time testing "i" is the # correct value and type. gdb_py_test_silent_cmd "python sb = sb.superblock" "get superblock" 0 gdb_test "python print (bf1.read_var(\"i\", sb))" "99" "test i = 99" gdb_test "python print (bf1.read_var(\"i\", sb).type)" "int" "test int i" +# Test what happens when we provide a block of the wrong type. +gdb_test "python print (bf1.read_var(\"i\", \"some_block\"))" \ + [multi_line \ + "TypeError: argument 2 must be gdb\\.Block, not str" \ + "Error while executing Python code\\."] \ + "check invalid block type error" +gdb_test "python print (bf1.read_var(block = \"some_block\", variable = \"i\"))" \ + [multi_line \ + "TypeError: argument 2 must be gdb\\.Block, not str" \ + "Error while executing Python code\\."] \ + "check invalid block type error when named args are used" + +# Test what happens when we provide a variable of the wrong type. +gdb_test "python print (bf1.read_var(None))" \ + [multi_line \ + "TypeError: argument 1 must be gdb\\.Symbol or str, not NoneType" \ + "Error while executing Python code\\."] \ + "check read_var error when variable is None" +gdb_test "python print (bf1.read_var(sb))" \ + [multi_line \ + "TypeError: argument 1 must be gdb\\.Symbol or str, not gdb\\.Block" \ + "Error while executing Python code\\."] \ + "check read_var error when variable is a gdb.Block" + gdb_breakpoint "f2" gdb_continue_to_breakpoint "breakpoint at f2" gdb_py_test_silent_cmd "python bframe = gdb.selected_frame()" \