# SPDX-License-Identifier: GPL-2.0 "Record and report data access pattern in realtime" import argparse import os import signal import subprocess import sys import _damon import _damon_args def cleanup(): if target_type == _damon_args.target_type_cmd and cmd_pipe.poll() == None: cmd_pipe.kill() def sighandler(signum, frame): print('\nsignal %s received' % signum) cleanup() def main(args): _damon.ensure_root_permission() global target_type global cmd_pipe signal.signal(signal.SIGINT, sighandler) signal.signal(signal.SIGTERM, sighandler) target = args.target target_fields = target.split() target_type = _damon_args.deduced_target_type(target) if target_type == None: print('invalid target \'%s\'' % target) exit(1) if target_type == _damon_args.target_type_explicit and target == 'paddr': pass elif target_type == _damon_args.target_type_cmd: cmd_pipe = subprocess.Popen(target, shell=True, executable='/bin/bash', stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) target = cmd_pipe.pid else: pid = int(target) bindir = os.path.dirname(sys.argv[0]) damo = os.path.join(bindir, 'damo') record_cmd = 'timeout %s %s record \"%s\"' % (args.delay, damo, target) report_cmd = [damo] if args.report_type == 'heats': report_cmd += 'report heats --heatmap stdout --resol 10 80'.split() else: report_cmd += ['report', 'wss'] nr_reports = 0 while not args.count or nr_reports < args.count: if (target_type == _damon_args.target_type_cmd and cmd_pipe.poll() != None): break try: subprocess.check_output(record_cmd, shell=True, stderr=subprocess.STDOUT, executable='/bin/bash') except subprocess.CalledProcessError as e: pass try: output = subprocess.check_output(report_cmd).decode() if args.report_type == 'heats': for line in output.strip().split('\n'): if not line.startswith('#'): print(line) else: print(output) except subprocess.CalledProcessError as e: pass nr_reports += 1 cleanup() def set_argparser(parser): parser.add_argument('target', type=str, metavar='', help='monitoring target (command, pid or \'paddr\')') parser.add_argument('--report_type', type=str, choices=['heats', 'wss'], default='heats', help='report type') parser.add_argument('--delay', type=float, metavar='', default=3, help='deplay between updates in seconds.') parser.add_argument('--count', type=int, metavar='', default=0, help='number of updates.')