# Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See LICENSE in the project root # for license information. from __future__ import absolute_import, division, print_function, unicode_literals """Provides facilities to dump all stacks of all threads in the process. """ import os import sys import time import threading import traceback from debugpy.common import log def dump(): """Dump stacks of all threads in this process, except for the current thread. """ tid = threading.current_thread().ident pid = os.getpid() log.info("Dumping stacks for process {0}...", pid) for t_ident, frame in sys._current_frames().items(): if t_ident == tid: continue for t in threading.enumerate(): if t.ident == tid: t_name = t.name t_daemon = t.daemon break else: t_name = t_daemon = "" stack = "".join(traceback.format_stack(frame)) log.info( "Stack of thread {0} (tid={1}, pid={2}, daemon={3}):\n\n{4}", t_name, t_ident, pid, t_daemon, stack, ) log.info("Finished dumping stacks for process {0}.", pid) def dump_after(secs): """Invokes dump() on a background thread after waiting for the specified time. """ def dumper(): time.sleep(secs) try: dump() except: log.swallow_exception() thread = threading.Thread(target=dumper) thread.daemon = True thread.start()