[Python-checkins] bpo-45831: _Py_DumpASCII() uses a single write() call if possible (GH-29596) (GH-29597)
ambv
webhook-mailer at python.org
Wed Nov 17 17:00:03 EST 2021
https://github.com/python/cpython/commit/ac89f8cab79800195687dd141de472f90c626ec3
commit: ac89f8cab79800195687dd141de472f90c626ec3
branch: 3.9
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: ambv <lukasz at langa.pl>
date: 2021-11-17T22:59:42+01:00
summary:
bpo-45831: _Py_DumpASCII() uses a single write() call if possible (GH-29596) (GH-29597)
If the string is ASCII only and doesn't need to escape characters,
write the whole string with a single write() syscall.
(cherry picked from commit b919d8105c4d77f00509b6d3ab2073f09db640de)
Co-authored-by: Victor Stinner <vstinner at python.org>
files:
A Misc/NEWS.d/next/Library/2021-11-17-19-25-37.bpo-45831.9-TojK.rst
M Python/traceback.c
diff --git a/Misc/NEWS.d/next/Library/2021-11-17-19-25-37.bpo-45831.9-TojK.rst b/Misc/NEWS.d/next/Library/2021-11-17-19-25-37.bpo-45831.9-TojK.rst
new file mode 100644
index 0000000000000..049449ff0a4a1
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-11-17-19-25-37.bpo-45831.9-TojK.rst
@@ -0,0 +1,5 @@
+:mod:`faulthandler` can now write ASCII-only strings (like filenames and
+function names) with a single write() syscall when dumping a traceback. It
+reduces the risk of getting an unreadable dump when two threads or two
+processes dump a traceback to the same file (like stderr) at the same time.
+Patch by Victor Stinner.
diff --git a/Python/traceback.c b/Python/traceback.c
index 83f3074f43d05..23d0e38e7377c 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -719,6 +719,26 @@ _Py_DumpASCII(int fd, PyObject *text)
truncated = 0;
}
+ // Is an ASCII string?
+ if (ascii->state.ascii) {
+ assert(kind == PyUnicode_1BYTE_KIND);
+ char *str = data;
+
+ int need_escape = 0;
+ for (i=0; i < size; i++) {
+ ch = str[i];
+ if (!(' ' <= ch && ch <= 126)) {
+ need_escape = 1;
+ break;
+ }
+ }
+ if (!need_escape) {
+ // The string can be written with a single write() syscall
+ _Py_write_noraise(fd, str, size);
+ goto done;
+ }
+ }
+
for (i=0; i < size; i++) {
if (kind != PyUnicode_WCHAR_KIND)
ch = PyUnicode_READ(kind, data, i);
@@ -742,6 +762,8 @@ _Py_DumpASCII(int fd, PyObject *text)
_Py_DumpHexadecimal(fd, ch, 8);
}
}
+
+done:
if (truncated) {
PUTS(fd, "...");
}
More information about the Python-checkins
mailing list