mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-26558: Fix Py_FatalError() with GIL released (GH-10267)
Don't call _Py_FatalError_PrintExc() nor flush_std_files() if the current thread doesn't hold the GIL, or if the current thread has no Python state thread.
This commit is contained in:
		
							parent
							
								
									2be00d987d
								
							
						
					
					
						commit
						3a228ab17c
					
				
					 1 changed files with 25 additions and 10 deletions
				
			
		|  | @ -1820,12 +1820,6 @@ _Py_FatalError_PrintExc(int fd) | ||||||
|     PyObject *exception, *v, *tb; |     PyObject *exception, *v, *tb; | ||||||
|     int has_tb; |     int has_tb; | ||||||
| 
 | 
 | ||||||
|     if (PyThreadState_GET() == NULL) { |  | ||||||
|         /* The GIL is released: trying to acquire it is likely to deadlock,
 |  | ||||||
|            just give up. */ |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     PyErr_Fetch(&exception, &v, &tb); |     PyErr_Fetch(&exception, &v, &tb); | ||||||
|     if (exception == NULL) { |     if (exception == NULL) { | ||||||
|         /* No current exception */ |         /* No current exception */ | ||||||
|  | @ -1930,9 +1924,30 @@ fatal_error(const char *prefix, const char *msg, int status) | ||||||
|     fputs("\n", stderr); |     fputs("\n", stderr); | ||||||
|     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,
 |     /* Check if the current thread has a Python thread state
 | ||||||
|      * or display the current Python stack. */ |        and holds the GIL */ | ||||||
|     if (!_Py_FatalError_PrintExc(fd)) { |     PyThreadState *tss_tstate = PyGILState_GetThisThreadState(); | ||||||
|  |     if (tss_tstate != NULL) { | ||||||
|  |         PyThreadState *tstate = PyThreadState_GET(); | ||||||
|  |         if (tss_tstate != tstate) { | ||||||
|  |             /* The Python thread does not hold the GIL */ | ||||||
|  |             tss_tstate = NULL; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         /* Py_FatalError() has been called from a C thread
 | ||||||
|  |            which has no Python thread state. */ | ||||||
|  |     } | ||||||
|  |     int has_tstate_and_gil = (tss_tstate != NULL); | ||||||
|  | 
 | ||||||
|  |     if (has_tstate_and_gil) { | ||||||
|  |         /* If an exception is set, print the exception with its traceback */ | ||||||
|  |         if (!_Py_FatalError_PrintExc(fd)) { | ||||||
|  |             /* No exception is set, or an exception is set without traceback */ | ||||||
|  |             _Py_FatalError_DumpTracebacks(fd); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|         _Py_FatalError_DumpTracebacks(fd); |         _Py_FatalError_DumpTracebacks(fd); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -1943,7 +1958,7 @@ fatal_error(const char *prefix, const char *msg, int status) | ||||||
|     _PyFaulthandler_Fini(); |     _PyFaulthandler_Fini(); | ||||||
| 
 | 
 | ||||||
|     /* Check if the current Python thread hold the GIL */ |     /* Check if the current Python thread hold the GIL */ | ||||||
|     if (PyThreadState_GET() != NULL) { |     if (has_tstate_and_gil) { | ||||||
|         /* Flush sys.stdout and sys.stderr */ |         /* Flush sys.stdout and sys.stderr */ | ||||||
|         flush_std_files(); |         flush_std_files(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner