Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9699440

Browse files
author
Victor Stinner
committed
faulthandler: check PyThreadState_Get() result in dump_tracebacks_later()
Cleanup also the code
1 parent 0df8092 commit 9699440

1 file changed

Lines changed: 21 additions & 12 deletions

File tree

Modules/faulthandler.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
#include <frameobject.h>
66
#include <signal.h>
77

8+
/* Allocate at maximum 100 MB of the stack to raise the stack overflow */
9+
#define STACK_OVERFLOW_MAX_SIZE (100*1024*1024)
10+
811
#ifdef WITH_THREAD
912
# define FAULTHANDLER_LATER
1013
#endif
@@ -16,9 +19,6 @@
1619
# define FAULTHANDLER_USER
1720
#endif
1821

19-
/* Allocate at maximum 100 MB of the stack to raise the stack overflow */
20-
#define STACK_OVERFLOW_MAX_SIZE (100*1024*1024)
21-
2222
#define PUTS(fd, str) write(fd, str, strlen(str))
2323

2424
#ifdef HAVE_SIGACTION
@@ -451,8 +451,8 @@ faulthandler_cancel_dump_tracebacks_later(void)
451451
}
452452

453453
static PyObject*
454-
faulthandler_dump_traceback_later(PyObject *self,
455-
PyObject *args, PyObject *kwargs)
454+
faulthandler_dump_tracebacks_later(PyObject *self,
455+
PyObject *args, PyObject *kwargs)
456456
{
457457
static char *kwlist[] = {"timeout", "repeat", "file", "exit", NULL};
458458
double timeout;
@@ -461,6 +461,7 @@ faulthandler_dump_traceback_later(PyObject *self,
461461
PyObject *file = NULL;
462462
int fd;
463463
int exit = 0;
464+
PyThreadState *tstate;
464465

465466
if (!PyArg_ParseTupleAndKeywords(args, kwargs,
466467
"d|iOi:dump_tracebacks_later", kwlist,
@@ -477,6 +478,13 @@ faulthandler_dump_traceback_later(PyObject *self,
477478
return NULL;
478479
}
479480

481+
tstate = PyThreadState_Get();
482+
if (tstate == NULL) {
483+
PyErr_SetString(PyExc_RuntimeError,
484+
"unable to get the current thread state");
485+
return NULL;
486+
}
487+
480488
file = faulthandler_get_fileno(file, &fd);
481489
if (file == NULL)
482490
return NULL;
@@ -490,7 +498,7 @@ faulthandler_dump_traceback_later(PyObject *self,
490498
thread.fd = fd;
491499
thread.timeout_ms = timeout_ms;
492500
thread.repeat = repeat;
493-
thread.interp = PyThreadState_Get()->interp;
501+
thread.interp = tstate->interp;
494502
thread.exit = exit;
495503

496504
/* Arm these locks to serve as events when released */
@@ -826,16 +834,16 @@ static int
826834
faulthandler_traverse(PyObject *module, visitproc visit, void *arg)
827835
{
828836
#ifdef FAULTHANDLER_USER
829-
unsigned int index;
837+
unsigned int signum;
830838
#endif
831839

832840
#ifdef FAULTHANDLER_LATER
833841
Py_VISIT(thread.file);
834842
#endif
835843
#ifdef FAULTHANDLER_USER
836844
if (user_signals != NULL) {
837-
for (index=0; index < NSIG; index++)
838-
Py_VISIT(user_signals[index].file);
845+
for (signum=0; signum < NSIG; signum++)
846+
Py_VISIT(user_signals[signum].file);
839847
}
840848
#endif
841849
Py_VISIT(fatal_error.file);
@@ -861,10 +869,11 @@ static PyMethodDef module_methods[] = {
861869
"if all_threads is True, into file")},
862870
#ifdef FAULTHANDLER_LATER
863871
{"dump_tracebacks_later",
864-
(PyCFunction)faulthandler_dump_traceback_later, METH_VARARGS|METH_KEYWORDS,
865-
PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderr):\n"
872+
(PyCFunction)faulthandler_dump_tracebacks_later, METH_VARARGS|METH_KEYWORDS,
873+
PyDoc_STR("dump_tracebacks_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n"
866874
"dump the traceback of all threads in timeout seconds,\n"
867-
"or each timeout seconds if repeat is True.")},
875+
"or each timeout seconds if repeat is True. If exit is True, "
876+
"call _exit(1) which is not safe.")},
868877
{"cancel_dump_tracebacks_later",
869878
(PyCFunction)faulthandler_cancel_dump_tracebacks_later_py, METH_NOARGS,
870879
PyDoc_STR("cancel_dump_tracebacks_later():\ncancel the previous call "

0 commit comments

Comments
 (0)