8000 bpo-45831: _Py_DumpASCII() uses a single write() call if possible (GH… · python/cpython@b919d81 · GitHub
[go: up one dir, main page]

Skip to content

Commit b919d81

Browse files
authored
bpo-45831: _Py_DumpASCII() uses a single write() call if possible (GH-29596)
If the string is ASCII only and doesn't need to escape characters, write the whole string with a single write() syscall.
1 parent e002bbc commit b919d81

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
:mod:`faulthandler` can now write ASCII-only strings (like filenames and
2+
function names) with a single write() syscall when dumping a traceback. It
3+
reduces the risk of getting an unreadable dump when two threads or two
4+
processes dump a traceback to the same file (like stderr) at the same time.
5+
Patch by Victor Stinner.

Python/traceback.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,26 @@ _Py_DumpASCII(int fd, PyObject *text)
10721072
truncated = 0;
10731073
}
10741074

1075+
// Is an ASCII string?
1076+
if (ascii->state.ascii) {
1077+
assert(kind == PyUnicode_1BYTE_KIND);
1078+
char *str = data;
1079+
1080+
int need_escape = 0;
1081+
for (i=0; i < size; i++) {
1082+
ch = str[i];
1083+
if (!(' ' <= ch && ch <= 126)) {
1084+
need_escape = 1;
1085+
break;
1086+
}
1087+
}
1088+
if (!need_escape) {
1089+
// The string can be written with a single write() syscall
1090+
_Py_write_noraise(fd, str, size);
1091+
goto done;
1092+
}
1093+
}
1094+
10751095
for (i=0; i < size; i++) {
10761096
if (kind != PyUnicode_WCHAR_KIND)
10771097
ch = PyUnicode_READ(kind, data, i);
@@ -1095,6 +1115,8 @@ _Py_DumpASCII(int fd, PyObject *text)
10951115
_Py_DumpHexadecimal(fd, ch, 8);
10961116
}
10971117
}
1118+
1119+
done:
10981120
if (truncated) {
10991121
PUTS(fd, "...");
11001122
}

0 commit comments

Comments
 (0)
0