Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions 3 Modules/faulthandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,6 @@ faulthandler_dump_traceback(int fd, int all_threads,
PyInterpreterState *interp)
{
static volatile int reentrant = 0;
PyThreadState *tstate;

if (reentrant)
return;
Expand All @@ -246,7 +245,7 @@ faulthandler_dump_traceback(int fd, int all_threads,
fault if the thread released the GIL, and so this function cannot be
used. Read the thread specific storage (TSS) instead: call
PyGILState_GetThisThreadState(). */
tstate = PyGILState_GetThisThreadState();
PyThreadState *tstate = PyGILState_GetThisThreadState();

if (all_threads) {
(void)_Py_DumpTracebackThreads(fd, NULL, tstate);
Expand Down
48 changes: 38 additions & 10 deletions 48 Python/traceback.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -1234,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");
Expand Down Expand Up @@ -1305,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.
Expand All @@ -1323,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();
Expand All @@ -1337,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
{
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.