aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Myllynen <myllynen@redhat.com>2018-09-26 20:09:07 +0300
committeryonghong-song <ys114321@gmail.com>2018-09-26 10:09:07 -0700
commit27e7aeab5d7b9f0f4259fb0f996274af0521243f (patch)
tree0ae870d5b088e56bdee091627a043957a4de6f8d
parent3d2211632247ad0d1ee9d1ecc1162764322eb974 (diff)
downloadbcc-27e7aeab5d7b9f0f4259fb0f996274af0521243f.zip
bcc-27e7aeab5d7b9f0f4259fb0f996274af0521243f.tar.gz
bcc-27e7aeab5d7b9f0f4259fb0f996274af0521243f.tar.bz2
tools: continue adding --ebpf support (#1986)
Use argparse in cachestat, add --ebpf support. Add --ebpf support for u* tools, finalize language sorting. Remove sole --ebpf string on usage line in tcpsubnet.
-rwxr-xr-xtools/cachestat.py64
-rwxr-xr-xtools/lib/ucalls.py8
-rwxr-xr-xtools/lib/uflow.py9
-rwxr-xr-xtools/lib/ugc.py43
-rwxr-xr-xtools/lib/uobjnew.py45
-rwxr-xr-xtools/lib/ustat.py6
-rwxr-xr-xtools/lib/uthreads.py9
-rwxr-xr-xtools/tcpsubnet.py2
8 files changed, 102 insertions, 84 deletions
diff --git a/tools/cachestat.py b/tools/cachestat.py
index 573c697..b00c804 100755
--- a/tools/cachestat.py
+++ b/tools/cachestat.py
@@ -19,6 +19,7 @@
from __future__ import print_function
from bcc import BPF
from time import sleep, strftime
+import argparse
import signal
import re
from sys import argv
@@ -48,43 +49,25 @@ misses = 0
hits = 0
debug = 0
-# args
-def usage():
- print("USAGE: %s [-T] [ interval [count] ]" % argv[0])
- exit()
-
# arguments
-interval = 5
-count = -1
-tstamp = 0
-
-if len(argv) > 1:
- if str(argv[1]) == '-T':
- tstamp = 1
-
-if len(argv) > 1 and tstamp == 0:
- try:
- if int(argv[1]) > 0:
- interval = int(argv[1])
- if len(argv) > 2:
- if int(argv[2]) > 0:
- count = int(argv[2])
- except:
- usage()
-
-elif len(argv) > 2 and tstamp == 1:
- try:
- if int(argv[2]) > 0:
- interval = int(argv[2])
- if len(argv) >= 4:
- if int(argv[3]) > 0:
- count = int(argv[3])
- except:
- usage()
-
-# load BPF program
+parser = argparse.ArgumentParser(
+ description="Count cache kernel function calls",
+ formatter_class=argparse.RawDescriptionHelpFormatter)
+parser.add_argument("-T", "--timestamp", action="store_true",
+ help="include timestamp on output")
+parser.add_argument("interval", nargs="?", default=5,
+ help="output interval, in seconds")
+parser.add_argument("count", nargs="?", default=-1,
+ help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+ help=argparse.SUPPRESS)
+args = parser.parse_args()
+count = int(args.count)
+tstamp = args.timestamp
+interval = int(args.interval)
+
+# define BPF program
bpf_text = """
-
#include <uapi/linux/ptrace.h>
struct key_t {
u64 ip;
@@ -102,6 +85,13 @@ int do_count(struct pt_regs *ctx) {
}
"""
+
+if debug or args.ebpf:
+ print(bpf_text)
+ if args.ebpf:
+ exit()
+
+# load BPF program
b = BPF(text=bpf_text)
b.attach_kprobe(event="add_to_page_cache_lru", fn_name="do_count")
b.attach_kprobe(event="mark_page_accessed", fn_name="do_count")
@@ -129,7 +119,7 @@ while 1:
# as cleanup can take many seconds, trap Ctrl-C:
signal.signal(signal.SIGINT, signal_ignore)
- counts = b.get_table("counts")
+ counts = b["counts"]
for k, v in sorted(counts.items(), key=lambda counts: counts[1].value):
if re.match(b'mark_page_accessed', b.ksym(k.ip)) is not None:
@@ -175,7 +165,7 @@ while 1:
cached = int(mem["Cached"]) / 1024
buff = int(mem["Buffers"]) / 1024
- if tstamp == 1:
+ if tstamp:
print("%-8s " % strftime("%H:%M:%S"), end="")
print("%8d %8d %8d %8d %12.0f %10.0f" %
(total, misses, hits, mbd, buff, cached))
diff --git a/tools/lib/ucalls.py b/tools/lib/ucalls.py
index b2d165c..1a0fe21 100755
--- a/tools/lib/ucalls.py
+++ b/tools/lib/ucalls.py
@@ -49,6 +49,8 @@ parser.add_argument("-v", "--verbose", action="store_true",
help="verbose mode: print the BPF program (for debugging purposes)")
parser.add_argument("-m", "--milliseconds", action="store_true",
help="report times in milliseconds (default is microseconds)")
+parser.add_argument("--ebpf", action="store_true",
+ help=argparse.SUPPRESS)
args = parser.parse_args()
language = args.language
@@ -243,10 +245,12 @@ if language:
else:
usdt = None
-if args.verbose:
- if usdt:
+if args.ebpf or args.verbose:
+ if args.verbose and usdt:
print(usdt.get_text())
print(program)
+ if args.ebpf:
+ exit()
bpf = BPF(text=program, usdt_contexts=[usdt] if usdt else [])
if args.syscalls:
diff --git a/tools/lib/uflow.py b/tools/lib/uflow.py
index 8419c88..fb306e3 100755
--- a/tools/lib/uflow.py
+++ b/tools/lib/uflow.py
@@ -39,6 +39,8 @@ parser.add_argument("-C", "--class", dest="clazz",
help="trace only calls to classes starting with this prefix")
parser.add_argument("-v", "--verbose", action="store_true",
help="verbose mode: print the BPF program (for debugging purposes)")
+parser.add_argument("--ebpf", action="store_true",
+ help=argparse.SUPPRESS)
args = parser.parse_args()
usdt = USDT(pid=args.pid)
@@ -165,9 +167,12 @@ else:
print("No language detected; use -l to trace a language.")
exit(1)
-if args.verbose:
- print(usdt.get_text())
+if args.ebpf or args.verbose:
+ if args.verbose:
+ print(usdt.get_text())
print(program)
+ if args.ebpf:
+ exit()
bpf = BPF(text=program, usdt_contexts=[usdt])
print("Tracing method calls in %s process %d... Ctrl-C to quit." %
diff --git a/tools/lib/ugc.py b/tools/lib/ugc.py
index 9f4d258..8288910 100755
--- a/tools/lib/ugc.py
+++ b/tools/lib/ugc.py
@@ -4,7 +4,7 @@
# ugc Summarize garbage collection events in high-level languages.
# For Linux, uses BCC, eBPF.
#
-# USAGE: ugc [-v] [-m] [-M MSEC] [-F FILTER] {java,python,ruby,node} pid
+# USAGE: ugc [-v] [-m] [-M MSEC] [-F FILTER] {java,node,python,ruby} pid
#
# Copyright 2016 Sasha Goldshtein
# Licensed under the Apache License, Version 2.0 (the "License")
@@ -18,7 +18,7 @@ import ctypes as ct
import time
import os
-languages = ["java", "python", "ruby", "node"]
+languages = ["java", "node", "python", "ruby"]
examples = """examples:
./ugc -l java 185 # trace Java GCs in process 185
@@ -40,6 +40,8 @@ parser.add_argument("-M", "--minimum", type=int, default=0,
help="display only GCs longer than this many milliseconds")
parser.add_argument("-F", "--filter", type=str,
help="display only GCs whose description contains this text")
+parser.add_argument("--ebpf", action="store_true",
+ help=argparse.SUPPRESS)
args = parser.parse_args()
usdt = USDT(pid=args.pid)
@@ -150,6 +152,21 @@ if language == "java":
probes.append(Probe("gc__begin", "gc__end",
"", "", lambda _: "no additional info available"))
#
+# Node
+#
+elif language == "node":
+ end_save = """
+ u32 gc_type = 0;
+ bpf_usdt_readarg(1, ctx, &gc_type);
+ event.field1 = gc_type;
+ """
+ descs = {"GC scavenge": 1, "GC mark-sweep-compact": 2,
+ "GC incremental mark": 4, "GC weak callbacks": 8}
+ probes.append(Probe("gc__start", "gc__done", "", end_save,
+ lambda e: str.join(", ",
+ [desc for desc, val in descs.items()
+ if e.field1 & val != 0])))
+#
# Python
#
elif language == "python":
@@ -179,21 +196,6 @@ elif language == "ruby":
"", "", lambda _: "GC mark stage"))
probes.append(Probe("gc__sweep__begin", "gc__sweep__end",
"", "", lambda _: "GC sweep stage"))
-#
-# Node
-#
-elif language == "node":
- end_save = """
- u32 gc_type = 0;
- bpf_usdt_readarg(1, ctx, &gc_type);
- event.field1 = gc_type;
- """
- descs = {"GC scavenge": 1, "GC mark-sweep-compact": 2,
- "GC incremental mark": 4, "GC weak callbacks": 8}
- probes.append(Probe("gc__start", "gc__done", "", end_save,
- lambda e: str.join(", ",
- [desc for desc, val in descs.items()
- if e.field1 & val != 0])))
else:
print("No language detected; use -l to trace a language.")
@@ -204,9 +206,12 @@ for probe in probes:
program += probe.generate()
probe.attach()
-if args.verbose:
- print(usdt.get_text())
+if args.ebpf or args.verbose:
+ if args.verbose:
+ print(usdt.get_text())
print(program)
+ if args.ebpf:
+ exit()
bpf = BPF(text=program, usdt_contexts=[usdt])
print("Tracing garbage collections in %s process %d... Ctrl-C to quit." %
diff --git a/tools/lib/uobjnew.py b/tools/lib/uobjnew.py
index bcd69b4..e3b61ff 100755
--- a/tools/lib/uobjnew.py
+++ b/tools/lib/uobjnew.py
@@ -4,7 +4,7 @@
# uobjnew Summarize object allocations in high-level languages.
# For Linux, uses BCC, eBPF.
#
-# USAGE: uobjnew [-h] [-T TOP] [-v] {java,ruby,c} pid [interval]
+# USAGE: uobjnew [-h] [-T TOP] [-v] {c,java,ruby} pid [interval]
#
# Copyright 2016 Sasha Goldshtein
# Licensed under the Apache License, Version 2.0 (the "License")
@@ -18,7 +18,7 @@ from time import sleep
import os
# C needs to be the last language.
-languages = ["java", "ruby", "c"]
+languages = ["c", "java", "ruby"]
examples = """examples:
./uobjnew -l java 145 # summarize Java allocations in process 145
@@ -41,6 +41,8 @@ parser.add_argument("-S", "--top-size", type=int,
help="number of largest types by allocated bytes to print")
parser.add_argument("-v", "--verbose", action="store_true",
help="verbose mode: print the BPF program (for debugging purposes)")
+parser.add_argument("--ebpf", action="store_true",
+ help=argparse.SUPPRESS)
args = parser.parse_args()
language = args.language
@@ -69,9 +71,24 @@ BPF_HASH(allocs, struct key_t, struct val_t);
usdt = USDT(pid=args.pid)
#
+# C
+#
+if language == "c":
+ program += """
+int alloc_entry(struct pt_regs *ctx, size_t size) {
+ struct key_t key = {};
+ struct val_t *valp, zero = {};
+ key.size = size;
+ valp = allocs.lookup_or_init(&key, &zero);
+ valp->total_size += size;
+ valp->num_allocs += 1;
+ return 0;
+}
+ """
+#
# Java
#
-if language == "java":
+elif language == "java":
program += """
int alloc_entry(struct pt_regs *ctx) {
struct key_t key = {};
@@ -120,30 +137,18 @@ int object_alloc_entry(struct pt_regs *ctx) {
program += create_template.replace("THETHING", thing)
usdt.enable_probe_or_bail("%s__create" % thing,
"%s_alloc_entry" % thing)
-#
-# C
-#
-elif language == "c":
- program += """
-int alloc_entry(struct pt_regs *ctx, size_t size) {
- struct key_t key = {};
- struct val_t *valp, zero = {};
- key.size = size;
- valp = allocs.lookup_or_init(&key, &zero);
- valp->total_size += size;
- valp->num_allocs += 1;
- return 0;
-}
- """
else:
print("No language detected; use -l to trace a language.")
exit(1)
-if args.verbose:
- print(usdt.get_text())
+if args.ebpf or args.verbose:
+ if args.verbose:
+ print(usdt.get_text())
print(program)
+ if args.ebpf:
+ exit()
bpf = BPF(text=program, usdt_contexts=[usdt])
if language == "c":
diff --git a/tools/lib/ustat.py b/tools/lib/ustat.py
index 8b2f80f..7ac0967 100755
--- a/tools/lib/ustat.py
+++ b/tools/lib/ustat.py
@@ -147,6 +147,8 @@ class Tool(object):
help="output interval, in seconds")
parser.add_argument("count", nargs="?", default=99999999, type=int,
help="number of outputs")
+ parser.add_argument("--ebpf", action="store_true",
+ help=argparse.SUPPRESS)
self.args = parser.parse_args()
def _create_probes(self):
@@ -197,8 +199,10 @@ class Tool(object):
def _attach_probes(self):
program = str.join('\n', [p.get_program() for p in self.probes])
- if self.args.debug:
+ if self.args.debug or self.args.ebpf:
print(program)
+ if self.args.ebpf:
+ exit()
for probe in self.probes:
print("Attached to %s processes:" % probe.language,
str.join(', ', map(str, probe.targets)))
diff --git a/tools/lib/uthreads.py b/tools/lib/uthreads.py
index a96750f..fb54599 100755
--- a/tools/lib/uthreads.py
+++ b/tools/lib/uthreads.py
@@ -34,6 +34,8 @@ parser.add_argument("-l", "--language", choices=languages + ["none"],
parser.add_argument("pid", type=int, help="process id to attach to")
parser.add_argument("-v", "--verbose", action="store_true",
help="verbose mode: print the BPF program (for debugging purposes)")
+parser.add_argument("--ebpf", action="store_true",
+ help=argparse.SUPPRESS)
args = parser.parse_args()
usdt = USDT(pid=args.pid)
@@ -88,9 +90,12 @@ int %s(struct pt_regs *ctx) {
usdt.enable_probe_or_bail("thread__start", "trace_start")
usdt.enable_probe_or_bail("thread__stop", "trace_stop")
-if args.verbose:
- print(usdt.get_text())
+if args.ebpf or args.verbose:
+ if args.verbose:
+ print(usdt.get_text())
print(program)
+ if args.ebpf:
+ exit()
bpf = BPF(text=program, usdt_contexts=[usdt])
print("Tracing thread events in process %d (language: %s)... Ctrl-C to quit." %
diff --git a/tools/tcpsubnet.py b/tools/tcpsubnet.py
index 328f426..5f2a806 100755
--- a/tools/tcpsubnet.py
+++ b/tools/tcpsubnet.py
@@ -4,7 +4,7 @@
# tcpsubnet Summarize TCP bytes sent to different subnets.
# For Linux, uses BCC, eBPF. Embedded C.
#
-# USAGE: tcpsubnet [-h] [-v] [--ebpf] [-J] [-f FORMAT] [-i INTERVAL] [subnets]
+# USAGE: tcpsubnet [-h] [-v] [-J] [-f FORMAT] [-i INTERVAL] [subnets]
#
# This uses dynamic tracing of kernel functions, and will need to be updated
# to match kernel changes.