mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	GH-116098: Remove dead frame object creation code (GH-116687)
This commit is contained in:
		
							parent
							
								
									149f7f7ae2
								
							
						
					
					
						commit
						a53cc3f494
					
				
					 2 changed files with 9 additions and 83 deletions
				
			
		|  | @ -37,24 +37,15 @@ _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame) | |||
|         return NULL; | ||||
|     } | ||||
|     PyErr_SetRaisedException(exc); | ||||
|     if (frame->frame_obj) { | ||||
|         // GH-97002: How did we get into this horrible situation? Most likely,
 | ||||
|         // allocating f triggered a GC collection, which ran some code that
 | ||||
|         // *also* created the same frame... while we were in the middle of
 | ||||
|         // creating it! See test_sneaky_frame_object in test_frame.py for a
 | ||||
|         // concrete example.
 | ||||
|         //
 | ||||
|         // Regardless, just throw f away and use that frame instead, since it's
 | ||||
|         // already been exposed to user code. It's actually a bit tricky to do
 | ||||
|         // this, since we aren't backed by a real _PyInterpreterFrame anymore.
 | ||||
|         // Just pretend that we have an owned, cleared frame so frame_dealloc
 | ||||
|         // doesn't make the situation worse:
 | ||||
|         f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data; | ||||
|         f->f_frame->owner = FRAME_CLEARED; | ||||
|         f->f_frame->frame_obj = f; | ||||
|         Py_DECREF(f); | ||||
|         return frame->frame_obj; | ||||
|     } | ||||
| 
 | ||||
|     // GH-97002: There was a time when a frame object could be created when we
 | ||||
|     // are allocating the new frame object f above, so frame->frame_obj would
 | ||||
|     // be assigned already. That path does not exist anymore. We won't call any
 | ||||
|     // Python code in this function and garbage collection will not run.
 | ||||
|     // Notice that _PyFrame_New_NoTrack() can potentially raise a MemoryError,
 | ||||
|     // but it won't allocate a traceback until the frame unwinds, so we are safe
 | ||||
|     // here.
 | ||||
|     assert(frame->frame_obj == NULL); | ||||
|     assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); | ||||
|     assert(frame->owner != FRAME_CLEARED); | ||||
|     f->f_frame = frame; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Tian Gao
						Tian Gao