bpo-45831: _Py_DumpASCII() uses a single write() call if possible (GH-29596) (GH-29598)

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 b919d8105c)

Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
Miss Islington (bot) 2021-11-17 13:59:19 -08:00 committed by GitHub
parent 1079b3e3cb
commit 4ffde90dcc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 0 deletions

View file

@ -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.

View file

@ -717,6 +717,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);
@ -740,6 +760,8 @@ _Py_DumpASCII(int fd, PyObject *text)
_Py_DumpHexadecimal(fd, ch, 8);
}
}
done:
if (truncated) {
PUTS(fd, "...");
}