1#!/usr/bin/env python 2# 3# tplist Display kernel tracepoints or USDT probes and their formats. 4# 5# USAGE: tplist [-p PID] [-l LIB] [-v] [filter] 6# 7# Licensed under the Apache License, Version 2.0 (the "License") 8# Copyright (C) 2016 Sasha Goldshtein. 9 10import argparse 11import fnmatch 12import os 13import re 14import sys 15 16from bcc import USDT 17 18trace_root = "/sys/kernel/debug/tracing" 19event_root = os.path.join(trace_root, "events") 20 21parser = argparse.ArgumentParser( 22 description="Display kernel tracepoints or USDT probes " + 23 "and their formats.", 24 formatter_class=argparse.RawDescriptionHelpFormatter) 25parser.add_argument("-p", "--pid", type=int, default=None, 26 help="List USDT probes in the specified process") 27parser.add_argument("-l", "--lib", default="", 28 help="List USDT probes in the specified library or executable") 29parser.add_argument("-v", dest="verbosity", action="count", default=0, 30 help="Increase verbosity level (print variables, arguments, etc.)") 31parser.add_argument(dest="filter", nargs="?", 32 help="A filter that specifies which probes/tracepoints to print") 33args = parser.parse_args() 34 35def print_tpoint_format(category, event): 36 fmt = open(os.path.join(event_root, category, event, "format")) \ 37 .readlines() 38 for line in fmt: 39 match = re.search(r'field:([^;]*);', line) 40 if match is None: 41 continue 42 parts = match.group(1).split() 43 field_name = parts[-1:][0] 44 field_type = " ".join(parts[:-1]) 45 if field_name.startswith("common_"): 46 continue 47 print(" %s %s;" % (field_type, field_name)) 48 49def print_tpoint(category, event): 50 tpoint = "%s:%s" % (category, event) 51 if not args.filter or fnmatch.fnmatch(tpoint, args.filter): 52 print(tpoint) 53 if args.verbosity > 0: 54 print_tpoint_format(category, event) 55 56def print_tracepoints(): 57 for category in os.listdir(event_root): 58 cat_dir = os.path.join(event_root, category) 59 if not os.path.isdir(cat_dir): 60 continue 61 for event in os.listdir(cat_dir): 62 evt_dir = os.path.join(cat_dir, event) 63 if os.path.isdir(evt_dir): 64 print_tpoint(category, event) 65 66def print_usdt_argument_details(location): 67 for idx in range(0, location.num_arguments): 68 arg = location.get_argument(idx) 69 print(" argument #%d %s" % (idx + 1, arg)) 70 71def print_usdt_details(probe): 72 if args.verbosity > 0: 73 print(probe) 74 if args.verbosity > 1: 75 for idx in range(0, probe.num_locations): 76 loc = probe.get_location(idx) 77 print(" location #%d %s" % (idx + 1, loc)) 78 print_usdt_argument_details(loc) 79 else: 80 print(" %d location(s)" % probe.num_locations) 81 print(" %d argument(s)" % probe.num_arguments) 82 else: 83 print("%s %s:%s" % 84 (probe.bin_path, probe.provider, probe.name)) 85 86def print_usdt(pid, lib): 87 reader = USDT(path=lib, pid=pid) 88 probes_seen = [] 89 for probe in reader.enumerate_probes(): 90 probe_name = probe.short_name() 91 if not args.filter or fnmatch.fnmatch(probe_name, args.filter): 92 if probe_name in probes_seen: 93 continue 94 probes_seen.append(probe_name) 95 print_usdt_details(probe) 96 97if __name__ == "__main__": 98 try: 99 if args.pid or args.lib != "": 100 print_usdt(args.pid, args.lib) 101 else: 102 print_tracepoints() 103 except: 104 if sys.exc_info()[0] is not SystemExit: 105 print(sys.exc_info()[1]) 106