bpo-31683: Py_FatalError() now supports long error messages (#3878)
On Windows, Py_FatalError() now limits the size to 256 bytes of the buffer used to call OutputDebugStringW(). Previously, the size depended on the length of the error message.
This commit is contained in:
parent
bf477a99e0
commit
8d5a3aad2f
@ -1825,16 +1825,46 @@ _Py_FatalError_PrintExc(int fd)
|
|||||||
|
|
||||||
/* Print fatal error message and abort */
|
/* Print fatal error message and abort */
|
||||||
|
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
static void
|
||||||
|
fatal_output_debug(const char *msg)
|
||||||
|
{
|
||||||
|
/* buffer of 256 bytes allocated on the stack */
|
||||||
|
WCHAR buffer[256 / sizeof(WCHAR)];
|
||||||
|
size_t buflen = Py_ARRAY_LENGTH(buffer) - 1;
|
||||||
|
size_t msglen;
|
||||||
|
|
||||||
|
OutputDebugStringW(L"Fatal Python error: ");
|
||||||
|
|
||||||
|
msglen = strlen(msg);
|
||||||
|
while (msglen) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (buflen > msglen) {
|
||||||
|
buflen = msglen;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert the message to wchar_t. This uses a simple one-to-one
|
||||||
|
conversion, assuming that the this error message actually uses
|
||||||
|
ASCII only. If this ceases to be true, we will have to convert. */
|
||||||
|
for (i=0; i < buflen; ++i) {
|
||||||
|
buffer[i] = msg[i];
|
||||||
|
}
|
||||||
|
buffer[i] = L'\0';
|
||||||
|
OutputDebugStringW(buffer);
|
||||||
|
|
||||||
|
msg += buflen;
|
||||||
|
msglen -= buflen;
|
||||||
|
}
|
||||||
|
OutputDebugStringW(L"\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
Py_FatalError(const char *msg)
|
Py_FatalError(const char *msg)
|
||||||
{
|
{
|
||||||
const int fd = fileno(stderr);
|
const int fd = fileno(stderr);
|
||||||
static int reentrant = 0;
|
static int reentrant = 0;
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
size_t len;
|
|
||||||
WCHAR* buffer;
|
|
||||||
size_t i;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (reentrant) {
|
if (reentrant) {
|
||||||
/* Py_FatalError() caused a second fatal error.
|
/* Py_FatalError() caused a second fatal error.
|
||||||
@ -1848,12 +1878,14 @@ Py_FatalError(const char *msg)
|
|||||||
|
|
||||||
/* Print the exception (if an exception is set) with its traceback,
|
/* Print the exception (if an exception is set) with its traceback,
|
||||||
* or display the current Python stack. */
|
* or display the current Python stack. */
|
||||||
if (!_Py_FatalError_PrintExc(fd))
|
if (!_Py_FatalError_PrintExc(fd)) {
|
||||||
_Py_FatalError_DumpTracebacks(fd);
|
_Py_FatalError_DumpTracebacks(fd);
|
||||||
|
}
|
||||||
|
|
||||||
/* The main purpose of faulthandler is to display the traceback. We already
|
/* The main purpose of faulthandler is to display the traceback.
|
||||||
* did our best to display it. So faulthandler can now be disabled.
|
This function already did its best to display a traceback.
|
||||||
* (Don't trigger it on abort().) */
|
Disable faulthandler to prevent writing a second traceback
|
||||||
|
on abort(). */
|
||||||
_PyFaulthandler_Fini();
|
_PyFaulthandler_Fini();
|
||||||
|
|
||||||
/* Check if the current Python thread hold the GIL */
|
/* Check if the current Python thread hold the GIL */
|
||||||
@ -1863,17 +1895,7 @@ Py_FatalError(const char *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
len = strlen(msg);
|
fatal_output_debug(msg);
|
||||||
|
|
||||||
/* Convert the message to wchar_t. This uses a simple one-to-one
|
|
||||||
conversion, assuming that the this error message actually uses ASCII
|
|
||||||
only. If this ceases to be true, we will have to convert. */
|
|
||||||
buffer = alloca( (len+1) * (sizeof *buffer));
|
|
||||||
for( i=0; i<=len; ++i)
|
|
||||||
buffer[i] = msg[i];
|
|
||||||
OutputDebugStringW(L"Fatal Python error: ");
|
|
||||||
OutputDebugStringW(buffer);
|
|
||||||
OutputDebugStringW(L"\n");
|
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user