@@ -1825,16 +1825,46 @@ _Py_FatalError_PrintExc(int fd)
1825
1825
1826
1826
/* Print fatal error message and abort */
1827
1827
1828
+ #ifdef MS_WINDOWS
1829
+ static void
1830
+ fatal_output_debug (const char * msg )
1831
+ {
1832
+ /* buffer of 256 bytes allocated on the stack */
1833
+ WCHAR buffer [256 / sizeof (WCHAR )];
1834
+ size_t buflen = Py_ARRAY_LENGTH (buffer ) - 1 ;
1835
+ size_t msglen ;
1836
+
1837
+ OutputDebugStringW (L"Fatal Python error: " );
1838
+
1839
+ msglen = strlen (msg );
1840
+ while (msglen ) {
1841
+ size_t i ;
1842
+
1843
+ if (buflen > msglen ) {
1844
+ buflen = msglen ;
1845
+ }
1846
+
1847
+ /* Convert the message to wchar_t. This uses a simple one-to-one
1848
+ conversion, assuming that the this error message actually uses
1849
+ ASCII only. If this ceases to be true, we will have to convert. */
1850
+ for (i = 0 ; i < buflen ; ++ i ) {
1851
+ buffer [i ] = msg [i ];
1852
+ }
1853
+ buffer [i ] = L'\0' ;
1854
+ OutputDebugStringW (buffer );
1855
+
1856
+ msg += buflen ;
1857
+ msglen -= buflen ;
1858
+ }
1859
+ OutputDebugStringW (L"\n" );
1860
+ }
1861
+ #endif
1862
+
1828
1863
void
1829
1864
Py_FatalError (const char * msg )
1830
1865
{
1831
1866
const int fd = fileno (stderr );
1832
1867
static int reentrant = 0 ;
1833
- #ifdef MS_WINDOWS
1834
- size_t len ;
1835
- WCHAR * buffer ;
1836
- size_t i ;
1837
- #endif
1838
1868
1839
1869
if (reentrant ) {
1840
1870
/* Py_FatalError() caused a second fatal error.
@@ -1848,12 +1878,14 @@ Py_FatalError(const char *msg)
1848
1878
1849
1879
/* Print the exception (if an exception is set) with its traceback,
1850
1880
* or display the current Python stack. */
1851
- if (!_Py_FatalError_PrintExc (fd ))
1881
+ if (!_Py_FatalError_PrintExc (fd )) {
1852
1882
_Py_FatalError_DumpTracebacks (fd );
1883
+ }
1853
1884
1854
- /* The main purpose of faulthandler is to display the traceback. We already
1855
- * did our best to display it. So faulthandler can now be disabled.
1856
- * (Don't trigger it on abort().) */
1885
+ /* The main purpose of faulthandler is to display the traceback.
1886
+ This function already did its best to display a traceback.
1887
+ Disable faulthandler to prevent writing a second traceback
1888
+ on abort(). */
1857
1889
_PyFaulthandler_Fini ();
1858
1890
1859
1891
/* Check if the current Python thread hold the GIL */
@@ -1863,17 +1895,7 @@ Py_FatalError(const char *msg)
1863
1895
}
1864
1896
1865
1897
#ifdef MS_WINDOWS
1866
- len = strlen (msg );
1867
-
1868
- /* Convert the message to wchar_t. This uses a simple one-to-one
1869
- conversion, assuming that the this error message actually uses ASCII
1870
- only. If this ceases to be true, we will have to convert. */
1871
- buffer = alloca ( (len + 1 ) * (sizeof * buffer ));
1872
- for ( i = 0 ; i <=len ; ++ i )
1873
- buffer [i ] = msg [i ];
1874
- OutputDebugStringW (L"Fatal Python error: " );
1875
- OutputDebugStringW (buffer );
1876
- OutputDebugStringW (L"\n" );
1898
+ fatal_output_debug (msg );
1877
1899
#endif /* MS_WINDOWS */
1878
1900
1879
1901
exit :
0 commit comments