mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Issue #23566: enable(), register(), dump_traceback() and dump_traceback_later()
functions of faulthandler now accept file descriptors. Patch by Wei Wu.
This commit is contained in:
parent
ebaa81f3b1
commit
95bb714ff7
5 changed files with 172 additions and 78 deletions
|
@ -133,32 +133,46 @@ static stack_t stack;
|
|||
call its flush() method.
|
||||
|
||||
If file is NULL or Py_None, use sys.stderr as the new file.
|
||||
If file is an integer, it will be treated as file descriptor.
|
||||
|
||||
On success, return the new file and write the file descriptor into *p_fd.
|
||||
On error, return NULL. */
|
||||
On success, return the file descriptor and write the new file into *file_ptr.
|
||||
On error, return -1. */
|
||||
|
||||
static PyObject*
|
||||
faulthandler_get_fileno(PyObject *file, int *p_fd)
|
||||
static int
|
||||
faulthandler_get_fileno(PyObject **file_ptr)
|
||||
{
|
||||
PyObject *result;
|
||||
long fd_long;
|
||||
int fd;
|
||||
PyObject *file = *file_ptr;
|
||||
|
||||
if (file == NULL || file == Py_None) {
|
||||
file = _PySys_GetObjectId(&PyId_stderr);
|
||||
if (file == NULL) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "unable to get sys.stderr");
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
if (file == Py_None) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "sys.stderr is None");
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (PyLong_Check(file)) {
|
||||
fd = _PyLong_AsInt(file);
|
||||
if (fd == -1 && PyErr_Occurred())
|
||||
return -1;
|
||||
if (fd < 0 || !_PyVerify_fd(fd)) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"file is not a valid file descripter");
|
||||
return -1;
|
||||
}
|
||||
*file_ptr = NULL;
|
||||
return fd;
|
||||
}
|
||||
|
||||
result = _PyObject_CallMethodId(file, &PyId_fileno, "");
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
return -1;
|
||||
|
||||
fd = -1;
|
||||
if (PyLong_Check(result)) {
|
||||
|
@ -171,7 +185,7 @@ faulthandler_get_fileno(PyObject *file, int *p_fd)
|
|||
if (fd == -1) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"file.fileno() is not a valid file descriptor");
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = _PyObject_CallMethodId(file, &PyId_flush, "");
|
||||
|
@ -181,8 +195,8 @@ faulthandler_get_fileno(PyObject *file, int *p_fd)
|
|||
/* ignore flush() error */
|
||||
PyErr_Clear();
|
||||
}
|
||||
*p_fd = fd;
|
||||
return file;
|
||||
*file_ptr = file;
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Get the state of the current thread: only call this function if the current
|
||||
|
@ -215,8 +229,8 @@ faulthandler_dump_traceback_py(PyObject *self,
|
|||
&file, &all_threads))
|
||||
return NULL;
|
||||
|
||||
file = faulthandler_get_fileno(file, &fd);
|
||||
if (file == NULL)
|
||||
fd = faulthandler_get_fileno(&file);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
tstate = get_thread_state();
|
||||
|
@ -339,8 +353,8 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
"|Oi:enable", kwlist, &file, &all_threads))
|
||||
return NULL;
|
||||
|
||||
file = faulthandler_get_fileno(file, &fd);
|
||||
if (file == NULL)
|
||||
fd = faulthandler_get_fileno(&file);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
tstate = get_thread_state();
|
||||
|
@ -348,7 +362,7 @@ faulthandler_enable(PyObject *self, PyObject *args, PyObject *kwargs)
|
|||
return NULL;
|
||||
|
||||
Py_XDECREF(fatal_error.file);
|
||||
Py_INCREF(file);
|
||||
Py_XINCREF(file);
|
||||
fatal_error.file = file;
|
||||
fatal_error.fd = fd;
|
||||
fatal_error.all_threads = all_threads;
|
||||
|
@ -553,8 +567,8 @@ faulthandler_dump_traceback_later(PyObject *self,
|
|||
if (tstate == NULL)
|
||||
return NULL;
|
||||
|
||||
file = faulthandler_get_fileno(file, &fd);
|
||||
if (file == NULL)
|
||||
fd = faulthandler_get_fileno(&file);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
/* format the timeout */
|
||||
|
@ -567,7 +581,7 @@ faulthandler_dump_traceback_later(PyObject *self,
|
|||
cancel_dump_traceback_later();
|
||||
|
||||
Py_XDECREF(thread.file);
|
||||
Py_INCREF(file);
|
||||
Py_XINCREF(file);
|
||||
thread.file = file;
|
||||
thread.fd = fd;
|
||||
thread.timeout_us = timeout_us;
|
||||
|
@ -737,8 +751,8 @@ faulthandler_register_py(PyObject *self,
|
|||
if (tstate == NULL)
|
||||
return NULL;
|
||||
|
||||
file = faulthandler_get_fileno(file, &fd);
|
||||
if (file == NULL)
|
||||
fd = faulthandler_get_fileno(&file);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
if (user_signals == NULL) {
|
||||
|
@ -760,7 +774,7 @@ faulthandler_register_py(PyObject *self,
|
|||
}
|
||||
|
||||
Py_XDECREF(user->file);
|
||||
Py_INCREF(file);
|
||||
Py_XINCREF(file);
|
||||
user->file = file;
|
||||
user->fd = fd;
|
||||
user->all_threads = all_threads;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue