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
6# Public License ("GPL") version 2 as published by the Free Software6# Public License ("GPL") version 2 as published by the Free Software
7# Foundation.7# Foundation.
8 8
9import errno, os
10
9NSECS_PER_SEC = 100000000011NSECS_PER_SEC = 1000000000
10 12
11def avg(total, n):13def avg(total, n):
@@ -26,3 +28,38 @@ def nsecs_str(nsecs): · 14 unmodified lines
26 28
27def clear_term():29def clear_term():
28 print("\x1b[H\x1b[2J")30 print("\x1b[H\x1b[2J")
31
32audit_package_warned = False
33
34try:
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]]
50except:
51 if not audit_package_warned:
52 audit_package_warned = True
53 print "Install the audit-libs-python package to get syscall names"
54
55def syscall_name(id):
56 try:
57 return audit.audit_syscall_to_name(id, machine_id)
58 except:
59 return str(id)
60
61def 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
13 13
14from perf_trace_context import *14from perf_trace_context import *
15from Core import *15from Core import *
16from Util import *
16 17
17usage = "perf trace -s syscall-counts-by-pid.py [comm]\n";18usage = "perf trace -s syscall-counts-by-pid.py [comm|pid]\n";
18 19
19for_comm = None20for_comm = None
21for_pid = None
20 22
21if len(sys.argv) > 2:23if len(sys.argv) > 2:
22 sys.exit(usage)24 sys.exit(usage)
23 25
24if len(sys.argv) > 1:26if 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]
26 31
27syscalls = autodict()32syscalls = autodict()
28 33
29def trace_begin():34def trace_begin():
30 pass35 print "Press control+C to stop and show the summary"
31 36
32def trace_end():37def trace_end():
33 print_error_totals()38 print_error_totals()
@@ -35,9 +40,9 @@ def trace_end(): · 1 unmodified line
35def raw_syscalls__sys_exit(event_name, context, common_cpu,40def raw_syscalls__sys_exit(event_name, context, common_cpu,
36 common_secs, common_nsecs, common_pid, common_comm,41 common_secs, common_nsecs, common_pid, common_comm,
37 id, ret):42 id, ret):
38 if for_comm is not None:43 if (for_comm and common_comm != for_comm) or \
39 if common_comm != for_comm:44 (for_pid and common_pid != for_pid ):
40 return45 return
41 46
42 if ret < 0:47 if ret < 0:
43 try:48 try:
@@ -62,7 +67,7 @@ def print_error_totals(): · 18 unmodified lines
62 print "\n%s [%d]\n" % (comm, pid),67 print "\n%s [%d]\n" % (comm, pid),
63 id_keys = syscalls[comm][pid].keys()68 id_keys = syscalls[comm][pid].keys()
64 for id in id_keys:69 for id in id_keys:
65 print " syscall: %-16d\n" % (id),70 print " syscall: %-16s\n" % syscall_name(id),
66 ret_keys = syscalls[comm][pid][id].keys()71 ret_keys = syscalls[comm][pid][id].keys()
67 for ret, val in sorted(syscalls[comm][pid][id].iteritems(), key = lambda(k, v): (v, k), reverse = True):72 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),