def find_frame(thread_id, frame_id): """ returns a frame on the thread that has a given frame_id """ try: curr_thread_id = get_thread_id(threading.currentThread()) if thread_id != curr_thread_id: try: return get_custom_frame(thread_id, frame_id) # I.e.: thread_id could be a stackless frame id + thread_id. except: pass raise VariableError("find_frame: must execute on same thread (%s != %s)" % (thread_id, curr_thread_id)) lookingFor = int(frame_id) if AdditionalFramesContainer.additional_frames: if dict_contains(AdditionalFramesContainer.additional_frames, thread_id): frame = AdditionalFramesContainer.additional_frames[thread_id].get(lookingFor) if frame is not None: return frame curFrame = get_frame() if frame_id == "*": return curFrame # any frame is specified with "*" frameFound = None for frame in _iter_frames(curFrame): if lookingFor == id(frame): frameFound = frame del frame break del frame # Important: python can hold a reference to the frame from the current context # if an exception is raised, so, if we don't explicitly add those deletes # we might have those variables living much more than we'd want to. # I.e.: sys.exc_info holding reference to frame that raises exception (so, other places # need to call sys.exc_clear()) del curFrame if frameFound is None: msgFrames = '' i = 0 for frame in _iter_frames(get_frame()): i += 1 msgFrames += str(id(frame)) if i % 5 == 0: msgFrames += '\n' else: msgFrames += ' - ' errMsg = '''find_frame: frame not found. Looking for thread_id:%s, frame_id:%s Current thread_id:%s, available frames: %s\n ''' % (thread_id, lookingFor, curr_thread_id, msgFrames) sys.stderr.write(errMsg) return None return frameFound except: import traceback traceback.print_exc() return None
def find_frame(thread_id, frame_id): """ returns a frame on the thread that has a given frame_id """ try: curr_thread_id = get_current_thread_id(threading.current_thread()) if thread_id != curr_thread_id: try: return get_custom_frame( thread_id, frame_id ) # I.e.: thread_id could be a stackless frame id + thread_id. except: pass raise VariableError( "find_frame: must execute on same thread (%s != %s)" % (thread_id, curr_thread_id)) lookingFor = int(frame_id) if AdditionalFramesContainer.additional_frames: if thread_id in AdditionalFramesContainer.additional_frames: frame = AdditionalFramesContainer.additional_frames[ thread_id].get(lookingFor) if frame is not None: return frame curFrame = get_frame() if frame_id == "*": return curFrame # any frame is specified with "*" frameFound = None for frame in _iter_frames(curFrame): if lookingFor == id(frame): frameFound = frame del frame break del frame # Important: python can hold a reference to the frame from the current context # if an exception is raised, so, if we don't explicitly add those deletes # we might have those variables living much more than we'd want to. # I.e.: sys.exc_info holding reference to frame that raises exception (so, other places # need to call sys.exc_clear()) del curFrame if frameFound is None: msgFrames = '' i = 0 for frame in _iter_frames(get_frame()): i += 1 msgFrames += str(id(frame)) if i % 5 == 0: msgFrames += '\n' else: msgFrames += ' - ' # Note: commented this error message out (it may commonly happen # if a message asking for a frame is issued while a thread is paused # but the thread starts running before the message is actually # handled). # Leaving code to uncomment during tests. # err_msg = '''find_frame: frame not found. # Looking for thread_id:%s, frame_id:%s # Current thread_id:%s, available frames: # %s\n # ''' % (thread_id, lookingFor, curr_thread_id, msgFrames) # # sys.stderr.write(err_msg) return None return frameFound except: import traceback traceback.print_exc() return None