mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +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; |     _Py_Finalizing = tstate; | ||||||
|     initialized = 0; |     initialized = 0; | ||||||
| 
 | 
 | ||||||
|     /* Flush stdout+stderr */ |     /* Flush sys.stdout and sys.stderr */ | ||||||
|     flush_std_files(); |     flush_std_files(); | ||||||
| 
 | 
 | ||||||
|     /* Disable signal handling */ |     /* Disable signal handling */ | ||||||
|  | @ -575,7 +575,7 @@ Py_Finalize(void) | ||||||
|     /* Destroy all modules */ |     /* Destroy all modules */ | ||||||
|     PyImport_Cleanup(); |     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(); |     flush_std_files(); | ||||||
| 
 | 
 | ||||||
|     /* Collect final garbage.  This disposes of cycles created by
 |     /* Collect final garbage.  This disposes of cycles created by
 | ||||||
|  | @ -1253,6 +1253,7 @@ initstdio(void) | ||||||
| static void | static void | ||||||
| _Py_PrintFatalError(int fd) | _Py_PrintFatalError(int fd) | ||||||
| { | { | ||||||
|  |     PyObject *ferr, *res; | ||||||
|     PyObject *exception, *v, *tb; |     PyObject *exception, *v, *tb; | ||||||
|     int has_tb; |     int has_tb; | ||||||
|     PyThreadState *tstate; |     PyThreadState *tstate; | ||||||
|  | @ -1263,6 +1264,13 @@ _Py_PrintFatalError(int fd) | ||||||
|         goto display_stack; |         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); |     PyErr_NormalizeException(&exception, &v, &tb); | ||||||
|     if (tb == NULL) { |     if (tb == NULL) { | ||||||
|         tb = Py_None; |         tb = Py_None; | ||||||
|  | @ -1270,7 +1278,7 @@ _Py_PrintFatalError(int fd) | ||||||
|     } |     } | ||||||
|     PyException_SetTraceback(v, tb); |     PyException_SetTraceback(v, tb); | ||||||
|     if (exception == NULL) { |     if (exception == NULL) { | ||||||
|         /* too bad, PyErr_NormalizeException() failed */ |         /* PyErr_NormalizeException() failed */ | ||||||
|         goto display_stack; |         goto display_stack; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -1279,6 +1287,14 @@ _Py_PrintFatalError(int fd) | ||||||
|     Py_XDECREF(exception); |     Py_XDECREF(exception); | ||||||
|     Py_XDECREF(v); |     Py_XDECREF(v); | ||||||
|     Py_XDECREF(tb); |     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) |     if (has_tb) | ||||||
|         return; |         return; | ||||||
| 
 | 
 | ||||||
|  | @ -1307,10 +1323,16 @@ Py_FatalError(const char *msg) | ||||||
|     fprintf(stderr, "Fatal Python error: %s\n", msg); |     fprintf(stderr, "Fatal Python error: %s\n", msg); | ||||||
|     fflush(stderr); /* it helps in Windows debug build */ |     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); |     _Py_PrintFatalError(fd); | ||||||
| 
 | 
 | ||||||
|  |     /* Flush sys.stdout and sys.stderr */ | ||||||
|  |     flush_std_files(); | ||||||
|  | 
 | ||||||
|     /* The main purpose of faulthandler is to display the traceback. We already
 |     /* 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(); |     _PyFaulthandler_Fini(); | ||||||
| 
 | 
 | ||||||
| #ifdef MS_WINDOWS | #ifdef MS_WINDOWS | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner