mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	(Merge 3.4) Issue #23571: Py_FatalError() now tries to flush sys.stdout and
sys.stderr It should help to see exceptions when stderr if buffered: PyErr_Display() calls sys.stderr.write(), it doesn't write into stderr file descriptor directly.
This commit is contained in:
		
						commit
						e0deff31d3
					
				
					 1 changed files with 26 additions and 4 deletions
				
			
		|  | @ -546,7 +546,7 @@ Py_Finalize(void) | |||
|     _Py_Finalizing = tstate; | ||||
|     initialized = 0; | ||||
| 
 | ||||
|     /* Flush stdout+stderr */ | ||||
|     /* Flush sys.stdout and sys.stderr */ | ||||
|     flush_std_files(); | ||||
| 
 | ||||
|     /* Disable signal handling */ | ||||
|  | @ -575,7 +575,7 @@ Py_Finalize(void) | |||
|     /* Destroy all modules */ | ||||
|     PyImport_Cleanup(); | ||||
| 
 | ||||
|     /* Flush stdout+stderr (again, in case more was printed) */ | ||||
|     /* Flush sys.stdout and sys.stderr (again, in case more was printed) */ | ||||
|     flush_std_files(); | ||||
| 
 | ||||
|     /* Collect final garbage.  This disposes of cycles created by
 | ||||
|  | @ -1253,6 +1253,7 @@ initstdio(void) | |||
| static void | ||||
| _Py_PrintFatalError(int fd) | ||||
| { | ||||
|     PyObject *ferr, *res; | ||||
|     PyObject *exception, *v, *tb; | ||||
|     int has_tb; | ||||
|     PyThreadState *tstate; | ||||
|  | @ -1263,6 +1264,13 @@ _Py_PrintFatalError(int fd) | |||
|         goto display_stack; | ||||
|     } | ||||
| 
 | ||||
|     ferr = _PySys_GetObjectId(&PyId_stderr); | ||||
|     if (ferr == NULL || ferr == Py_None) { | ||||
|         /* sys.stderr is not set yet or set to None,
 | ||||
|            no need to try to display the exception */ | ||||
|         goto display_stack; | ||||
|     } | ||||
| 
 | ||||
|     PyErr_NormalizeException(&exception, &v, &tb); | ||||
|     if (tb == NULL) { | ||||
|         tb = Py_None; | ||||
|  | @ -1270,7 +1278,7 @@ _Py_PrintFatalError(int fd) | |||
|     } | ||||
|     PyException_SetTraceback(v, tb); | ||||
|     if (exception == NULL) { | ||||
|         /* too bad, PyErr_NormalizeException() failed */ | ||||
|         /* PyErr_NormalizeException() failed */ | ||||
|         goto display_stack; | ||||
|     } | ||||
| 
 | ||||
|  | @ -1279,6 +1287,14 @@ _Py_PrintFatalError(int fd) | |||
|     Py_XDECREF(exception); | ||||
|     Py_XDECREF(v); | ||||
|     Py_XDECREF(tb); | ||||
| 
 | ||||
|     /* sys.stderr may be buffered: call sys.stderr.flush() */ | ||||
|     res = _PyObject_CallMethodId(ferr, &PyId_flush, ""); | ||||
|     if (res == NULL) | ||||
|         PyErr_Clear(); | ||||
|     else | ||||
|         Py_DECREF(res); | ||||
| 
 | ||||
|     if (has_tb) | ||||
|         return; | ||||
| 
 | ||||
|  | @ -1307,10 +1323,16 @@ Py_FatalError(const char *msg) | |||
|     fprintf(stderr, "Fatal Python error: %s\n", msg); | ||||
|     fflush(stderr); /* it helps in Windows debug build */ | ||||
| 
 | ||||
|     /* Print the exception (if an exception is set) with its traceback,
 | ||||
|      * or display the current Python stack. */ | ||||
|     _Py_PrintFatalError(fd); | ||||
| 
 | ||||
|     /* Flush sys.stdout and sys.stderr */ | ||||
|     flush_std_files(); | ||||
| 
 | ||||
|     /* The main purpose of faulthandler is to display the traceback. We already
 | ||||
|      * did our best to display it. So faulthandler can now be disabled. */ | ||||
|      * did our best to display it. So faulthandler can now be disabled. | ||||
|      * (Don't trigger it on abort().) */ | ||||
|     _PyFaulthandler_Fini(); | ||||
| 
 | ||||
| #ifdef MS_WINDOWS | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner