diff options
author | shadchin <shadchin@yandex-team.com> | 2023-10-03 23:32:21 +0300 |
---|---|---|
committer | shadchin <shadchin@yandex-team.com> | 2023-10-03 23:48:51 +0300 |
commit | 01ffd024041ac933854c367fb8d1b5682d19883f (patch) | |
tree | b70aa497ba132a133ccece49f7763427dcd0743f /contrib/tools/python3/src/Python/traceback.c | |
parent | a33fdb9a34581fd124e92535153b1f1fdeca6aaf (diff) | |
download | ydb-01ffd024041ac933854c367fb8d1b5682d19883f.tar.gz |
Update Python 3 to 3.11.6
Diffstat (limited to 'contrib/tools/python3/src/Python/traceback.c')
-rw-r--r-- | contrib/tools/python3/src/Python/traceback.c | 65 |
1 files changed, 55 insertions, 10 deletions
diff --git a/contrib/tools/python3/src/Python/traceback.c b/contrib/tools/python3/src/Python/traceback.c index 7f47349a27..c4f5ec877b 100644 --- a/contrib/tools/python3/src/Python/traceback.c +++ b/contrib/tools/python3/src/Python/traceback.c @@ -12,6 +12,7 @@ #include "pycore_parser.h" // _PyParser_ASTFromString #include "pycore_pyarena.h" // _PyArena_Free() #include "pycore_pyerrors.h" // _PyErr_Fetch() +#include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_traceback.h" // EXCEPTION_TB_HEADER @@ -621,6 +622,11 @@ extract_anchors_from_expr(const char *segment_str, expr_ty expr, Py_ssize_t *lef ++*right_anchor; } + // Keep going if the current char is not ')' + if (i+1 < right->col_offset && (segment_str[i] == ')')) { + continue; + } + // Set the error characters *primary_error_char = "~"; *secondary_error_char = "^"; @@ -631,6 +637,18 @@ extract_anchors_from_expr(const char *segment_str, expr_ty expr, Py_ssize_t *lef case Subscript_kind: { *left_anchor = expr->v.Subscript.value->end_col_offset; *right_anchor = expr->v.Subscript.slice->end_col_offset + 1; + Py_ssize_t str_len = strlen(segment_str); + + // Move right_anchor and left_anchor forward to the first non-whitespace character that is not ']' and '[' + while (*left_anchor < str_len && (IS_WHITESPACE(segment_str[*left_anchor]) || segment_str[*left_anchor] != '[')) { + ++*left_anchor; + } + while (*right_anchor < str_len && (IS_WHITESPACE(segment_str[*right_anchor]) || segment_str[*right_anchor] != ']')) { + ++*right_anchor; + } + if (*right_anchor < str_len){ + *right_anchor += 1; + } // Set the error characters *primary_error_char = "~"; @@ -1217,23 +1235,45 @@ dump_frame(int fd, _PyInterpreterFrame *frame) PUTS(fd, "\n"); } +static int +tstate_is_freed(PyThreadState *tstate) +{ + if (_PyMem_IsPtrFreed(tstate)) { + return 1; + } + if (_PyMem_IsPtrFreed(tstate->interp)) { + return 1; + } + return 0; +} + + +static int +interp_is_freed(PyInterpreterState *interp) +{ + return _PyMem_IsPtrFreed(interp); +} + + static void dump_traceback(int fd, PyThreadState *tstate, int write_header) { - _PyInterpreterFrame *frame; - unsigned int depth; - if (write_header) { PUTS(fd, "Stack (most recent call first):\n"); } - frame = tstate->cframe->current_frame; + if (tstate_is_freed(tstate)) { + PUTS(fd, " <tstate is freed>\n"); + return; + } + + _PyInterpreterFrame *frame = tstate->cframe->current_frame; if (frame == NULL) { PUTS(fd, " <no Python frame>\n"); return; } - depth = 0; + unsigned int depth = 0; while (1) { if (MAX_FRAME_DEPTH <= depth) { PUTS(fd, " ...\n"); @@ -1288,9 +1328,6 @@ const char* _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, PyThreadState *current_tstate) { - PyThreadState *tstate; - unsigned int nthreads; - if (current_tstate == NULL) { /* _Py_DumpTracebackThreads() is called from signal handlers by faulthandler. @@ -1306,6 +1343,10 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, current_tstate = PyGILState_GetThisThreadState(); } + if (current_tstate != NULL && tstate_is_freed(current_tstate)) { + return "tstate is freed"; + } + if (interp == NULL) { if (current_tstate == NULL) { interp = _PyGILState_GetInterpreterStateUnsafe(); @@ -1320,14 +1361,18 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, } assert(interp != NULL); + if (interp_is_freed(interp)) { + return "interp is freed"; + } + /* Get the current interpreter from the current thread */ - tstate = PyInterpreterState_ThreadHead(interp); + PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); if (tstate == NULL) return "unable to get the thread head state"; /* Dump the traceback of each thread */ tstate = PyInterpreterState_ThreadHead(interp); - nthreads = 0; + unsigned int nthreads = 0; _Py_BEGIN_SUPPRESS_IPH do { |