diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index b7554d698c9..2b1c6cd0c38 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -168,7 +168,11 @@ class DebuggerTests(unittest.TestCase): commands += ['set print entry-values no'] if cmds_after_breakpoint: - commands += cmds_after_breakpoint + # bpo-32962: When Python is compiled with -mcet -fcf-protection, + # arguments are unusable before running the first instruction + # of the function entry point. The 'next' command makes the + # required first step. + commands += ['next'] + cmds_after_breakpoint else: commands += ['backtrace'] @@ -859,9 +863,12 @@ id(42) id("first break point") l = MyList() ''') + # bpo-32962: same case as in get_stack_trace(): + # we need an additional 'next' command in order to read + # arguments of the innermost function of the call stack. # Verify with "py-bt": gdb_output = self.get_stack_trace(cmd, - cmds_after_breakpoint=['break wrapper_call', 'continue', 'py-bt']) + cmds_after_breakpoint=['break wrapper_call', 'continue', 'next', 'py-bt']) self.assertRegex(gdb_output, r"' def safe_tp_name(self): try: return self.field('self')['ob_type']['tp_name'].string() - except (NullPyObjectPtr, RuntimeError): + except (NullPyObjectPtr, RuntimeError, UnicodeDecodeError): return '' def safe_self_addresss(self): @@ -1541,6 +1547,7 @@ class Frame(object): return False if caller == 'PyCFunction_Call': + arg_name = 'func' # Within that frame: # "func" is the local containing the PyObject* of the # PyCFunctionObject instance @@ -1548,24 +1555,35 @@ class Frame(object): # "self" is the (PyObject*) of the 'self' try: # Use the prettyprinter for the func: - func = frame.read_var('func') + func = frame.read_var(arg_name) return str(func) + except ValueError: + return ('PyCFunction invocation (unable to read %s: ' + 'missing debuginfos?)' % arg_name) except RuntimeError: - return 'PyCFunction invocation (unable to read "func")' + return 'PyCFunction invocation (unable to read %s)' % arg_name elif caller == '_PyCFunction_FastCallDict': + arg_name = 'func_obj' try: - func = frame.read_var('func_obj') + func = frame.read_var(arg_name) return str(func) + except ValueError: + return ('PyCFunction invocation (unable to read %s: ' + 'missing debuginfos?)' % arg_name) except RuntimeError: - return 'PyCFunction invocation (unable to read "func_obj")' + return 'PyCFunction invocation (unable to read %s)' % arg_name if caller == 'wrapper_call': + arg_name = 'wp' try: - func = frame.read_var('wp') + func = frame.read_var(arg_name) return str(func) + except ValueError: + return ('' % arg_name) except RuntimeError: - return '' + return '' % arg_name # This frame isn't worth reporting: return False