def do_frame(self, arg): """frame [thread-Name|thread-number] [frame-number] Move the current frame to the specified frame number. If a Thread-Name is given, move the current frame to that. Dot (.) can be used to indicate the name of the current frame. A thread number can be used in Python 2.5 or greater. 0 is the most recent frame. A negative number indicates position from the other end. So 'frame -1' moves when gdb dialect is in effect moves to the oldest frame, and 'frame 0' moves to the newest frame.""" args = arg.split() if len(args) > 0: thread_name = args[0] try: thread_id = int(thread_name) if hasattr(sys, '_current_frames'): threads = sys._current_frames() if thread_id not in threads.keys(): self.errmsg("I don't know about thread number %s" % thread_name) self.info_thread_terse() return frame = threads[thread_id] newframe = find_nondebug_frame(self, frame) if newframe is not None: frame = newframe self.stack, self.curindex = self.get_stack(frame, None) if len(args) == 1: arg = '0' else: arg = ' '.join(args[1:]) except ValueError: # Must be frame command without a frame number if thread_name == '.': thread_name = threading.currentThread().getName() if thread_name not in self.traced.keys(): self.errmsg("I don't know about thread %s" % thread_name) return thread_id = self.traced[thread_name] if hasattr(sys, '_current_frames'): frames = sys._current_frames() if thread_id in frames.keys(): self.curframe_thread_name = thread_name frame = frames[thread_id] else: self.errmsg("Frame selection not supported. Upgrade to") self.errmsg("Python 2.5 or install threadframe.") return newframe = find_nondebug_frame(self, frame) if newframe is not None: frame = newframe self.stack, self.curindex = self.get_stack(frame, None) if len(args) == 1: arg = '0' else: arg = ' '.join(args[1:]) self.thread_name = threading.currentThread().getName() pydb.Pdb.do_frame(self, arg)
def wrapped(*args, **kwargs): old_threads = set(sys._current_frames().keys()) res = func(*args, **kwargs) new_threads = set(sys._current_frames().keys()) new_threads -= old_threads global_exclude_thread_ids.update(new_threads) return res
def metrics(self): metrics = {} # get total threads metrics['totalThreads'] = len(sys._current_frames().keys()) # get free threads freeThreads = 0 for frame in sys._current_frames().values(): _self = frame.f_locals.get('self') if getattr(_self, '__module__', None) == ZRendevous.__module__: freeThreads += 1 metrics['freeThreads'] = freeThreads try: metrics['activeSessions'] = len(self.context.unrestrictedTraverse('/temp_folder/session_data')) except Exception: metrics['activeSessions'] = -1 global _REQUEST_TOTAL, _REQUEST_COUNT, _REQUEST_TIME metrics["requestTotal"] = _REQUEST_TOTAL metrics["request1m"] = max(_REQUEST_COUNT.query(60), 1) metrics["requestTimeAvg1m"] = _REQUEST_TIME.query(60) / float(metrics["request1m"]) for key, value in self._getVmStats(): metrics[key] = value return metrics
def test_current_frames(self): import sys import time import thread # XXX workaround for now: to prevent deadlocks, call # sys._current_frames() once before starting threads. # This is an issue in non-translated versions only. sys._current_frames() thread_id = thread.get_ident() def other_thread(): print "thread started" lock2.release() lock1.acquire() lock1 = thread.allocate_lock() lock2 = thread.allocate_lock() lock1.acquire() lock2.acquire() thread.start_new_thread(other_thread, ()) def f(): lock2.acquire() return sys._current_frames() frames = f() lock1.release() thisframe = frames.pop(thread_id) assert thisframe.f_code.co_name in ('f', '?') assert len(frames) == 1 _, other_frame = frames.popitem() assert other_frame.f_code.co_name in ('other_thread', '?')
def streaming(self): next_call = time.time() while not self.stopped.wait(next_call - time.time()): #timer compensate self.x=self.x+1 self.s.send(self.input_update) print "have sent update command to streamer.." # print "recv data1 from streamer.." resp1 = self.s.recv(1024*10) # print "received simu's data1:",resp1 print "received data from streamer!!" xdata["1"].append(self.x) xdata["2"].append(self.x) # print resp1,"dd" resp_A=resp1.split('\n')[0] resp_B=resp1.split('\n')[1] rexp = re.compile(r'[^\d.,]+') data1=map(float,rexp.sub('', resp_A).split(','))[1] data2=map(float,rexp.sub('', resp_B).split(','))[1] ydata["1"].append(data1) ydata["2"].append(data2) thread2.on_running(xdata, ydata) print sys._current_frames() next_call = next_call+1 #timer=1s
def __dumpstacks(self, context=1, sighandler_deep=2): """ Signal handler: dump a stack trace for each existing thread.""" currentThreadId = threading.currentThread().ident def unique_count(l): d = collections.defaultdict(lambda: 0) for v in l: d[tuple(v)] += 1 return list((k, v) for k, v in d.items()) stack_displays = [] for threadId, stack in sys._current_frames().items(): stack_display = [] for filename, lineno, name, line in traceback.extract_stack(stack): stack_display.append(' File: "%s", line %d, in %s' % (filename, lineno, name)) if line: stack_display.append(" %s" % (line.strip())) if currentThreadId == threadId: stack_display = stack_display[:- (sighandler_deep * 2)] stack_display.append(' => Stopped to handle current signal. ') stack_displays.append(stack_display) stacks = unique_count(stack_displays) self.ui.debug('thread', "** Thread List:\n") for stack, times in stacks: if times == 1: msg = "%s Thread is at:\n%s\n" else: msg = "%s Threads are at:\n%s\n" self.ui.debug('thread', msg % (times, '\n'.join(stack[- (context * 2):]))) self.ui.debug('thread', "Dumped a total of %d Threads." % len(sys._current_frames().keys()))
def adminInfo(handler): handler.title('Information') requirePriv(handler, 'Admin') print "<div class=\"info\">" print "<h3>Uptime</h3>" loadTime = getLoadtime() print "Started %s<br>" % loadTime print "Up for %s<br>" % timesince(loadTime) print "Total requests: %d<br>" % server().getTotalRequests() print "<form method=\"post\" action=\"/admin/restart\">" print Button('Restart', type = 'submit').negative() print "</form>" print "<h3>Threads</h3>" print "<table border=\"1\" cellspacing=\"0\" cellpadding=\"4\">" print "<tr><th>ID</th><th class=\"main\">Name</th><th>Alive</th><th>Daemon</th></tr>" for thread in sorted(threads(), key = lambda thread: thread.name): print "<tr><td>%s</td><td>" % ('None' if thread.ident is None else "%x" % abs(thread.ident)) print thread.name print "<br>" try: print CollapsibleBox('Traceback', formatTrace(traceback.extract_stack(sys._current_frames()[thread.ident]))) except Exception: pass print "</td><td class=\"%s\"> </td><td class=\"%s\"> </td></tr>" % ('yes' if thread.isAlive() else 'no', 'yes' if thread.daemon else 'no') print "</table>" print "<h3>Locks</h3>" print "<table border=\"1\" cellspacing=\"0\" cellpadding=\"4\">" print "<tr><th class=\"main\">Name</th><th>Available</th><th>Reentrant</th></tr>" for (name, lock) in sorted(locks.iteritems()): print "<tr><td>" print name avail = lock.avail() if not avail: print "<br>" writer = ResponseWriter() try: owner, tb = lock.owner, lock.tb name = ("%x" % abs(owner)) if owner else 'None' #TODO Is there no O(1) way to do this? for thread in threads(): if thread.ident == owner: name = "%s (%x)" % (thread.name, abs(owner)) break print "Owned by: <b>%s</b><br><br>" % name if tb: print "Acquisition traceback:<br>" print formatTrace(tb) print "<br>" print "Current traceback:<br>" print formatTrace(traceback.extract_stack(sys._current_frames()[owner])) except Exception, e: writer.clear() print "<i>(Unable to retrieve stack trace)</i>" print CollapsibleBox('Ownership', writer.done()) print "</td><td class=\"%s\">%s</td><td class=\"%s\"> </td></tr>" % ('yes' if avail else 'no', ' ' if avail else (lock.owner or '???'), 'yes' if lock.reentrant() else 'no')
def getCallingModuleName(): import sys if sys.version_info[0] == 3: f = list(sys._current_frames().values())[0] else: f = sys._current_frames().values()[0] f = f.f_back return f.f_back.f_globals['__name__']
def synthesize_thread_stacks(): threads = dict([(th.ident, th) for th in threading.enumerate()]) ostr = StringIO() if len(sys._current_frames()) > 1 or ( sys._current_frames().values()[0] != inspect.currentframe()): # Multi-threaded ostr.write('\nAll threads:\n') for thread_id, stack in sys._current_frames().items(): AppExceptionHandler.print_stack(thread_id, threads[thread_id], stack, ostr, indent=2) return ostr.getvalue()
def test_top_frame(self): self.assertEqual(1, len(sys._current_frames())) frame = sys._current_frames().items()[0][1] # frame filename and name self.assertEqual((frame.f_code.co_filename, frame.f_code.co_name), _snakemeter.get_top_frame()[:2]) # line number of current frame self.assertEqual(sys._current_frames().items()[0][1].f_lineno, _snakemeter.get_top_frame()[2])
def info_thread_missing(self): """Show information about threads we might not know about""" if hasattr(sys, "_current_frames") and \ len(self.traced) != len(sys._current_frames()): frames = sys._current_frames() thread_ids = frames.keys() self.msg("Untraced/unknown threads:") for thread_id in thread_ids: if thread_id not in self.traced.values(): self.msg("\t%d" % thread_id) return
def info_thread_missing(obj): """Show information about threads we might not know about""" if not hasattr(obj, "traced"): return if (hasattr(sys, "_current_frames") and len(obj.traced) != len(sys._current_frames())): frames = sys._current_frames() thread_ids = frames.keys() obj.msg("Untraced/unknown threads:") for thread_id in thread_ids: if thread_id not in obj.traced.values(): obj.msg("\t%d" % thread_id) return
def synthesize_thread_stacks(): threads = dict([(th.ident, th) for th in threading.enumerate()]) ostr = Compatibility.StringIO() # _current_frames not yet implemented on pypy and not guaranteed anywhere but # cpython in practice. if hasattr(sys, '_current_frames') and (len(sys._current_frames()) > 1 or sys._current_frames().values()[0] != inspect.currentframe()): # Multi-threaded ostr.write('\nAll threads:\n') for thread_id, stack in sys._current_frames().items(): BasicExceptionHandler.print_stack(thread_id, threads[thread_id], stack, ostr, indent=2) return ostr.getvalue()
def dumpThread(threadId): import sys if not hasattr(sys, "_current_frames"): print "Warning: dumpThread: no sys._current_frames" return if threadId not in sys._current_frames(): print("Thread %d not found" % threadId) return stack = sys._current_frames()[threadId] better_exchook.print_traceback(stack)
def dumpThread(threadId): import threading, sys, traceback if threadId not in sys._current_frames(): print "Thread", threadId, "not found" return code = [] stack = sys._current_frames()[threadId] for filename, lineno, name, line in traceback.extract_stack(stack): code.append('File: "%s", line %d, in %s' % (filename, lineno, name)) if line: code.append(" %s" % (line.strip())) print "\n".join(code)
def debug_dump_threads(): print("\n===== %s dump thread stack frames. %i threads. conductor lock = %s:\n" % ( format_unixts(time.time()), len(sys._current_frames()), the_conductor.lock), file=sys.stderr) idx=0 for thread_id, frame in sys._current_frames().items(): print("===== thread #%i [%#x] refcount = %s" % (idx, thread_id, sys.getrefcount(frame)), file=sys.stderr) if thread_id != _debug_thread_id: traceback.print_stack(frame, file = sys.stderr) else: print(" debug thread, skipping", file=sys.stderr) idx += 1 print("=====\n", file=sys.stderr)
def getCallingModuleName(): import sys if sys.version_info[0] == 3: frames = list(sys._current_frames().values()) else: frames = sys._current_frames().values() for i in range(len(frames)): f = frames[i] if f.f_globals['__name__'] == "tulipplugins": f = f.f_back break while f.f_globals['__name__'] == "tulipplugins": f = f.f_back return f.f_globals['__name__']
def wrapped(*args, **kwargs): """ :param args: :param kwargs: :return: """ # noinspection PyProtectedMember old_threads = set(sys._current_frames().keys()) res = func(*args, **kwargs) # noinspection PyProtectedMember new_threads = set(sys._current_frames().keys()) new_threads -= old_threads global_exclude_thread_ids.update(new_threads) return res
def save_transaction(self, transaction): """Saves the specified transaction away under the thread ID of the current executing thread. Will also cache a reference to the greenlet if using coroutines. This is so we can later determine the stack trace for a transaction when using greenlets. """ thread_id = transaction.thread_id if thread_id in self._cache: raise RuntimeError('transaction already active') self._cache[thread_id] = transaction # We judge whether we are actually running in a coroutine by # seeing if the current thread ID is actually listed in the set # of all current frames for executing threads. If we are # executing within a greenlet, then thread.get_ident() will # return the greenlet identifier. This will not be a key in # dictionary of all current frames because that will still be # the original standard thread which all greenlets are running # within. transaction._greenlet = None if hasattr(sys, '_current_frames'): if thread_id not in sys._current_frames(): greenlet = sys.modules.get('greenlet') if greenlet: transaction._greenlet = weakref.ref(greenlet.getcurrent())
def current_frames_without_threads(self): # Not much happens here: there is only one thread, with artificial # "thread id" 0. d = sys._current_frames() self.assertEqual(len(d), 1) self.assertIn(0, d) self.assertTrue(d[0] is sys._getframe())
def _find_thread_stack(id): """Returns a stack object that can be used to dump a stack trace for the given thread id (or None if the id is not found).""" for thread_id, stack in sys._current_frames().items(): if thread_id == id: return stack return None
def dumpstacks(sig=None, frame=None): """ Signal handler: dump a stack trace for each existing thread.""" code = [] def extract_stack(stack): for filename, lineno, name, line in traceback.extract_stack(stack): yield 'File: "%s", line %d, in %s' % (filename, lineno, name) if line: yield " %s" % (line.strip(),) # code from http://stackoverflow.com/questions/132058/getting-stack-trace-from-a-running-python-application#answer-2569696 # modified for python 2.5 compatibility threads_info = dict([(th.ident, {'name': th.name, 'uid': getattr(th, 'uid', 'n/a')}) for th in threading.enumerate()]) for threadId, stack in sys._current_frames().items(): thread_info = threads_info.get(threadId) code.append("\n# Thread: %s (id:%s) (uid:%s)" % (thread_info and thread_info['name'] or 'n/a', threadId, thread_info and thread_info['uid'] or 'n/a')) for line in extract_stack(stack): code.append(line) if openerp.evented: # code from http://stackoverflow.com/questions/12510648/in-gevent-how-can-i-dump-stack-traces-of-all-running-greenlets import gc from greenlet import greenlet for ob in gc.get_objects(): if not isinstance(ob, greenlet) or not ob: continue code.append("\n# Greenlet: %r" % (ob,)) for line in extract_stack(ob.gr_frame): code.append(line) _logger.info("\n".join(code))
def cry(): # pragma: no cover """Return stacktrace of all active threads. From https://gist.github.com/737056 """ tmap = {} main_thread = None # get a map of threads by their ID so we can print their names # during the traceback dump for t in threading.enumerate(): if getattr(t, "ident", None): tmap[t.ident] = t else: main_thread = t out = StringIO() sep = "=" * 49 + "\n" for tid, frame in sys._current_frames().iteritems(): thread = tmap.get(tid, main_thread) out.write("%s\n" % (thread.getName(),)) out.write(sep) traceback.print_stack(frame, file=out) out.write(sep) out.write("LOCAL VARIABLES\n") out.write(sep) pprint(frame.f_locals, stream=out) out.write("\n\n") return out.getvalue()
def __init__(self): #dynamically determine the unittest.case frame and use it to get the name of the test method ident = threading.current_thread().ident upperf = sys._current_frames()[ident] while (upperf.f_globals['__name__'] != 'unittest.case'): upperf = upperf.f_back def handleList(items): ret = [] # items is a list of tuples, (test, failure) or (_ErrorHandler(), Exception()) for i in items: s = i[0].id() #Handle the _ErrorHolder objects from skipModule failures if "setUpModule (" in s: ret.append(s.replace("setUpModule (", "").replace(")","")) else: ret.append(s) # Append also the test without the full path testname = s.split('.')[-1] if testname: ret.append(testname) return ret self.faillist = handleList(upperf.f_locals['result'].failures) self.errorlist = handleList(upperf.f_locals['result'].errors) self.skiplist = handleList(upperf.f_locals['result'].skipped)
def current_frames_with_threads(self): import threading, thread import traceback # Spawn a thread that blocks at a known place. Then the main # thread does sys._current_frames(), and verifies that the frames # returned make sense. entered_g = threading.Event() leave_g = threading.Event() thread_info = [] # the thread's id def f123(): g456() def g456(): thread_info.append(thread.get_ident()) entered_g.set() leave_g.wait() t = threading.Thread(target=f123) t.start() entered_g.wait() # At this point, t has finished its entered_g.set(), although it's # impossible to guess whether it's still on that line or has moved on # to its leave_g.wait(). self.assertEqual(len(thread_info), 1) thread_id = thread_info[0] d = sys._current_frames() main_id = thread.get_ident() self.assertIn(main_id, d) self.assertIn(thread_id, d) # Verify that the captured main-thread frame is _this_ frame. frame = d.pop(main_id) self.assertTrue(frame is sys._getframe()) # Verify that the captured thread frame is blocked in g456, called # from f123. This is a litte tricky, since various bits of # threading.py are also in the thread's call stack. frame = d.pop(thread_id) stack = traceback.extract_stack(frame) for i, (filename, lineno, funcname, sourceline) in enumerate(stack): if funcname == "f123": break else: self.fail("didn't find f123() on thread's call stack") self.assertEqual(sourceline, "g456()") # And the next record must be for g456(). filename, lineno, funcname, sourceline = stack[i + 1] self.assertEqual(funcname, "g456") self.assertIn(sourceline, ["leave_g.wait()", "entered_g.set()"]) # Reap the spawned thread. leave_g.set() t.join()
def cry(out=None, sepchr='=', seplen=49): # pragma: no cover """Return stack-trace of all active threads, taken from https://gist.github.com/737056.""" import threading out = WhateverIO() if out is None else out P = partial(print, file=out) # get a map of threads by their ID so we can print their names # during the traceback dump tmap = {t.ident: t for t in threading.enumerate()} sep = sepchr * seplen for tid, frame in items(sys._current_frames()): thread = tmap.get(tid) if not thread: # skip old junk (left-overs from a fork) continue P('{0.name}'.format(thread)) P(sep) traceback.print_stack(frame, file=out) P(sep) P('LOCAL VARIABLES') P(sep) pprint(frame.f_locals, stream=out) P('\n') return out.getvalue()
def api_callstack(self, ignores=None): # pylint: disable=line-too-long """ return a list of function calls that form the stack Example: [' File "bastproxy.py", line 280, in <module>', ' main()', ' File "bastproxy.py", line 253, in main', ' start(listen_port)', ' File "/home/endavis/src/games/bastproxy/bp/libs/event.py", line 60, in new_func', ' return func(*args, **kwargs)', ' File "/home/endavis/src/games/bastproxy/bp/libs/net/proxy.py", line 63, in handle_read', " 'convertansi':tconvertansi})", ' """ # pylint: enable=line-too-long if ignores is None: ignores = [] callstack = [] for _, frame in sys._current_frames().items(): # pylint: disable=protected-access for i in traceback.format_stack(frame)[:-1]: if True in [tstr in i for tstr in ignores]: continue tlist = i.split('\n') for tline in tlist: if tline: if self.BASEPATH: tline = tline.replace(self.BASEPATH + "/", "") callstack.append(tline.rstrip()) return callstack
def dumpState(self): from meh import ExceptionInfo from meh.dump import ReverseExceptionDump from inspect import stack as _stack from traceback import format_stack # Skip the frames for dumpState and the signal handler. stack = _stack()[2:] stack.reverse() exn = ReverseExceptionDump(ExceptionInfo(None, None, stack), self.mehConfig) # gather up info on the running threads threads = "\nThreads\n-------\n" # Every call to sys._current_frames() returns a new dict, so it is not # modified when threads are created or destroyed. Iterating over it is # thread safe. for thread_id, frame in sys._current_frames().items(): threads += "\nThread %s\n" % (thread_id,) threads += "".join(format_stack(frame)) # dump to a unique file (fd, filename) = mkstemp(prefix="anaconda-tb-", dir="/tmp") dump_text = exn.traceback_and_object_dump(self) dump_text += threads dump_text_bytes = dump_text.encode("utf-8") os.write(fd, dump_text_bytes) os.close(fd) # append to a given file with open("/tmp/anaconda-tb-all.log", "a+") as f: f.write("--- traceback: %s ---\n" % filename) f.write(dump_text + "\n")
def run( self ): self.file = open( self.fname, "a" ) print >> self.file, "Heartbeat for pid %d thread started at %s" % ( self.pid, time.asctime() ) print >> self.file self.file_nonsleeping = open( self.fname_nonsleeping, "a" ) print >> self.file_nonsleeping, "Non-Sleeping-threads for pid %d thread started at %s" % ( self.pid, time.asctime() ) print >> self.file_nonsleeping try: while not self.should_stop: # Print separator with timestamp print >> self.file, "Traceback dump for all threads at %s:" % time.asctime() print >> self.file # Print the thread states threads = get_current_thread_object_dict() for thread_id, frame in iteritems(sys._current_frames()): if thread_id in threads: object = repr( threads[thread_id] ) else: object = "<No Thread object>" print >> self.file, "Thread %s, %s:" % ( thread_id, object ) print >> self.file traceback.print_stack( frame, file=self.file ) print >> self.file print >> self.file, "End dump" print >> self.file self.file.flush() self.print_nonsleeping(threads) # Sleep for a bit self.wait_event.wait( self.period ) finally: print >> self.file, "Heartbeat for pid %d thread stopped at %s" % ( self.pid, time.asctime() ) print >> self.file # Cleanup self.file.close() self.file_nonsleeping.close()
def cry(): # pragma: no cover """Return stacktrace of all active threads. From https://gist.github.com/737056 """ tmap = {} main_thread = None # get a map of threads by their ID so we can print their names # during the traceback dump for t in threading.enumerate(): if getattr(t, 'ident', None): tmap[t.ident] = t else: main_thread = t out = StringIO() P = partial(print, file=out) sep = '=' * 49 for tid, frame in sys._current_frames().iteritems(): thread = tmap.get(tid, main_thread) if not thread: # skip old junk (left-overs from a fork) continue P('{0.name}'.format(thread)) P(sep) traceback.print_stack(frame, file=out) P(sep) P('LOCAL VARIABLES') P(sep) pprint(frame.f_locals, stream=out) P('\n') return out.getvalue()
def f(): return sys._current_frames()
def test_current_frames(self): import threading import traceback # Spawn a thread that blocks at a known place. Then the main # thread does sys._current_frames(), and verifies that the frames # returned make sense. entered_g = threading.Event() leave_g = threading.Event() thread_info = [] # the thread's id def f123(): g456() def g456(): thread_info.append(threading.get_ident()) entered_g.set() leave_g.wait() t = threading.Thread(target=f123) t.start() entered_g.wait() # At this point, t has finished its entered_g.set(), although it's # impossible to guess whether it's still on that line or has moved on # to its leave_g.wait(). self.assertEqual(len(thread_info), 1) thread_id = thread_info[0] d = sys._current_frames() for tid in d: self.assertIsInstance(tid, int) self.assertGreater(tid, 0) main_id = threading.get_ident() self.assertIn(main_id, d) self.assertIn(thread_id, d) # Verify that the captured main-thread frame is _this_ frame. frame = d.pop(main_id) self.assertTrue(frame is sys._getframe()) # Verify that the captured thread frame is blocked in g456, called # from f123. This is a litte tricky, since various bits of # threading.py are also in the thread's call stack. frame = d.pop(thread_id) stack = traceback.extract_stack(frame) for i, (filename, lineno, funcname, sourceline) in enumerate(stack): if funcname == "f123": break else: self.fail("didn't find f123() on thread's call stack") self.assertEqual(sourceline, "g456()") # And the next record must be for g456(). filename, lineno, funcname, sourceline = stack[i + 1] self.assertEqual(funcname, "g456") self.assertIn(sourceline, ["leave_g.wait()", "entered_g.set()"]) # Reap the spawned thread. leave_g.set() t.join()
def dumpstacks(signal, frame): import threading id2name = dict((t.ident, t.name) for t in threading.enumerate()) for tid, stack in sys._current_frames().items(): logging.info("=== {} ===".format(id2name[tid])) traceback.print_stack(f=stack)
def current_thread_id(): thread_id, _ = sys._current_frames().items()[0] return thread_id
def print_stack_frames(signum=None, frame=None): for frame in sys._current_frames().values(): traceback.print_stack(frame) print()
def print_thread_stacktrace(): print('Here is the stacktrace for all threads:') thread_names = {t.ident: t.name for t in threading.enumerate()} for thread_id, frame in sys._current_frames().items(): # pylint: disable=protected-access print('Thread {}'.format(thread_names.get(thread_id, thread_id))) traceback.print_stack(frame)
def current_thread_id(): for thread_id in sys._current_frames().keys(): return thread_id return None
def is_dbg_callee(): if os.path.basename(sys._current_frames()[_thread.get_ident()].f_back. f_back.f_code.co_filename) in epdb_modules: return True return False
def worker_abort(worker): worker.log.info("worker received ABORT {}".format(worker.pid)) for threadId, stack in sys._current_frames().items(): worker.log.error(''.join(traceback.format_stack(stack)))
def set_trace_to_threads(tracing_func): lib = load_python_helper_lib() if lib is None: # This is the case if it's not CPython. return -1 if hasattr(sys, 'getswitchinterval'): get_interval, set_interval = sys.getswitchinterval, sys.setswitchinterval else: get_interval, set_interval = sys.getcheckinterval, sys.setcheckinterval prev_value = get_interval() ret = 0 try: if not IS_PY37_OR_GREATER: # Prevent going to any other thread... if we switch the thread during this operation we # could potentially corrupt the interpreter. # Note: on CPython 3.7 onwards this is not needed (we have a different implementation # for setting the tracing for other threads in this case). set_interval(2**15) set_trace_func = TracingFunctionHolder._original_tracing or sys.settrace # Note: use sys._current_frames() keys to get the thread ids because it'll return # thread ids created in C/C++ where there's user code running, unlike the APIs # from the threading module which see only threads created through it (unless # a call for threading.current_thread() was previously done in that thread, # in which case a dummy thread would've been created for it). thread_idents = set(sys._current_frames().keys()) if IS_WINDOWS and IS_PYCHARM_ATTACH: # On Windows, when attaching to a process, some existing threads may not # appear in sys._current_frames()` but be available through the `threading` # facilities. See: PY-44778. thread_idents = thread_idents.union( set(t.ident for t in threading.enumerate())) thread_idents = thread_idents.difference( # Ignore pydevd threads. set(t.ident for t in threading.enumerate() if getattr(t, 'pydev_do_not_trace', False))) curr_ident = thread.get_ident() curr_thread = threading._active.get(curr_ident) for thread_ident in thread_idents: # If that thread is not available in the threading module we also need to create a # dummy thread for it (otherwise it'll be invisible to the debugger). if thread_ident not in threading._active: class _DummyThread(threading._DummyThread): def _set_ident(self): # Note: Hack to set the thread ident that we want. if IS_PY2: self._Thread__ident = thread_ident else: self._ident = thread_ident t = _DummyThread() # Reset to the base class (don't expose our own version of the class). t.__class__ = threading._DummyThread with threading._active_limbo_lock: # On Py2 it'll put in active getting the current indent, not using the # ident that was set, so, we have to update it (should be harmless on Py3 # so, do it always). threading._active[thread_ident] = t threading._active[curr_ident] = curr_thread if t.ident != thread_ident: # Check if it actually worked. pydev_log.error( 'pydevd: creation of _DummyThread with fixed thread ident did not succeed.' ) # Some (ptvsd) tests failed because of this, so, leave it always disabled for now. # show_debug_info = 1 if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1 else 0 show_debug_info = 0 if IS_PY37_OR_GREATER: # Hack to increase _Py_TracingPossible. # See comments on py_settrace_37.hpp proceed = thread.allocate_lock() proceed.acquire() def dummy_trace_on_py37(frame, event, arg): return dummy_trace_on_py37 def increase_tracing_count_on_py37(): SetTrace(dummy_trace_on_py37) proceed.release() start_new_thread = pydev_monkey.get_original_start_new_thread( thread) start_new_thread(increase_tracing_count_on_py37, ()) proceed.acquire() # Only proceed after the release() is done. proceed = None result = lib.AttachDebuggerTracing( ctypes.c_int(show_debug_info), ctypes.py_object(set_trace_func), ctypes.py_object(tracing_func), ctypes.c_uint(thread_ident), ctypes.py_object(None), ) if result != 0: pydev_log.info( 'Unable to set tracing for existing threads. Result: %s' % result) ret = result finally: if not IS_PY37_OR_GREATER: set_interval(prev_value) return ret
def _print_nativethreads(): for threadId, stack in sys._current_frames().items(): print(threadId) traceback.print_stack(stack) print()
def test_collection_locking_enforces_consistency(self): # Create the collection and get initial version. bso = {"id": "TEST", "payload": _PLD} ver0 = self.storage.set_items(_UID, "col1", [bso]) # Some events to coordinate action between the threads. read_locked = threading.Event() write_complete = threading.Event() # Somewhere to collection failures from subthreads. # Assertion errors don't bubble up automatically. failures = [] def catch_failures(func): def catch_failures_wrapper(*args, **kwds): try: return func(*args, **kwds) except Exception: failures.append(sys.exc_info()) return catch_failures_wrapper # A reader thread. It locks the collection for reading, then # reads the version twice in succession. They should both # match the initial version despite concurrent write thread. @catch_failures def reader_thread(): with self.storage.lock_for_read(_UID, "col1"): read_locked.set() ver1 = self.storage.get_collection_version(_UID, "col1") self.assertEquals(ver0, ver1) # Give the writer a chance to update the value. # It may be blocking on us though, so don't wait forever. write_complete.wait(timeout=1) ver2 = self.storage.get_collection_version(_UID, "col1") self.assertEquals(ver1, ver2) # After releasing our read lock, the writer should complete. # Make sure its changes are visible to this thread. write_complete.wait() ver3 = self.storage.get_collection_version(_UID, "col1") self.assertTrue(ver2 < ver3) # A writer thread. It waits until the collection is locked for # read, then attempts to write-lock and update the collection. # This may block or raise a ConflictError, so it tries in a loop # until succeeding. @catch_failures def writer_thread(): read_locked.wait() storage = self.storage while True: try: with self.storage.lock_for_write(_UID, "col1"): ver1 = storage.get_collection_version(_UID, "col1") self.assertEquals(ver0, ver1) ver2 = storage.set_items(_UID, "col1", [bso]) self.assertTrue(ver1 < ver2) break except ConflictError: continue write_complete.set() # Check that our changes are visible outside of the lock. ver3 = storage.get_collection_version(_UID, "col1") self.assertEquals(ver2, ver3) reader = threading.Thread(target=reader_thread) writer = threading.Thread(target=writer_thread) reader.start() writer.start() reader.join(10) writer.join(10) if reader.isAlive() or writer.isAlive(): print>>sys.stderr, "TEST THREADS APPEAR TO BE DEADLOCKED" print>>sys.stderr, "\n" current_frames = sys._current_frames() rframe = current_frames.get(reader.ident) if rframe is not None: print>>sys.stderr, "READ THREAD TRACEBACK:" print>>sys.stderr, "".join(traceback.format_stack(rframe)) print>>sys.stderr, "\n" wframe = current_frames.get(writer.ident) if wframe is not None: print>>sys.stderr, "WRITE THREAD TRACEBACK:" print>>sys.stderr, "".join(traceback.format_stack(wframe)) print>>sys.stderr, "\n" read_locked.set() write_complete.set() for exc_type, exc_val, exc_tb in failures: raise exc_type, exc_val, exc_tb if reader.isAlive() or writer.isAlive(): raise RuntimeError("Test threads appear to be deadlocked")
def set_trace_to_threads(tracing_func, thread_idents=None, create_dummy_thread=True): assert tracing_func is not None ret = 0 # Note: use sys._current_frames() keys to get the thread ids because it'll return # thread ids created in C/C++ where there's user code running, unlike the APIs # from the threading module which see only threads created through it (unless # a call for threading.current_thread() was previously done in that thread, # in which case a dummy thread would've been created for it). if thread_idents is None: thread_idents = set(sys._current_frames().keys()) for t in threading.enumerate(): # PY-44778: ignore pydevd threads and also add any thread that wasn't found on # sys._current_frames() as some existing threads may not appear in # sys._current_frames() but may be available through the `threading` module. if getattr(t, 'pydev_do_not_trace', False): thread_idents.discard(t.ident) else: thread_idents.add(t.ident) curr_ident = thread.get_ident() curr_thread = threading._active.get(curr_ident) if curr_ident in thread_idents and len(thread_idents) != 1: # The current thread must be updated first (because we need to set # the reference to `curr_thread`). thread_idents = list(thread_idents) thread_idents.remove(curr_ident) thread_idents.insert(0, curr_ident) for thread_ident in thread_idents: # If that thread is not available in the threading module we also need to create a # dummy thread for it (otherwise it'll be invisible to the debugger). if create_dummy_thread: if thread_ident not in threading._active: class _DummyThread(threading._DummyThread): def _set_ident(self): # Note: Hack to set the thread ident that we want. if IS_PY2: self._Thread__ident = thread_ident else: self._ident = thread_ident t = _DummyThread() # Reset to the base class (don't expose our own version of the class). t.__class__ = threading._DummyThread if thread_ident == curr_ident: curr_thread = t with threading._active_limbo_lock: # On Py2 it'll put in active getting the current indent, not using the # ident that was set, so, we have to update it (should be harmless on Py3 # so, do it always). threading._active[thread_ident] = t threading._active[curr_ident] = curr_thread if t.ident != thread_ident: # Check if it actually worked. pydev_log.critical( 'pydevd: creation of _DummyThread with fixed thread ident did not succeed.' ) # Some (ptvsd) tests failed because of this, so, leave it always disabled for now. # show_debug_info = 1 if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1 else 0 show_debug_info = 0 # Hack to increase _Py_TracingPossible. # See comments on py_custom_pyeval_settrace.hpp proceed = thread.allocate_lock() proceed.acquire() def dummy_trace(frame, event, arg): return dummy_trace def increase_tracing_count(): set_trace = TracingFunctionHolder._original_tracing or sys.settrace set_trace(dummy_trace) proceed.release() start_new_thread = pydev_monkey.get_original_start_new_thread(thread) start_new_thread(increase_tracing_count, ()) proceed.acquire() # Only proceed after the release() is done. proceed = None # Note: The set_trace_func is not really used anymore in the C side. set_trace_func = TracingFunctionHolder._original_tracing or sys.settrace lib = _load_python_helper_lib() if lib is None: # This is the case if it's not CPython. pydev_log.info( 'Unable to load helper lib to set tracing to all threads (unsupported python vm).' ) ret = -1 else: try: result = lib.AttachDebuggerTracing( ctypes.c_int(show_debug_info), ctypes.py_object(set_trace_func), ctypes.py_object(tracing_func), ctypes.c_uint(thread_ident), ctypes.py_object(None), ) except: if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1: # There is no need to show this unless debug tracing is enabled. pydev_log.exception('Error attaching debugger tracing') ret = -1 else: if result != 0: pydev_log.info( 'Unable to set tracing for existing thread. Result: %s', result) ret = result return ret
def iter_thread_frames(): yield from sys._current_frames().items()
def __enter__(self): assert (self._state == STATE_PENDING) # Bail out if the transaction is not enabled. if not self.enabled: return self # Mark transaction as active and update state # used to validate correct usage of class. self._state = STATE_RUNNING # Cache transaction in thread/coroutine local # storage so that it can be accessed from # anywhere in the context of the transaction. try: self.save_transaction() except: # Catch all self._state = STATE_PENDING self.enabled = False raise # Record the start time for transaction. self.start_time = time.time() # Record initial CPU user time. self._cpu_user_time_start = os.times()[0] # Calculate initial thread utilisation factor. # For now we only do this if we know it is an # actual thread and not a greenlet. if (not hasattr(sys, '_current_frames') or self.thread_id in sys._current_frames()): thread_instance = threading.currentThread() self._utilization_tracker = utilization_tracker( self.application.name) if self._utilization_tracker: self._utilization_tracker.enter_transaction(thread_instance) self._thread_utilization_start = \ self._utilization_tracker.utilization_count() # We need to push an object onto the top of the # node stack so that children can reach back and # add themselves as children to the parent. We # can't use ourself though as we then end up # with a reference count cycle which will cause # the destructor to never be called if the # __exit__() function is never called. We # instead push on to the top of the node stack a # dummy time trace object and when done we will # just grab what we need from that. self._node_stack.append(newrelic.api.time_trace.TimeTrace(None)) return self
def f(): lock2.acquire() return sys._current_frames()
def test_func(): del _global_workers[:] _global_clients.clear() active_threads_start = set(threading._active) reset_config() dask.config.set({'distributed.comm.timeouts.connect': '5s'}) # Restore default logging levels # XXX use pytest hooks/fixtures instead? for name, level in logging_levels.items(): logging.getLogger(name).setLevel(level) result = None workers = [] with pristine_loop() as loop: with check_active_rpc(loop, active_rpc_timeout): @gen.coroutine def coro(): with dask.config.set(config): s = False for i in range(5): try: s, ws = yield start_cluster( ncores, scheduler, loop, security=security, Worker=Worker, scheduler_kwargs=scheduler_kwargs, worker_kwargs=worker_kwargs) except Exception as e: logger.error( "Failed to start gen_cluster, retryng", exc_info=True) else: workers[:] = ws args = [s] + workers break if s is False: raise Exception("Could not start cluster") if client: c = yield Client(s.address, loop=loop, security=security, asynchronous=True, **client_kwargs) args = [c] + args try: future = func(*args) if timeout: future = gen.with_timeout( timedelta(seconds=timeout), future) result = yield future if s.validate: s.validate_state() finally: if client: yield c._close(fast=s.status == 'closed') yield end_cluster(s, workers) yield gen.with_timeout( timedelta(seconds=1), cleanup_global_workers()) try: c = yield default_client() except ValueError: pass else: yield c._close(fast=True) raise gen.Return(result) result = loop.run_sync(coro, timeout=timeout * 2 if timeout else timeout) for w in workers: if getattr(w, 'data', None): try: w.data.clear() except EnvironmentError: # zict backends can fail if their storage directory # was already removed pass del w.data DequeHandler.clear_all_instances() for w in _global_workers: w = w() w._close(report=False, executor_wait=False) if w.status == 'running': w.close() del _global_workers[:] if PY3 and not WINDOWS and check_new_threads: start = time() while True: bad = [ t for t, v in threading._active.items() if t not in active_threads_start and "Threaded" not in v.name and "watch message" not in v.name ] if not bad: break else: sleep(0.01) if time() > start + 2: from distributed import profile tid = bad[0] thread = threading._active[tid] call_stacks = profile.call_stack( sys._current_frames()[tid]) assert False, (thread, call_stacks) return result
def worker_abort(worker): worker.log.info("worker received ABORT") for stack in sys._current_frames().values(): worker.log.error(''.join(traceback.format_stack(stack)))
def _threads(): return sys._current_frames().iteritems()
def dump_thread_handler(signum, frame): # type: (int, FrameType) -> None for thread_id, thread_frame in iteritems(sys._current_frames()): print("-- thread id {}:".format(thread_id)) print("".join(traceback.format_stack(thread_frame)))
def current_frames_without_threads(self): d = sys._current_frames() self.assertEqual(len(d), 1) self.assertIn(0, d) self.assertTrue(d[0] is sys._getframe())
def __call__(self, frame, event, arg): if event not in [ 'call', 'c_call', 'return', 'c_return', 'exception', 'c_exception' ]: return transaction = current_transaction() if not transaction: return # Not sure if setprofile() is reliable in the face of # coroutine systems based on greenlets so don't run # if we detect may be using greenlets. if (hasattr(sys, '_current_frames') and not transaction.thread_id in sys._current_frames()): return co = frame.f_code func_name = co.co_name func_line_no = frame.f_lineno func_filename = co.co_filename def _callable_name(): # This is pretty ugly and inefficient, but a stack # frame doesn't provide any information about the # original callable object. We thus need to try and # deduce what it is by searching through the stack # frame globals. This will still not work in many # cases, including lambdas, generator expressions, # and decoratored attributes such as properties of # classes. try: if func_name in frame.f_globals: if frame.f_globals[func_name].func_code is co: return callable_name(frame.f_globals[func_name]) except Exception: pass for name, obj in six.iteritems(frame.f_globals): try: if obj.__dict__[func_name].func_code is co: return callable_name(obj.__dict__[func_name]) except Exception: pass if event in ['call', 'c_call']: # Skip the outermost as we catch that with the root # function traces for the profile trace. if len(self.function_traces) == 0: self.function_traces.append(None) return if self.current_depth >= self.maximum_depth: self.function_traces.append(None) return if func_filename.startswith(AGENT_PACKAGE_DIRECTORY): self.function_traces.append(None) return if event == 'call': name = _callable_name() if not name: name = '%s:%s#%s' % (func_filename, func_name, func_line_no) else: name = callable_name(arg) if not name: name = '%s:@%s#%s' % (func_filename, func_name, func_line_no) function_trace = FunctionTrace(transaction, name=name) function_trace.__enter__() self.function_traces.append(function_trace) self.current_depth += 1 elif event in ['return', 'c_return', 'c_exception']: if not self.function_traces: return try: function_trace = self.function_traces.pop() except IndexError: pass else: if function_trace: function_trace.__exit__(None, None, None) self.current_depth -= 1
def dump_all_thread_tracebacks(exclude_thread_ids=None, exclude_self=False, file=sys.stderr): """ :param set[int]|None exclude_thread_ids: set|list of thread.ident to exclude :param bool exclude_self: """ from traceback import print_stack, walk_stack from multiprocessing.pool import worker as mp_worker from multiprocessing.pool import Pool from queue import Queue import threading if not hasattr(sys, "_current_frames"): print("Does not have sys._current_frames, cannot get thread tracebacks.", file=file) return if exclude_thread_ids is None: exclude_thread_ids = set() exclude_thread_ids = set(exclude_thread_ids) if exclude_self: exclude_thread_ids.add(threading.current_thread().ident) print("", file=file) threads = {t.ident: t for t in threading.enumerate()} for tid, stack in sorted(sys._current_frames().items()): # This is a bug in earlier Python versions. # http://bugs.python.org/issue17094 # Note that this leaves out all threads not created via the threading module. if tid not in threads: continue tags = [] thread = threads.get(tid) if thread: assert isinstance(thread, threading.Thread) if thread is threading.current_thread(): tags += ["current"] if thread is threading.main_thread(): tags += ["main"] tags += [str(thread)] else: tags += ["unknown with id %i" % tid] print("Thread %s:" % ", ".join(tags), file=file) if tid in exclude_thread_ids: print("(Excluded thread.)\n", file=file) continue stack_frames = [f[0] for f in walk_stack(stack)] stack_func_code = [f.f_code for f in stack_frames] if mp_worker.__code__ in stack_func_code: i = stack_func_code.index(mp_worker.__code__) if i > 0 and stack_func_code[i - 1] is Queue.get.__code__: print("(Exclude multiprocessing idling worker.)\n", file=file) continue if Pool._handle_tasks.__code__ in stack_func_code: i = stack_func_code.index(Pool._handle_tasks.__code__) if i > 0 and stack_func_code[i - 1] is Queue.get.__code__: print("(Exclude multiprocessing idling task handler.)\n", file=file) continue if Pool._handle_workers.__code__ in stack_func_code: i = stack_func_code.index(Pool._handle_workers.__code__) if i == 0: # time.sleep is native, thus not on the stack print("(Exclude multiprocessing idling worker handler.)\n", file=file) continue if Pool._handle_results.__code__ in stack_func_code: i = stack_func_code.index(Pool._handle_results.__code__) if i > 0 and stack_func_code[i - 1] is Queue.get.__code__: print("(Exclude multiprocessing idling result handler.)\n", file=file) continue print_stack(stack, file=file) print("", file=file) print("That were all threads.", file=file)
def _print_stacks(): id2name = dict((th.ident, th.name) for th in threading.enumerate()) for threadId, stack in sys._current_frames().items(): print(id2name[threadId]) traceback.print_stack(f=stack)
## If there is an associated application, then we can start it up now as ## well. It will listen for UI update requests from the ravenThread. if simulation.app is not None: simulation.app.exec_() ## This makes sure that the main thread waits for RAVEN to complete before ## exiting, however join will block the main thread until ravenThread is ## complete, thus ignoring any kill signals until after it has completed # ravenThread.join() waitTime = 0.1 ## in seconds ## So, in order to live wait for ravenThread, we need a spinlock that will ## allow us to accept keyboard input. while ravenThread.isAlive(): ## Use one of these two alternatives, effectively they should be the same ## not sure if there is any advantage to one over the other time.sleep(waitTime) # ravenThread.join(waitTime) except KeyboardInterrupt: if ravenThread.isAlive(): traceback.print_stack(sys._current_frames()[ravenThread.ident]) print('\n\n! Received keyboard interrupt, exiting RAVEN.\n\n') except SystemExit: if ravenThread.isAlive(): traceback.print_stack(sys._current_frames()[ravenThread.ident]) print('\n\n! Exit called, exiting RAVEN.\n\n') else: raven()
def dump_thread_stacks(): for (k,v) in sys._current_frames().items(): stack = traceback.format_stack(f=v) text = '\nThread {}:\n{}'.format(hex(k), '\n'.join(stack)) logging.debug(text)
def test_identifier(): frame = sys._current_frames()[get_thread_identity()] assert identifier(frame) == identifier(frame) assert identifier(None) == identifier(None)
def test_call_stack(): frame = sys._current_frames()[get_thread_identity()] L = call_stack(frame) assert isinstance(L, list) assert all(isinstance(s, str) for s in L) assert 'test_call_stack' in str(L[-1])
def __init__(self): print("---2----") frame = sys._current_frames() frame2 = sys._getframe() print(frame) print(frame2)
def run(self, args): # FIXME: add thread locking here? self.thread_name = Mthread.current_thread_name() name2id = Mthread.map_thread_names() # invert threading._active for thread_id in list(threading._active.keys()): thread = threading._active[thread_id] name = thread.getName() if name not in list(self.name2id.keys()): self.name2id[name] = thread_id pass pass all_verbose = False if len(args) == 1: if args[0].startswith('verbose'): all_verbose = True elif args[0].startswith('terse'): self.info_thread_terse(name2id) return pass if len(args) > 0 and not all_verbose: thread_name = args[0] if thread_name == '.': thread_name = self.thread_name try: thread_id = int(thread_name) if thread_id not in list(threading._active.keys()): self.errmsg("Don't know about thread number %s" % thread_name) self.info_thread_terse(name2id) return except ValueError: if thread_name not in list(self.name2id.keys()): self.errmsg("Don't know about thread %s" % thread_name) self.info_thread_terse(name2id) return thread_id = self.name2id[thread_name] pass frame = sys._current_frames()[thread_id] self.stack_trace(frame) return # Show info about *all* threads thread_key_list = list(self.name2id.keys()) thread_key_list.sort() for thread_name in thread_key_list: thread_id = self.name2id[thread_name] frame = sys._current_frames()[thread_id] s = '' # Print location where thread was created and line number if thread_id in threading._active: thread = threading._active[thread_id] thread_name = thread.getName() if thread_name == self.proc.frame_thread_name: prefix = '-> ' if not self.settings['dbg_trepan']: frame = Mthread.find_debugged_frame(frame) pass pass elif thread_name == self.proc.thread_name: prefix = '=> ' else: prefix = ' ' pass s += "%s%s" % (prefix, str(thread)) if all_verbose: s += ": %d" % thread_id pass else: s += " thread id: %d" % thread_id pass s += "\n " s += Mstack.format_stack_entry(self, (frame, frame.f_lineno), color=self.settings['highlight']) self.section('-' * 40) self.msg(s) frame = frame.f_back if all_verbose and frame: self.stack_trace(frame) pass return