History

perf python scripting: Improve the failed-syscalls-by-pid script

. Print message at script start telling how to get te summary . Print the syscall name using the audit-lib-python package, if installed . Print the errno string . Accept both pid (if numeric) or COMM name Now it looks like this: [root@emilia ~]# perf trace failed-syscalls-by-pid Press control+C to stop and show the summary ^C syscall errors: comm [pid] count ------------------------------ ---------- automount [1670] syscall: futex err = ETIMEDOUT 39 irqbalance [1462] syscall: openat err = ENOENT 4 perf [7888] syscall: lseek err = ESPIPE 1 syscall: open err = ENOENT 24 perf [7889] syscall: ioctl err = EINVAL 1 syscall: readlink err = EINVAL 2 syscall: open err = ENOENT 389 syscall: stat err = ENOENT 141 syscall: lseek err = ESPIPE 3 [root@emilia ~]# [root@emilia ~]# perf trace failed-syscalls-by-pid 1670 Press control+C to stop and show the summary ^C syscall errors: comm [pid] count ------------------------------ ---------- automount [1670] syscall: futex err = ETIMEDOUT 2 [root@emilia ~]# [root@emilia ~]# [root@emilia ~]# [root@emilia ~]# perf trace failed-syscalls-by-pid automount Press control+C to stop and show the summary ^C syscall errors for automount: comm [pid] count ------------------------------ ---------- automount [1669] syscall: futex err = ETIMEDOUT 1 automount [1670] syscall: futex err = ETIMEDOUT 5 [root@emilia ~]#

Arnaldo Carvalho de Melo committed 16 years ago

Commit 6cc73611 parent 66a301c2 files · +50 −8Browse files

Showing the changes to tools/perf/scripts/python (2 of 2 files). Show all

Unified · Split

2 files
  1. tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py +37 −0
  2. tools/perf/scripts/python/failed-syscalls-by-pid.py +13 −8
tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/Util.py+37−0
@@ -6,6 +6,8 @@ · 5 unmodified lines
66 # Public License ("GPL") version 2 as published by the Free Software
77 # Foundation.
88
9+import errno, os
10+
911 NSECS_PER_SEC = 1000000000
1012
1113 def avg(total, n):
@@ -26,3 +28,38 @@ def nsecs_str(nsecs): · 14 unmodified lines
2628
2729 def clear_term():
2830 print("\x1b[H\x1b[2J")
31+
32+audit_package_warned = False
33+
34+try:
35+ import audit
36+ machine_to_id = {
37+ 'x86_64': audit.MACH_86_64,
38+ 'alpha' : audit.MACH_ALPHA,
39+ 'armeb' : audit.MACH_ARMEB,
40+ 'ia64' : audit.MACH_IA64,
41+ 'ppc' : audit.MACH_PPC,
42+ 'ppc64' : audit.MACH_PPC64,
43+ 's390' : audit.MACH_S390,
44+ 's390x' : audit.MACH_S390X,
45+ 'i386' : audit.MACH_X86,
46+ 'i586' : audit.MACH_X86,
47+ 'i686' : audit.MACH_X86,
48+ }
49+ machine_id = machine_to_id[os.uname()[4]]
50+except:
51+ if not audit_package_warned:
52+ audit_package_warned = True
53+ print "Install the audit-libs-python package to get syscall names"
54+
55+def syscall_name(id):
56+ try:
57+ return audit.audit_syscall_to_name(id, machine_id)
58+ except:
59+ return str(id)
60+
61+def strerror(nr):
62+ try:
63+ return errno.errorcode[abs(nr)]
64+ except:
65+ return "Unknown %d errno" % nr
tools/perf/scripts/python/failed-syscalls-by-pid.py+13−8
@@ -13,21 +13,26 @@ sys.path.append(os.environ['PERF_EXEC_PATH'] + \ · 12 unmodified lines
1313
1414 from perf_trace_context import *
1515 from Core import *
16+from Util import *
1617
17−usage = "perf trace -s syscall-counts-by-pid.py [comm]\n";
18+usage = "perf trace -s syscall-counts-by-pid.py [comm|pid]\n";
1819
1920 for_comm = None
21+for_pid = None
2022
2123 if len(sys.argv) > 2:
2224 sys.exit(usage)
2325
2426 if len(sys.argv) > 1:
25− for_comm = sys.argv[1]
27+ try:
28+ for_pid = int(sys.argv[1])
29+ except:
30+ for_comm = sys.argv[1]
2631
2732 syscalls = autodict()
2833
2934 def trace_begin():
30− pass
35+ print "Press control+C to stop and show the summary"
3136
3237 def trace_end():
3338 print_error_totals()
@@ -35,9 +40,9 @@ def trace_end(): · 1 unmodified line
3540 def raw_syscalls__sys_exit(event_name, context, common_cpu,
3641 common_secs, common_nsecs, common_pid, common_comm,
3742 id, ret):
38− if for_comm is not None:
39− if common_comm != for_comm:
40− return
43+ if (for_comm and common_comm != for_comm) or \
44+ (for_pid and common_pid != for_pid ):
45+ return
4146
4247 if ret < 0:
4348 try:
@@ -62,7 +67,7 @@ def print_error_totals(): · 18 unmodified lines
6267 print "\n%s [%d]\n" % (comm, pid),
6368 id_keys = syscalls[comm][pid].keys()
6469 for id in id_keys:
65− print " syscall: %-16d\n" % (id),
70+ print " syscall: %-16s\n" % syscall_name(id),
6671 ret_keys = syscalls[comm][pid][id].keys()
6772 for ret, val in sorted(syscalls[comm][pid][id].iteritems(), key = lambda(k, v): (v, k), reverse = True):
68− print " err = %-20d %10d\n" % (ret, val),
73+ print " err = %-20s %10d\n" % (strerror(ret), val),