[diffoscope] 02/03: Print top memory allocations when receiving USR1
Jérémy Bobbio
lunar at moszumanska.debian.org
Tue Dec 22 18:22:38 CET 2015
This is an automated email from the git hooks/post-receive script.
lunar pushed a commit to branch master
in repository diffoscope.
commit 4530f664a0cf6e9cef13b3b0bc9f7bcdd23144b9
Author: Jérémy Bobbio <lunar at debian.org>
Date: Tue Dec 22 13:57:56 2015 +0000
Print top memory allocations when receiving USR1
In order to debug the current large memory requirements, we implement
support for displaying top memory allocations when receiving the USR1 signal.
The code comes from the Python documentation for the tracemalloc module.
---
diffoscope/__main__.py | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/diffoscope/__main__.py b/diffoscope/__main__.py
index ac7913c..09382af 100644
--- a/diffoscope/__main__.py
+++ b/diffoscope/__main__.py
@@ -20,12 +20,14 @@
import argparse
from contextlib import contextmanager
+import linecache
import logging
import codecs
import os
import signal
import sys
import traceback
+import tracemalloc
try:
import tlsh
except ImportError:
@@ -162,18 +164,53 @@ def run_diffoscope(parsed_args):
return 0
+def display_top(snapshot, group_by='lineno', limit=10):
+ snapshot = snapshot.filter_traces((
+ tracemalloc.Filter(False, "<frozen importlib._bootstrap>"),
+ tracemalloc.Filter(False, "<unknown>"),
+ ))
+ top_stats = snapshot.statistics(group_by)
+
+ logger.debug("Top %s lines", limit)
+ for index, stat in enumerate(top_stats[:limit], 1):
+ frame = stat.traceback[0]
+ # replace "/path/to/module/file.py" with "module/file.py"
+ filename = os.sep.join(frame.filename.split(os.sep)[-2:])
+ logger.debug("#%s: %s:%s: %.1f KiB",
+ index, filename, frame.lineno, stat.size / 1024)
+ line = linecache.getline(frame.filename, frame.lineno).strip()
+ if line:
+ logger.debug(' %s', line)
+
+ other = top_stats[limit:]
+ if other:
+ size = sum(stat.size for stat in other)
+ logger.debug("%s other: %.1f KiB", len(other), size / 1024)
+ total = sum(stat.size for stat in top_stats)
+ logger.debug("Total allocated size: %.1f KiB", total / 1024)
+
+
def sigterm_handler(signo, stack_frame):
sys.exit(2)
+def sigusr1_handler(signo, stack_frame):
+ logger.debug('got SIGUSR1')
+ snapshot = tracemalloc.take_snapshot()
+ logger.debug('display_top')
+ display_top(snapshot)
+
+
def main(args=None):
if args is None:
args = sys.argv[1:]
signal.signal(signal.SIGTERM, sigterm_handler)
+ signal.signal(signal.SIGUSR1, sigusr1_handler)
parsed_args = None
try:
parser = create_parser()
parsed_args = parser.parse_args(args)
+ tracemalloc.start()
sys.exit(run_diffoscope(parsed_args))
except KeyboardInterrupt:
logger.info('Keyboard Interrupt')
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git
More information about the diffoscope
mailing list