@@ -976,44 +976,61 @@ _Py_DumpASCII(int fd, PyObject *text)
976976
977977/* Write a frame into the file fd: "File "xxx", line xxx in xxx".
978978
979- This function is signal safe. */
979+ This function is signal safe.
980980
981- static void
981+ Return 0 on success. Return -1 if the frame is invalid. */
982+
983+ static int
982984dump_frame (int fd , _PyInterpreterFrame * frame )
983985{
984- assert (frame -> owner < FRAME_OWNED_BY_INTERPRETER );
986+ if (frame -> owner == FRAME_OWNED_BY_INTERPRETER ) {
987+ /* Ignore trampoline frame */
988+ return 0 ;
989+ }
985990
986- PyCodeObject * code = _PyFrame_GetCode (frame );
991+ PyCodeObject * code = _PyFrame_SafeGetCode (frame );
992+ if (code == NULL ) {
993+ return -1 ;
994+ }
995+
996+ int res = 0 ;
987997 PUTS (fd , " File " );
988998 if (code -> co_filename != NULL
989999 && PyUnicode_Check (code -> co_filename ))
9901000 {
9911001 PUTS (fd , "\"" );
9921002 _Py_DumpASCII (fd , code -> co_filename );
9931003 PUTS (fd , "\"" );
994- } else {
1004+ }
1005+ else {
9951006 PUTS (fd , "???" );
1007+ res = -1 ;
9961008 }
997- int lasti = PyUnstable_InterpreterFrame_GetLasti (frame );
998- int lineno = _PyCode_Addr2LineNoTstate (code , lasti );
1009+
9991010 PUTS (fd , ", line " );
1011+ int lasti = _PyFrame_SafeGetLasti (frame );
1012+ int lineno = -1 ;
1013+ if (lasti >= 0 ) {
1014+ lineno = _PyCode_SafeAddr2Line (code , lasti );
1015+ }
10001016 if (lineno >= 0 ) {
10011017 _Py_DumpDecimal (fd , (size_t )lineno );
10021018 }
10031019 else {
10041020 PUTS (fd , "???" );
1021+ res = -1 ;
10051022 }
1006- PUTS (fd , " in " );
10071023
1008- if ( code -> co_name != NULL
1009- && PyUnicode_Check (code -> co_name )) {
1024+ PUTS ( fd , " in " );
1025+ if ( code -> co_name != NULL && PyUnicode_Check (code -> co_name )) {
10101026 _Py_DumpASCII (fd , code -> co_name );
10111027 }
10121028 else {
10131029 PUTS (fd , "???" );
1030+ res = -1 ;
10141031 }
1015-
10161032 PUTS (fd , "\n" );
1033+ return res ;
10171034}
10181035
10191036static int
@@ -1056,17 +1073,6 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header)
10561073
10571074 unsigned int depth = 0 ;
10581075 while (1 ) {
1059- if (frame -> owner == FRAME_OWNED_BY_INTERPRETER ) {
1060- /* Trampoline frame */
1061- frame = frame -> previous ;
1062- if (frame == NULL ) {
1063- break ;
1064- }
1065-
1066- /* Can't have more than one shim frame in a row */
1067- assert (frame -> owner != FRAME_OWNED_BY_INTERPRETER );
1068- }
1069-
10701076 if (MAX_FRAME_DEPTH <= depth ) {
10711077 if (MAX_FRAME_DEPTH < depth ) {
10721078 PUTS (fd , "plus " );
@@ -1076,7 +1082,15 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header)
10761082 break ;
10771083 }
10781084
1079- dump_frame (fd , frame );
1085+ if (_PyMem_IsPtrFreed (frame )) {
1086+ PUTS (fd , " <freed frame>\n" );
1087+ break ;
1088+ }
1089+ if (dump_frame (fd , frame ) < 0 ) {
1090+ PUTS (fd , " <invalid frame>\n" );
1091+ break ;
1092+ }
1093+
10801094 frame = frame -> previous ;
10811095 if (frame == NULL ) {
10821096 break ;
0 commit comments