From: Tom de Vries <tdevries@suse.de>
To: gdb-patches@sourceware.org
Subject: [PATCH 1/2] [gdb/python] Handle normalized exception returned by PyErr_Fetch
Date: Mon, 4 Mar 2024 17:03:46 +0100 [thread overview]
Message-ID: <20240304160347.31182-1-tdevries@suse.de> (raw)
With python 3.12 and test-case gdb.python/py-block.exp, before commit
a207f6b3a38 ("Rewrite "python" command exception handling"), we had:
...
(gdb) python print (block['nonexistent'])^M
Traceback (most recent call last):^M
File "<string>", line 1, in <module>^M
KeyError: 'nonexistent'^M
Error while executing Python code.^M
(gdb) PASS: gdb.python/py-block.exp: check nonexistent variable
...
but after the commit we have:
...
(gdb) python print (block['nonexistent'])^M
Python Exception <class 'KeyError'>: 'nonexistent'^M
Error occurred in Python: 'nonexistent'^M
(gdb) FAIL: gdb.python/py-block.exp: check nonexistent variable
...
In contrast, with python 3.6 we have:
...
(gdb) python print (block['nonexistent'])^M
Python Exception <class 'KeyError'>: nonexistent^M
Error occurred in Python: nonexistent^M
(gdb) PASS: gdb.python/py-block.exp: check nonexistent variable
...
The change in the test-case is:
...
-gdb_test "python print (block\['nonexistent'\])" ".*KeyError: 'nonexistent'.*" \
+gdb_test "python print (block\['nonexistent'\])" ".*KeyError.*: nonexistent.*" \
"check nonexistent variable"
...
which drops the single quotes around the nonexistent string, which matches the
output with python 3.6, but not with python 3.12.
The difference is caused by a difference in the result of PyErr_Fetch.
[ PyErr_Fetch is deprecated in python 3.12, this will be addressed in a
follow-up commit. ]
With python 3.6, we have PyErr_Fetch returning:
...
(gdb) p PyObject_Print(error_value, stderr, 0)
'nonexistent'$3 = 0
(gdb) p PyObject_Print(error_value, stderr, 1)
nonexistent$4 = 0
...
but with python 3.12, we have instead:
...
(gdb) p (int)PyObject_Print(error_value,stderr, 0)
KeyError('nonexistent')$3 = 0
(gdb) p (int)PyObject_Print(error_value,stderr, 1)
'nonexistent'$4 = 0
...
In more detail, with python 3.12 we get a normalized exception, so the
error_value is an object of class KeyError. With python 3.6, error_value is
an unnormalized exception, meaning not of class KeyError.
Apparantly we rely here on PyErr_Fetch to return an unnormalized exception.
Fix this by pretending to have an unnormalized exception in
gdbpy_err_fetch::to_string.
Tested on aarch64-linux.
PR python/31425
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31425
---
gdb/python/py-utils.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c
index 9382eb62a5f..8eee33f89bb 100644
--- a/gdb/python/py-utils.c
+++ b/gdb/python/py-utils.c
@@ -196,7 +196,19 @@ gdbpy_err_fetch::to_string () const
gdb.GdbError ("message"). */
if (m_error_value.get () != nullptr && m_error_value.get () != Py_None)
- return gdbpy_obj_to_string (m_error_value.get ());
+ {
+ if ((PyObject *)Py_TYPE (m_error_value.get ()) == m_error_type.get ())
+ {
+ /* Detected a normalized exception. */
+ PyObject *args = PyException_GetArgs (m_error_value.get ());
+ if (PyTuple_Size (args) == 1)
+ {
+ /* Pretend to be looking at an unnormalized exception. */
+ return gdbpy_obj_to_string (PyTuple_GetItem (args, 0));
+ }
+ }
+ return gdbpy_obj_to_string (m_error_value.get ());
+ }
else
return gdbpy_obj_to_string (m_error_type.get ());
}
base-commit: 1485a3fb63619cced99dd7a4a043cf01a0f423d9
--
2.35.3
next reply other threads:[~2024-03-04 16:03 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-04 16:03 Tom de Vries [this message]
2024-03-04 16:03 ` [PATCH 2/2] [gdb/python] Handle deprecation of PyErr_{Fetch,Restore} in 3.12 Tom de Vries
2024-03-04 18:48 ` [PATCH 2/2] [gdb/python] Handle deprecation of PyErr_{Fetch, Restore} " Tom Tromey
2024-03-08 15:36 ` Tom de Vries
2024-03-04 18:40 ` [PATCH 1/2] [gdb/python] Handle normalized exception returned by PyErr_Fetch Tom Tromey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240304160347.31182-1-tdevries@suse.de \
--to=tdevries@suse.de \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).