Skip to content

Commit

Permalink
bpo-45831: _Py_DumpASCII() uses a single write() call if possible (GH…
Browse files Browse the repository at this point in the history
…-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 b919d81)

Co-authored-by: Victor Stinner <vstinner@python.org>
  • Loading branch information
miss-islington and vstinner committed Nov 17, 2021
1 parent 1079b3e commit 4ffde90
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -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.
22 changes: 22 additions & 0 deletions Python/traceback.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -740,6 +760,8 @@ _Py_DumpASCII(int fd, PyObject *text)
_Py_DumpHexadecimal(fd, ch, 8);
}
}

done:
if (truncated) {
PUTS(fd, "...");
}
Expand Down

0 comments on commit 4ffde90

Please sign in to comment.