From e61cceeeacea42566240bc7635bc8cc2f4168cf1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 15 Aug 2014 23:30:40 +0200 Subject: Issue #22156: Fix "comparison between signed and unsigned integers" compiler warnings in the Python/ subdirectory. --- Python/traceback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Python/traceback.c') diff --git a/Python/traceback.c b/Python/traceback.c index 2ece192db9..565094b1e8 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -198,7 +198,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * } strcpy(namebuf, PyBytes_AS_STRING(path)); Py_DECREF(path); - if (strlen(namebuf) != len) + if (strlen(namebuf) != (size_t)len) continue; /* v contains '\0' */ if (len > 0 && namebuf[len-1] != SEP) namebuf[len++] = SEP; -- cgit v1.2.1 From 877cbd7f86a2234c5b834a72d5425b81374921e9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 3 Oct 2014 14:18:09 +0200 Subject: faulthandler: enhance dump_ascii() to escape also non-printable ASCII characters (U+0000..U+001f and U+007f). --- Python/traceback.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'Python/traceback.c') diff --git a/Python/traceback.c b/Python/traceback.c index 565094b1e8..5d60dade4c 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -541,15 +541,16 @@ dump_ascii(int fd, PyObject *text) ch = PyUnicode_READ(kind, data, i); else ch = wstr[i]; - if (ch < 128) { + if (' ' <= ch && ch <= 126) { + /* printable ASCII character */ char c = (char)ch; write(fd, &c, 1); } - else if (ch < 0xff) { + else if (ch <= 0xff) { PUTS(fd, "\\x"); dump_hexadecimal(fd, ch, 2); } - else if (ch < 0xffff) { + else if (ch <= 0xffff) { PUTS(fd, "\\u"); dump_hexadecimal(fd, ch, 4); } @@ -644,7 +645,7 @@ write_thread_id(int fd, PyThreadState *tstate, int is_current) PUTS(fd, "Current thread 0x"); else PUTS(fd, "Thread 0x"); - dump_hexadecimal(fd, (unsigned long)tstate->thread_id, sizeof(long)*2); + dump_hexadecimal(fd, (unsigned long)tstate->thread_id, sizeof(unsigned long)*2); PUTS(fd, " (most recent call first):\n"); } -- cgit v1.2.1 From 33e32cfef754465ea947a41f9731180f04d6ecf8 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 1 Apr 2015 18:38:01 +0200 Subject: Issue #23836: Use _Py_write_noraise() to retry on EINTR in _Py_DumpTraceback() and _Py_DumpTracebackThreads(). Document also these functions to explain that the caller is responsible to call PyErr_CheckSignals(). --- Python/traceback.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'Python/traceback.c') diff --git a/Python/traceback.c b/Python/traceback.c index ef7b9f5880..d69feb95fd 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -13,7 +13,7 @@ #define OFF(x) offsetof(PyTracebackObject, x) -#define PUTS(fd, str) write(fd, str, (int)strlen(str)) +#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) #define MAX_STRING_LENGTH 500 #define MAX_FRAME_DEPTH 100 #define MAX_NTHREADS 100 @@ -512,7 +512,7 @@ dump_decimal(int fd, int value) len++; } while (value); reverse_string(buffer, len); - write(fd, buffer, len); + _Py_write_noraise(fd, buffer, len); } /* Format an integer in range [0; 0xffffffff] to hexadecimal of 'width' digits, @@ -532,7 +532,7 @@ dump_hexadecimal(int fd, unsigned long value, int width) len++; } while (len < width || value); reverse_string(buffer, len); - write(fd, buffer, len); + _Py_write_noraise(fd, buffer, len); } /* Write an unicode object into the file fd using ascii+backslashreplace. @@ -585,7 +585,7 @@ dump_ascii(int fd, PyObject *text) if (' ' <= ch && ch <= 126) { /* printable ASCII character */ char c = (char)ch; - write(fd, &c, 1); + _Py_write_noraise(fd, &c, 1); } else if (ch <= 0xff) { PUTS(fd, "\\x"); @@ -619,9 +619,9 @@ dump_frame(int fd, PyFrameObject *frame) if (code != NULL && code->co_filename != NULL && PyUnicode_Check(code->co_filename)) { - write(fd, "\"", 1); + PUTS(fd, "\""); dump_ascii(fd, code->co_filename); - write(fd, "\"", 1); + PUTS(fd, "\""); } else { PUTS(fd, "???"); } @@ -638,7 +638,7 @@ dump_frame(int fd, PyFrameObject *frame) else PUTS(fd, "???"); - write(fd, "\n", 1); + PUTS(fd, "\n"); } static void @@ -668,6 +668,12 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header) } } +/* Dump the traceback of a Python thread into fd. Use write() to write the + traceback and retry if write() is interrupted by a signal (failed with + EINTR), but don't call the Python signal handler. + + The caller is responsible to call PyErr_CheckSignals() to call Python signal + handlers if signals were received. */ void _Py_DumpTraceback(int fd, PyThreadState *tstate) { @@ -690,6 +696,12 @@ write_thread_id(int fd, PyThreadState *tstate, int is_current) PUTS(fd, " (most recent call first):\n"); } +/* Dump the traceback of all Python threads into fd. Use write() to write the + traceback and retry if write() is interrupted by a signal (failed with + EINTR), but don't call the Python signal handler. + + The caller is responsible to call PyErr_CheckSignals() to call Python signal + handlers if signals were received. */ const char* _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, PyThreadState *current_thread) @@ -708,7 +720,7 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, do { if (nthreads != 0) - write(fd, "\n", 1); + PUTS(fd, "\n"); if (nthreads >= MAX_NTHREADS) { PUTS(fd, "...\n"); break; -- cgit v1.2.1 From e07a52f272f00b6707b40f557e481749b73dd0fd Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Sun, 12 Apr 2015 00:26:27 -0400 Subject: Issue #23524: Replace _PyVerify_fd function with calls to _set_thread_local_invalid_parameter_handler. --- Python/traceback.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Python/traceback.c') diff --git a/Python/traceback.c b/Python/traceback.c index d69feb95fd..71ffecd74a 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -717,6 +717,7 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, /* Dump the traceback of each thread */ tstate = PyInterpreterState_ThreadHead(interp); nthreads = 0; + _Py_BEGIN_SUPPRESS_IPH do { if (nthreads != 0) @@ -730,6 +731,7 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, tstate = PyThreadState_Next(tstate); nthreads++; } while (tstate != NULL); + _Py_END_SUPPRESS_IPH return NULL; } -- cgit v1.2.1 From 6cf5f5721762a4f21679137869fa1ee78cba0a9c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 18 Oct 2016 13:23:18 +0300 Subject: Issue #23782: Fixed possible memory leak in _PyTraceback_Add() and exception loss in PyTraceBack_Here(). --- Python/traceback.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'Python/traceback.c') diff --git a/Python/traceback.c b/Python/traceback.c index 941d1cbbbb..9e7fe3b5c6 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -132,47 +132,53 @@ newtracebackobject(PyTracebackObject *next, PyFrameObject *frame) int PyTraceBack_Here(PyFrameObject *frame) { - PyThreadState *tstate = PyThreadState_GET(); - PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback; - PyTracebackObject *tb = newtracebackobject(oldtb, frame); - if (tb == NULL) + PyObject *exc, *val, *tb, *newtb; + PyErr_Fetch(&exc, &val, &tb); + newtb = (PyObject *)newtracebackobject((PyTracebackObject *)tb, frame); + if (newtb == NULL) { + _PyErr_ChainExceptions(exc, val, tb); return -1; - tstate->curexc_traceback = (PyObject *)tb; - Py_XDECREF(oldtb); + } + PyErr_Restore(exc, val, newtb); + Py_XDECREF(tb); return 0; } /* Insert a frame into the traceback for (funcname, filename, lineno). */ void _PyTraceback_Add(const char *funcname, const char *filename, int lineno) { - PyObject *globals = NULL; - PyCodeObject *code = NULL; - PyFrameObject *frame = NULL; - PyObject *exception, *value, *tb; + PyObject *globals; + PyCodeObject *code; + PyFrameObject *frame; + PyObject *exc, *val, *tb; /* Save and clear the current exception. Python functions must not be called with an exception set. Calling Python functions happens when the codec of the filesystem encoding is implemented in pure Python. */ - PyErr_Fetch(&exception, &value, &tb); + PyErr_Fetch(&exc, &val, &tb); globals = PyDict_New(); if (!globals) - goto done; + goto error; code = PyCode_NewEmpty(filename, funcname, lineno); - if (!code) - goto done; + if (!code) { + Py_DECREF(globals); + goto error; + } frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL); + Py_DECREF(globals); + Py_DECREF(code); if (!frame) - goto done; + goto error; frame->f_lineno = lineno; - PyErr_Restore(exception, value, tb); + PyErr_Restore(exc, val, tb); PyTraceBack_Here(frame); + Py_DECREF(frame); + return; -done: - Py_XDECREF(globals); - Py_XDECREF(code); - Py_XDECREF(frame); +error: + _PyErr_ChainExceptions(exc, val, tb); } static PyObject * -- cgit v1.2.1