debug: dump asyncio tasks

This commit is contained in:
Maximilian Hils 2020-11-21 19:48:55 +01:00
parent 9b7dfb0fc9
commit 9b0c4e2338
2 changed files with 83 additions and 52 deletions

View File

@ -1,14 +1,17 @@
import asyncio
import gc import gc
import linecache
import os import os
import platform import platform
import signal import signal
import sys import sys
import threading import threading
import traceback import traceback
from contextlib import redirect_stdout
from OpenSSL import SSL from OpenSSL import SSL
from mitmproxy import version from mitmproxy import version
from mitmproxy.utils import asyncio_utils
def dump_system_info(): def dump_system_info():
@ -24,60 +27,79 @@ def dump_system_info():
def dump_info(signal=None, frame=None, file=sys.stdout, testing=False): # pragma: no cover def dump_info(signal=None, frame=None, file=sys.stdout, testing=False): # pragma: no cover
print("****************************************************", file=file) with redirect_stdout(file):
print("Summary", file=file) print("****************************************************")
print("=======", file=file) print("Summary")
print("=======")
try: try:
import psutil import psutil
except: except:
print("(psutil not installed, skipping some debug info)", file=file) print("(psutil not installed, skipping some debug info)")
else:
p = psutil.Process()
print("num threads: ", p.num_threads(), file=file)
if hasattr(p, "num_fds"):
print("num fds: ", p.num_fds(), file=file)
print("memory: ", p.memory_info(), file=file)
print(file=file)
print("Files", file=file)
print("=====", file=file)
for i in p.open_files():
print(i, file=file)
print(file=file)
print("Connections", file=file)
print("===========", file=file)
for i in p.connections():
print(i, file=file)
print(file=file)
print("Threads", file=file)
print("=======", file=file)
bthreads = []
for i in threading.enumerate():
if hasattr(i, "_threadinfo"):
bthreads.append(i)
else: else:
print(i.name, file=file) p = psutil.Process()
bthreads.sort(key=lambda x: x._thread_started) print("num threads: ", p.num_threads())
for i in bthreads: if hasattr(p, "num_fds"):
print(i._threadinfo(), file=file) print("num fds: ", p.num_fds())
print("memory: ", p.memory_info())
print(file=file) print()
print("Memory", file=file) print("Files")
print("=======", file=file) print("=====")
gc.collect() for i in p.open_files():
d = {} print(i)
for i in gc.get_objects():
t = str(type(i)) print()
if "mitmproxy" in t: print("Connections")
d[t] = d.setdefault(t, 0) + 1 print("===========")
itms = list(d.items()) for i in p.connections():
itms.sort(key=lambda x: x[1]) print(i)
for i in itms[-20:]:
print(i[1], i[0], file=file) print()
print("****************************************************", file=file) print("Threads")
print("=======")
bthreads = []
for i in threading.enumerate():
if hasattr(i, "_threadinfo"):
bthreads.append(i)
else:
print(i.name)
bthreads.sort(key=lambda x: x._thread_started)
for i in bthreads:
print(i._threadinfo())
print()
print("Memory")
print("=======")
gc.collect()
d = {}
for i in gc.get_objects():
t = str(type(i))
if "mitmproxy" in t:
d[t] = d.setdefault(t, 0) + 1
itms = list(d.items())
itms.sort(key=lambda x: x[1])
for i in itms[-20:]:
print(i[1], i[0])
try:
if sys.version_info < (3, 8):
raise RuntimeError
asyncio.get_running_loop()
except RuntimeError:
pass
else:
print()
print("Tasks")
print("=======")
for task in asyncio.all_tasks():
f = task.get_stack(limit=1)[0]
line = linecache.getline(f.f_code.co_filename, f.f_lineno, f.f_globals).strip()
line = f"{line} # at {os.path.basename(f.f_code.co_filename)}:{f.f_lineno}"
print(f"{asyncio_utils.task_repr(task)}\n"
f" {line}")
print("****************************************************")
if not testing: if not testing:
sys.exit(1) sys.exit(1)

View File

@ -17,6 +17,15 @@ def test_dump_info():
cs = io.StringIO() cs = io.StringIO()
debug.dump_info(None, None, file=cs, testing=True) debug.dump_info(None, None, file=cs, testing=True)
assert cs.getvalue() assert cs.getvalue()
assert "Tasks" not in cs.getvalue()
@pytest.mark.asyncio
async def test_dump_info_async():
cs = io.StringIO()
debug.dump_info(None, None, file=cs, testing=True)
if sys.version_info >= (3,8):
assert "Tasks" in cs.getvalue()
def test_dump_stacks(): def test_dump_stacks():