summaryrefslogtreecommitdiffstats
path: root/Lib/pdb.py
diff options
context:
space:
mode:
authorTian Gao <gaogaotiantian@hotmail.com>2023-10-18 23:42:36 (GMT)
committerGitHub <noreply@github.com>2023-10-18 23:42:36 (GMT)
commitfabfc2ccfc50e58284da48db9cb63f9dd58606a6 (patch)
tree44e48671a91853446a5ad8f41fcd39900d1b55e1 /Lib/pdb.py
parentfaa7c207bfe6b04c88f8440d95c36739ae69d518 (diff)
downloadcpython-fabfc2ccfc50e58284da48db9cb63f9dd58606a6.zip
cpython-fabfc2ccfc50e58284da48db9cb63f9dd58606a6.tar.gz
cpython-fabfc2ccfc50e58284da48db9cb63f9dd58606a6.tar.bz2
[3.11] GH-65052: Prevent pdb from crashing when trying to display objects (GH-111002)
(cherry picked from commit c523ce0f434582580a3721e15cb7dd6b56ad0236)
Diffstat (limited to 'Lib/pdb.py')
-rwxr-xr-xLib/pdb.py23
1 files changed, 16 insertions, 7 deletions
diff --git a/Lib/pdb.py b/Lib/pdb.py
index fe9eab9..5dfe507 100755
--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -405,8 +405,9 @@ class Pdb(bdb.Bdb, cmd.Cmd):
# fields are changed to be displayed
if newvalue is not oldvalue and newvalue != oldvalue:
displaying[expr] = newvalue
- self.message('display %s: %r [old: %r]' %
- (expr, newvalue, oldvalue))
+ self.message('display %s: %s [old: %s]' %
+ (expr, self._safe_repr(newvalue, expr),
+ self._safe_repr(oldvalue, expr)))
def interaction(self, frame, traceback):
# Restore the previous signal handler at the Pdb prompt.
@@ -1221,7 +1222,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
for i in range(n):
name = co.co_varnames[i]
if name in dict:
- self.message('%s = %r' % (name, dict[name]))
+ self.message('%s = %s' % (name, self._safe_repr(dict[name], name)))
else:
self.message('%s = *** undefined ***' % (name,))
do_a = do_args
@@ -1231,7 +1232,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
Print the return value for the last return of a function.
"""
if '__return__' in self.curframe_locals:
- self.message(repr(self.curframe_locals['__return__']))
+ self.message(self._safe_repr(self.curframe_locals['__return__'], "retval"))
else:
self.error('Not yet returned!')
do_rv = do_retval
@@ -1268,6 +1269,12 @@ class Pdb(bdb.Bdb, cmd.Cmd):
except:
self._error_exc()
+ def _safe_repr(self, obj, expr):
+ try:
+ return repr(obj)
+ except Exception as e:
+ return _rstr(f"*** repr({expr}) failed: {self._format_exc(e)} ***")
+
def do_p(self, arg):
"""p expression
Print the value of the expression.
@@ -1438,12 +1445,12 @@ class Pdb(bdb.Bdb, cmd.Cmd):
"""
if not arg:
self.message('Currently displaying:')
- for item in self.displaying.get(self.curframe, {}).items():
- self.message('%s: %r' % item)
+ for key, val in self.displaying.get(self.curframe, {}).items():
+ self.message('%s: %s' % (key, self._safe_repr(val, key)))
else:
val = self._getval_except(arg)
self.displaying.setdefault(self.curframe, {})[arg] = val
- self.message('display %s: %r' % (arg, val))
+ self.message('display %s: %s' % (arg, self._safe_repr(val, arg)))
complete_display = _complete_expression
@@ -1645,6 +1652,8 @@ class Pdb(bdb.Bdb, cmd.Cmd):
self.run(target.code)
+ def _format_exc(self, exc: BaseException):
+ return traceback.format_exception_only(exc)[-1].strip()
def _getsourcelines(self, obj):
# GH-103319