@@ -1028,44 +1028,61 @@ _Py_DumpWideString(int fd, wchar_t *str)
10281028
10291029/* Write a frame into the file fd: "File "xxx", line xxx in xxx".
10301030
1031- This function is signal safe. */
1031+ This function is signal safe.
10321032
1033- static void
1033+ Return 0 on success. Return -1 if the frame is invalid. */
1034+
1035+ static int
10341036dump_frame (int fd , _PyInterpreterFrame * frame )
10351037{
1036- assert (frame -> owner < FRAME_OWNED_BY_INTERPRETER );
1038+ if (frame -> owner == FRAME_OWNED_BY_INTERPRETER ) {
1039+ /* Ignore trampoline frame */
1040+ return 0 ;
1041+ }
10371042
1038- PyCodeObject * code = _PyFrame_GetCode (frame );
1043+ PyCodeObject * code = _PyFrame_SafeGetCode (frame );
1044+ if (code == NULL ) {
1045+ return -1 ;
1046+ }
1047+
1048+ int res = 0 ;
10391049 PUTS (fd , " File " );
10401050 if (code -> co_filename != NULL
10411051 && PyUnicode_Check (code -> co_filename ))
10421052 {
10431053 PUTS (fd , "\"" );
10441054 _Py_DumpASCII (fd , code -> co_filename );
10451055 PUTS (fd , "\"" );
1046- } else {
1056+ }
1057+ else {
10471058 PUTS (fd , "???" );
1059+ res = -1 ;
10481060 }
1049- int lasti = PyUnstable_InterpreterFrame_GetLasti (frame );
1050- int lineno = _PyCode_Addr2LineNoTstate (code , lasti );
1061+
10511062 PUTS (fd , ", line " );
1063+ int lasti = _PyFrame_SafeGetLasti (frame );
1064+ int lineno = -1 ;
1065+ if (lasti >= 0 ) {
1066+ lineno = _PyCode_SafeAddr2Line (code , lasti );
1067+ }
10521068 if (lineno >= 0 ) {
10531069 _Py_DumpDecimal (fd , (size_t )lineno );
10541070 }
10551071 else {
10561072 PUTS (fd , "???" );
1073+ res = -1 ;
10571074 }
1058- PUTS (fd , " in " );
10591075
1060- if ( code -> co_name != NULL
1061- && PyUnicode_Check (code -> co_name )) {
1076+ PUTS ( fd , " in " );
1077+ if ( code -> co_name != NULL && PyUnicode_Check (code -> co_name )) {
10621078 _Py_DumpASCII (fd , code -> co_name );
10631079 }
10641080 else {
10651081 PUTS (fd , "???" );
1082+ res = -1 ;
10661083 }
1067-
10681084 PUTS (fd , "\n" );
1085+ return res ;
10691086}
10701087
10711088static int
@@ -1108,17 +1125,6 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header)
11081125
11091126 unsigned int depth = 0 ;
11101127 while (1 ) {
1111- if (frame -> owner == FRAME_OWNED_BY_INTERPRETER ) {
1112- /* Trampoline frame */
1113- frame = frame -> previous ;
1114- if (frame == NULL ) {
1115- break ;
1116- }
1117-
1118- /* Can't have more than one shim frame in a row */
1119- assert (frame -> owner != FRAME_OWNED_BY_INTERPRETER );
1120- }
1121-
11221128 if (MAX_FRAME_DEPTH <= depth ) {
11231129 if (MAX_FRAME_DEPTH < depth ) {
11241130 PUTS (fd , "plus " );
@@ -1128,7 +1134,15 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header)
11281134 break ;
11291135 }
11301136
1131- dump_frame (fd , frame );
1137+ if (_PyMem_IsPtrFreed (frame )) {
1138+ PUTS (fd , " <freed frame>\n" );
1139+ break ;
1140+ }
1141+ if (dump_frame (fd , frame ) < 0 ) {
1142+ PUTS (fd , " <invalid frame>\n" );
1143+ break ;
1144+ }
1145+
11321146 frame = frame -> previous ;
11331147 if (frame == NULL ) {
11341148 break ;
0 commit comments