continue adding --ebpf option to the python tools/ scripts

Several python tools allow their eBPF code to be printed to
stdout for debugging.  There are other projects that would
like to share these program definitions however, instead of
duplicating code.  We previously agreed on an --ebpf option
and we now continue adding it to more tools.

Signed-off-by: Nathan Scott <nathans@redhat.com>
diff --git a/tools/btrfsdist.py b/tools/btrfsdist.py
index fe5a2bf..4659ab4 100755
--- a/tools/btrfsdist.py
+++ b/tools/btrfsdist.py
@@ -40,6 +40,8 @@
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 pid = args.pid
 countdown = int(args.count)
@@ -183,8 +185,10 @@
     bpf_text = bpf_text.replace('FILTER_PID', 'pid != %s' % pid)
 else:
     bpf_text = bpf_text.replace('FILTER_PID', '0')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # load BPF program
 b = BPF(text=bpf_text)
diff --git a/tools/btrfsslower.py b/tools/btrfsslower.py
index f145dcf..5623018 100755
--- a/tools/btrfsslower.py
+++ b/tools/btrfsslower.py
@@ -51,6 +51,8 @@
     help="trace this PID only")
 parser.add_argument("min_ms", nargs="?", default='10',
     help="minimum I/O duration to trace, in ms (default 10)")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 min_ms = int(args.min_ms)
 pid = args.pid
@@ -280,8 +282,10 @@
     bpf_text = bpf_text.replace('FILTER_PID', 'pid != %s' % pid)
 else:
     bpf_text = bpf_text.replace('FILTER_PID', '0')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # kernel->user event data: struct data_t
 DNAME_INLINE_LEN = 32   # linux/dcache.h
diff --git a/tools/cpudist.py b/tools/cpudist.py
index 47658c0..4d7c9eb 100755
--- a/tools/cpudist.py
+++ b/tools/cpudist.py
@@ -44,6 +44,8 @@
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 countdown = int(args.count)
 debug = 0
@@ -149,8 +151,10 @@
     bpf_text = bpf_text.replace('STORAGE', 'BPF_HISTOGRAM(dist);')
     bpf_text = bpf_text.replace('STORE',
         'dist.increment(bpf_log2l(delta));')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 b = BPF(text=bpf_text)
 b.attach_kprobe(event="finish_task_switch", fn_name="sched_switch")
diff --git a/tools/cpuunclaimed.py b/tools/cpuunclaimed.py
index 58b8e4a..95d88b8 100755
--- a/tools/cpuunclaimed.py
+++ b/tools/cpuunclaimed.py
@@ -87,6 +87,8 @@
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 countdown = int(args.count)
 frequency = 99
@@ -155,8 +157,10 @@
 """
 
 # code substitutions
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF & perf_events
 b = BPF(text=bpf_text)
diff --git a/tools/dbslower.py b/tools/dbslower.py
index d6f36cc..e5578db 100755
--- a/tools/dbslower.py
+++ b/tools/dbslower.py
@@ -51,6 +51,8 @@
     dest="path", metavar="PATH", help="path to binary")
 parser.add_argument("-m", "--threshold", type=int, default=1,
     help="trace queries slower than this threshold (ms)")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 
 threshold_ns = args.threshold * 1000000
@@ -196,8 +198,10 @@
 
     bpf = BPF(text=program, usdt_contexts=usdts)
 
-if args.verbose:
+if args.verbose or args.ebpf:
     print(program)
+    if args.ebpf:
+        exit()
 
 class Data(ct.Structure):
     _fields_ = [
diff --git a/tools/dcsnoop.py b/tools/dcsnoop.py
index 45fc6be..39064c9 100755
--- a/tools/dcsnoop.py
+++ b/tools/dcsnoop.py
@@ -38,6 +38,8 @@
     epilog=examples)
 parser.add_argument("-a", "--all", action="store_true",
     help="trace all lookups (default is fails only)")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 
 # define BPF program
@@ -132,6 +134,10 @@
         ("filename", ct.c_char * MAX_FILE_LEN),
     ]
 
+if args.ebpf:
+    print(bpf_text)
+    exit()
+
 # initialize BPF
 b = BPF(text=bpf_text)
 if args.all:
diff --git a/tools/execsnoop.py b/tools/execsnoop.py
index 5711fd1..651f944 100755
--- a/tools/execsnoop.py
+++ b/tools/execsnoop.py
@@ -46,6 +46,8 @@
     help="only print commands where arg contains this line (regex)")
 parser.add_argument("--max-args", default="20",
     help="maximum number of arguments parsed and displayed, defaults to 20")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 
 # define BPF program
@@ -128,8 +130,13 @@
 }
 """
 
+bpf_text.replace("MAXARG", args.max_args)
+if args.ebpf:
+    print(bpf_text)
+    exit()
+
 # initialize BPF
-b = BPF(text=bpf_text.replace("MAXARG", args.max_args))
+b = BPF(text=bpf_text)
 
 # header
 if args.timestamp:
diff --git a/tools/ext4dist.py b/tools/ext4dist.py
index 4b9142f..2b0c3e4 100755
--- a/tools/ext4dist.py
+++ b/tools/ext4dist.py
@@ -40,6 +40,8 @@
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 pid = args.pid
 countdown = int(args.count)
@@ -163,8 +165,10 @@
     bpf_text = bpf_text.replace('FILTER_PID', 'pid != %s' % pid)
 else:
     bpf_text = bpf_text.replace('FILTER_PID', '0')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # load BPF program
 b = BPF(text=bpf_text)
diff --git a/tools/ext4slower.py b/tools/ext4slower.py
index 09e8572..6ec87da 100755
--- a/tools/ext4slower.py
+++ b/tools/ext4slower.py
@@ -51,6 +51,8 @@
     help="trace this PID only")
 parser.add_argument("min_ms", nargs="?", default='10',
     help="minimum I/O duration to trace, in ms (default 10)")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 min_ms = int(args.min_ms)
 pid = args.pid
@@ -274,8 +276,10 @@
     bpf_text = bpf_text.replace('FILTER_PID', 'pid != %s' % pid)
 else:
     bpf_text = bpf_text.replace('FILTER_PID', '0')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # kernel->user event data: struct data_t
 DNAME_INLINE_LEN = 32   # linux/dcache.h
diff --git a/tools/filelife.py b/tools/filelife.py
index 9405af3..a613304 100755
--- a/tools/filelife.py
+++ b/tools/filelife.py
@@ -34,6 +34,8 @@
     epilog=examples)
 parser.add_argument("-p", "--pid",
     help="trace this PID only")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 debug = 0
 
@@ -114,8 +116,10 @@
         'if (pid != %s) { return 0; }' % args.pid)
 else:
     bpf_text = bpf_text.replace('FILTER', '')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF
 b = BPF(text=bpf_text)
diff --git a/tools/fileslower.py b/tools/fileslower.py
index 996ab58..0f58d91 100755
--- a/tools/fileslower.py
+++ b/tools/fileslower.py
@@ -50,6 +50,8 @@
     help="include non-regular file types (sockets, FIFOs, etc)")
 parser.add_argument("min_ms", nargs="?", default='10',
     help="minimum I/O duration to trace, in ms (default 10)")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 min_ms = int(args.min_ms)
 tgid = args.tgid
@@ -185,11 +187,13 @@
 else:
     bpf_text = bpf_text.replace('TYPE_FILTER', '!S_ISREG(mode)')
 
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF
-b = BPF(text=bpf_text,)
+b = BPF(text=bpf_text)
 
 # I'd rather trace these via new_sync_read/new_sync_write (which used to be
 # do_sync_read/do_sync_write), but those became static. So trace these from
diff --git a/tools/filetop.py b/tools/filetop.py
index c8122ce..1577a5d 100755
--- a/tools/filetop.py
+++ b/tools/filetop.py
@@ -47,6 +47,8 @@
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 interval = int(args.interval)
 countdown = int(args.count)
@@ -149,8 +151,10 @@
 else:
     bpf_text = bpf_text.replace('TYPE_FILTER', '!S_ISREG(mode)')
 
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF
 b = BPF(text=bpf_text)
diff --git a/tools/funclatency.py b/tools/funclatency.py
index d2e65f2..fe06d1b 100755
--- a/tools/funclatency.py
+++ b/tools/funclatency.py
@@ -63,6 +63,8 @@
     help="print the BPF program (for debugging purposes)")
 parser.add_argument("pattern",
     help="search expression for functions")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 
 def bail(error):
@@ -184,8 +186,10 @@
     bpf_text = bpf_text.replace('ENTRYSTORE', '')
     bpf_text = bpf_text.replace('STORE',
         'dist.increment(bpf_log2l(delta));')
-if args.verbose:
+if args.verbose or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # signal handler
 def signal_ignore(signal, frame):
diff --git a/tools/funcslower.py b/tools/funcslower.py
index a807458..55219f2 100755
--- a/tools/funcslower.py
+++ b/tools/funcslower.py
@@ -55,6 +55,8 @@
     help="print the BPF program for debugging purposes")
 parser.add_argument(metavar="function", nargs="+", dest="functions",
     help="function(s) to trace")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 
 args = parser.parse_args()
 # fractions are allowed, but rounded to an integer nanosecond
@@ -165,8 +167,10 @@
 }
 """ % (i, i)
 
-if args.verbose:
+if args.verbose or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 b = BPF(text=bpf_text)
 
diff --git a/tools/gethostlatency.py b/tools/gethostlatency.py
index 77a8b81..7bbd792 100755
--- a/tools/gethostlatency.py
+++ b/tools/gethostlatency.py
@@ -31,6 +31,8 @@
     epilog=examples)
 parser.add_argument("-p", "--pid", help="trace this PID only", type=int,
     default=-1)
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 
 # load BPF program
@@ -94,6 +96,10 @@
     return 0;
 }
 """
+if args.ebpf:
+    print(bpf_text)
+    exit()
+
 b = BPF(text=bpf_text)
 b.attach_uprobe(name="c", sym="getaddrinfo", fn_name="do_entry", pid=args.pid)
 b.attach_uprobe(name="c", sym="gethostbyname", fn_name="do_entry",
diff --git a/tools/hardirqs.py b/tools/hardirqs.py
index 0690f09..6a5da03 100755
--- a/tools/hardirqs.py
+++ b/tools/hardirqs.py
@@ -41,6 +41,8 @@
     help="output interval, in seconds")
 parser.add_argument("outputs", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 countdown = int(args.outputs)
 if args.count and (args.dist or args.nanoseconds):
@@ -136,8 +138,10 @@
         'bpf_probe_read(&key.name, sizeof(key.name), name);' +
         'u64 zero = 0, *vp = dist.lookup_or_init(&key, &zero);' +
         '(*vp) += delta;')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # load BPF program
 b = BPF(text=bpf_text)
diff --git a/tools/killsnoop.py b/tools/killsnoop.py
index 2ca1586..9d86930 100755
--- a/tools/killsnoop.py
+++ b/tools/killsnoop.py
@@ -32,6 +32,8 @@
     help="only show failed kill syscalls")
 parser.add_argument("-p", "--pid",
     help="trace this PID only")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 debug = 0
 
@@ -102,8 +104,10 @@
         'if (pid != %s) { return 0; }' % args.pid)
 else:
     bpf_text = bpf_text.replace('FILTER', '')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF
 b = BPF(text=bpf_text)
diff --git a/tools/llcstat.py b/tools/llcstat.py
index eb32a22..0dfc232 100755
--- a/tools/llcstat.py
+++ b/tools/llcstat.py
@@ -28,10 +28,12 @@
     help="Sample one in this many number of cache reference / miss events")
 parser.add_argument(
     "duration", nargs="?", default=10, help="Duration, in seconds, to run")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 
 # load BPF program
-b = BPF(text="""
+bpf_text="""
 #include <linux/ptrace.h>
 #include <uapi/linux/bpf_perf_event.h>
 
@@ -71,8 +73,13 @@
 
     return 0;
 }
-""")
+"""
 
+if args.ebpf:
+    print(bpf_text)
+    exit()
+
+b = BPF(text=bpf_text)
 b.attach_perf_event(
     ev_type=PerfType.HARDWARE, ev_config=PerfHWConfig.CACHE_MISSES,
     fn_name="on_cache_miss", sample_period=args.sample_period)
diff --git a/tools/memleak.py b/tools/memleak.py
index 5788e32..7725b1e 100755
--- a/tools/memleak.py
+++ b/tools/memleak.py
@@ -97,6 +97,8 @@
         help="capture only allocations smaller than this size")
 parser.add_argument("-O", "--obj", type=str, default="c",
         help="attach to allocator functions in the specified object")
+parser.add_argument("--ebpf", action="store_true",
+        help=argparse.SUPPRESS)
 
 args = parser.parse_args()
 
@@ -384,6 +386,10 @@
         stack_flags += "|BPF_F_USER_STACK"
 bpf_source = bpf_source.replace("STACK_FLAGS", stack_flags)
 
+if args.ebpf:
+    print(bpf_source)
+    exit()
+
 bpf = BPF(text=bpf_source)
 
 if not kernel_trace:
diff --git a/tools/mountsnoop.py b/tools/mountsnoop.py
index 223b2f8..abb39d3 100755
--- a/tools/mountsnoop.py
+++ b/tools/mountsnoop.py
@@ -393,10 +393,15 @@
     parser = argparse.ArgumentParser(
         description='trace mount() and umount() syscalls'
     )
+    parser.add_argument("--ebpf", action="store_true",
+        help=argparse.SUPPRESS)
     args = parser.parse_args()
 
     mounts = {}
     umounts = {}
+    if args.ebpf:
+        print(bpf_text)
+        exit()
     b = bcc.BPF(text=bpf_text)
     b['events'].open_perf_buffer(
         functools.partial(print_event, mounts, umounts))
diff --git a/tools/nfsdist.py b/tools/nfsdist.py
index c38c053..ff78506 100755
--- a/tools/nfsdist.py
+++ b/tools/nfsdist.py
@@ -34,6 +34,8 @@
                     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
                     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+                    help=argparse.SUPPRESS)
 args = parser.parse_args()
 pid = args.pid
 countdown = int(args.count)
@@ -124,8 +126,10 @@
     bpf_text = bpf_text.replace('FILTER_PID', 'pid != %s' % pid)
 else:
     bpf_text = bpf_text.replace('FILTER_PID', '0')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # load BPF program
 b = BPF(text=bpf_text)
diff --git a/tools/nfsslower.py b/tools/nfsslower.py
index cacd473..724b05b 100755
--- a/tools/nfsslower.py
+++ b/tools/nfsslower.py
@@ -53,6 +53,8 @@
 parser.add_argument("-p", "--pid", help="Trace this pid only")
 parser.add_argument("min_ms", nargs="?", default='10',
                     help="Minimum IO duration to trace in ms (default=10ms)")
+parser.add_argument("--ebpf", action="store_true",
+                    help=argparse.SUPPRESS)
 args = parser.parse_args()
 min_ms = int(args.min_ms)
 pid = args.pid
@@ -236,8 +238,10 @@
     bpf_text = bpf_text.replace('FILTER_PID', 'pid != %s' % pid)
 else:
     bpf_text = bpf_text.replace('FILTER_PID', '0')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # kernel->user event data: struct data_t
 DNAME_INLINE_LEN = 32   # linux/dcache.h
diff --git a/tools/offcputime.py b/tools/offcputime.py
index 1f47459..a54d10a 100755
--- a/tools/offcputime.py
+++ b/tools/offcputime.py
@@ -91,6 +91,8 @@
 parser.add_argument("--state", type=positive_int,
     help="filter on this thread state bitmask (eg, 2 == TASK_UNINTERRUPTIBLE" +
          ") see include/linux/sched.h")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 if args.pid and args.tgid:
     parser.error("specify only one of -p and -t")
@@ -222,8 +224,10 @@
           "doesn't make sense.", file=stderr)
     exit(1)
 
-if (debug):
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF
 b = BPF(text=bpf_text)
diff --git a/tools/offwaketime.py b/tools/offwaketime.py
index 10b427a..af4028d 100755
--- a/tools/offwaketime.py
+++ b/tools/offwaketime.py
@@ -88,6 +88,8 @@
     type=positive_nonzero_int,
     help="the amount of time in microseconds under which we " +
          "store traces (default U64_MAX)")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 folded = args.folded
 duration = int(args.duration)
@@ -235,6 +237,9 @@
     stack_context = "user + kernel"
 bpf_text = bpf_text.replace('USER_STACK_GET', user_stack_get)
 bpf_text = bpf_text.replace('KERNEL_STACK_GET', kernel_stack_get)
+if args.ebpf:
+    print(bpf_text)
+    exit()
 
 # initialize BPF
 b = BPF(text=bpf_text)
diff --git a/tools/opensnoop.py b/tools/opensnoop.py
index 6d011e9..d0dc335 100755
--- a/tools/opensnoop.py
+++ b/tools/opensnoop.py
@@ -41,6 +41,8 @@
     help="trace this TID only")
 parser.add_argument("-n", "--name",
     help="only print process names containing this name")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 debug = 0
 
@@ -119,8 +121,10 @@
         'if (pid != %s) { return 0; }' % args.pid)
 else:
     bpf_text = bpf_text.replace('FILTER', '')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF
 b = BPF(text=bpf_text)
diff --git a/tools/profile.py b/tools/profile.py
index 687a162..78c85f6 100755
--- a/tools/profile.py
+++ b/tools/profile.py
@@ -97,6 +97,8 @@
 parser.add_argument("duration", nargs="?", default=99999999,
     type=positive_nonzero_int,
     help="duration of trace, in seconds")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 
 # option logic
 args = parser.parse_args()
@@ -209,8 +211,10 @@
     else:
         print("... Hit Ctrl-C to end.")
 
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF & perf_events
 b = BPF(text=bpf_text)
diff --git a/tools/runqlat.py b/tools/runqlat.py
index 1eb5d9a..636ff97 100755
--- a/tools/runqlat.py
+++ b/tools/runqlat.py
@@ -58,6 +58,8 @@
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 countdown = int(args.count)
 debug = 0
@@ -169,8 +171,10 @@
     bpf_text = bpf_text.replace('STORAGE', 'BPF_HISTOGRAM(dist);')
     bpf_text = bpf_text.replace('STORE',
         'dist.increment(bpf_log2l(delta));')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # load BPF program
 b = BPF(text=bpf_text)
diff --git a/tools/runqlen.py b/tools/runqlen.py
index e8430ca..4217f4d 100755
--- a/tools/runqlen.py
+++ b/tools/runqlen.py
@@ -48,6 +48,8 @@
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 countdown = int(args.count)
 debug = 0
@@ -158,6 +160,7 @@
 }
 """
 
+# code substitutions
 if args.cpus:
     bpf_text = bpf_text.replace('STORAGE',
         'BPF_HISTOGRAM(dist, cpu_key_t);')
@@ -174,9 +177,10 @@
 else:
     bpf_text = bpf_text.replace('RUNNABLE_WEIGHT_FIELD', '')
 
-# code substitutions
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # load BPF program
 b = BPF(text=bpf_text)
diff --git a/tools/slabratetop.py b/tools/slabratetop.py
index aa1a7b4..cdef6fa 100755
--- a/tools/slabratetop.py
+++ b/tools/slabratetop.py
@@ -41,6 +41,8 @@
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 interval = int(args.interval)
 countdown = int(args.count)
@@ -90,8 +92,10 @@
     return 0;
 }
 """
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF
 b = BPF(text=bpf_text)
diff --git a/tools/softirqs.py b/tools/softirqs.py
index 2cd9248..84c3246 100755
--- a/tools/softirqs.py
+++ b/tools/softirqs.py
@@ -38,6 +38,8 @@
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 countdown = int(args.count)
 if args.nanoseconds:
@@ -110,8 +112,10 @@
         'key.vec = valp->vec; ' +
         'u64 zero = 0, *vp = dist.lookup_or_init(&key, &zero); ' +
         '(*vp) += delta;')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # load BPF program
 b = BPF(text=bpf_text)
diff --git a/tools/solisten.py b/tools/solisten.py
index 31f4637..57f27ce 100755
--- a/tools/solisten.py
+++ b/tools/solisten.py
@@ -42,6 +42,8 @@
     help="trace this PID only")
 parser.add_argument("-n", "--netns", default=0, type=int,
     help="trace this Network Namespace only")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 
 
 # BPF Program
@@ -190,6 +192,10 @@
     bpf_text = bpf_text.replace("##FILTER_PID##", pid_filter)
     bpf_text = bpf_text.replace("##FILTER_NETNS##", netns_filter)
 
+    if args.ebpf:
+        print(bpf_text)
+        exit()
+
     # Initialize BPF
     b = BPF(text=bpf_text)
     b["listen_evt"].open_perf_buffer(event_printer(args.show_netns))
diff --git a/tools/sslsniff.py b/tools/sslsniff.py
index a81b4a4..e8e2c13 100755
--- a/tools/sslsniff.py
+++ b/tools/sslsniff.py
@@ -39,6 +39,8 @@
                     help="do not show GnuTLS calls.")
 parser.add_argument('-d', '--debug', dest='debug', action='count', default=0,
                     help='debug mode.')
+parser.add_argument("--ebpf", action="store_true",
+                    help=argparse.SUPPRESS)
 args = parser.parse_args()
 
 
@@ -119,8 +121,10 @@
 else:
     prog = prog.replace('FILTER', '')
 
-if args.debug:
+if args.debug or args.ebpf:
     print(prog)
+    if args.ebpf:
+        exit()
 
 
 b = BPF(text=prog)
diff --git a/tools/statsnoop.py b/tools/statsnoop.py
index f68acdc..6d0a281 100755
--- a/tools/statsnoop.py
+++ b/tools/statsnoop.py
@@ -34,6 +34,8 @@
     help="only show failed stats")
 parser.add_argument("-p", "--pid",
     help="trace this PID only")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 debug = 0
 
@@ -100,8 +102,10 @@
         'if (pid != %s) { return 0; }' % args.pid)
 else:
     bpf_text = bpf_text.replace('FILTER', '')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF
 b = BPF(text=bpf_text)
diff --git a/tools/syscount.py b/tools/syscount.py
index 0e53635..a20d777 100755
--- a/tools/syscount.py
+++ b/tools/syscount.py
@@ -401,6 +401,8 @@
     help="count by process and not by syscall")
 parser.add_argument("-l", "--list", action="store_true",
     help="print list of recognized syscalls and exit")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 
 if args.list:
@@ -488,6 +490,9 @@
     text = "#define LATENCY\n" + text
 if args.process:
     text = "#define BY_PROCESS\n" + text
+if args.ebpf:
+    print(text)
+    exit()
 
 bpf = BPF(text=text)
 
diff --git a/tools/tcpaccept.py b/tools/tcpaccept.py
index 8593837..a9e627d 100755
--- a/tools/tcpaccept.py
+++ b/tools/tcpaccept.py
@@ -36,6 +36,8 @@
     help="include timestamp on output")
 parser.add_argument("-p", "--pid",
     help="trace this PID only")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 debug = 0
 
@@ -123,8 +125,10 @@
         'if (pid != %s) { return 0; }' % args.pid)
 else:
     bpf_text = bpf_text.replace('FILTER', '')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # event data
 TASK_COMM_LEN = 16      # linux/sched.h
diff --git a/tools/tcpconnect.py b/tools/tcpconnect.py
index 6779adf..dbade83 100755
--- a/tools/tcpconnect.py
+++ b/tools/tcpconnect.py
@@ -42,6 +42,8 @@
     help="trace this PID only")
 parser.add_argument("-P", "--port",
     help="comma-separated list of destination ports to trace.")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 debug = 0
 
@@ -162,8 +164,10 @@
 bpf_text = bpf_text.replace('FILTER_PID', '')
 bpf_text = bpf_text.replace('FILTER_PORT', '')
 
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # event data
 TASK_COMM_LEN = 16      # linux/sched.h
diff --git a/tools/tcpconnlat.py b/tools/tcpconnlat.py
index 073c663..5f7404e 100755
--- a/tools/tcpconnlat.py
+++ b/tools/tcpconnlat.py
@@ -53,6 +53,8 @@
     help="minimum duration to trace (ms)")
 parser.add_argument("-v", "--verbose", action="store_true",
     help="print the BPF program for debugging purposes")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 
 if args.duration_ms:
@@ -186,8 +188,10 @@
         'if (pid != %s) { return 0; }' % args.pid)
 else:
     bpf_text = bpf_text.replace('FILTER', '')
-if debug or args.verbose:
+if debug or args.verbose or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF
 b = BPF(text=bpf_text)
diff --git a/tools/tcpretrans.py b/tools/tcpretrans.py
index 50d1f41..b94abbc 100755
--- a/tools/tcpretrans.py
+++ b/tools/tcpretrans.py
@@ -37,6 +37,8 @@
     help="include tail loss probe attempts")
 parser.add_argument("-c", "--count", action="store_true",
     help="count occurred retransmits per flow")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 debug = 0
 
@@ -189,8 +191,10 @@
     bpf_text = bpf_text.replace("IPV4_CORE", "ipv4_events.perf_submit(ctx, &data4, sizeof(data4));")
     bpf_text = bpf_text.replace("IPV6_CORE", "ipv6_events.perf_submit(ctx, &data6, sizeof(data6));")
 
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # event data
 class Data_ipv4(ct.Structure):
diff --git a/tools/tcptop.py b/tools/tcptop.py
index 4b448e8..58bfeab 100755
--- a/tools/tcptop.py
+++ b/tools/tcptop.py
@@ -60,6 +60,8 @@
     help="output interval, in seconds (default 1)")
 parser.add_argument("count", nargs="?", default=-1, type=range_check,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 debug = 0
 
@@ -189,8 +191,10 @@
         'if (pid != %s) { return 0; }' % args.pid)
 else:
     bpf_text = bpf_text.replace('FILTER', '')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 def pid_to_comm(pid):
     try:
diff --git a/tools/tcptracer.py b/tools/tcptracer.py
index bc1c412..7dd760c 100755
--- a/tools/tcptracer.py
+++ b/tools/tcptracer.py
@@ -32,6 +32,8 @@
                     help="trace this Network Namespace only")
 parser.add_argument("-v", "--verbose", action="store_true",
                     help="include Network Namespace in the output")
+parser.add_argument("--ebpf", action="store_true",
+                    help=argparse.SUPPRESS)
 args = parser.parse_args()
 
 bpf_text = """
@@ -622,6 +624,10 @@
 bpf_text = bpf_text.replace('##FILTER_PID##', pid_filter)
 bpf_text = bpf_text.replace('##FILTER_NETNS##', netns_filter)
 
+if args.ebpf:
+    print(bpf_text)
+    exit()
+
 # initialize BPF
 b = BPF(text=bpf_text)
 b.attach_kprobe(event="tcp_v4_connect", fn_name="trace_connect_v4_entry")
diff --git a/tools/trace.py b/tools/trace.py
index 272d0c6..e257fc1 100755
--- a/tools/trace.py
+++ b/tools/trace.py
@@ -660,6 +660,8 @@
                        "as either full path, "
                        "or relative to current working directory, "
                        "or relative to default kernel header search path")
+                parser.add_argument("--ebpf", action="store_true",
+                  help=argparse.SUPPRESS)
                 self.args = parser.parse_args()
                 if self.args.tgid and self.args.pid:
                         parser.error("only one of -p and -L may be specified")
@@ -690,8 +692,10 @@
                         self.program += probe.generate_program(
                                         self.args.include_self)
 
-                if self.args.verbose:
+                if self.args.verbose or self.args.ebpf:
                         print(self.program)
+                        if self.args.ebpf:
+                                exit()
 
         def _attach_probes(self):
                 usdt_contexts = []
diff --git a/tools/ttysnoop.py b/tools/ttysnoop.py
index 1510d7b..d0981a4 100755
--- a/tools/ttysnoop.py
+++ b/tools/ttysnoop.py
@@ -42,6 +42,8 @@
     help="don't clear the screen")
 parser.add_argument("device", default="-1",
     help="path to a tty device (eg, /dev/tty0) or pts number")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 debug = 0
 
@@ -91,8 +93,10 @@
 """
 
 bpf_text = bpf_text.replace('PTS', str(pi.st_ino))
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF
 b = BPF(text=bpf_text)
diff --git a/tools/wakeuptime.py b/tools/wakeuptime.py
index b242f30..67b7a53 100755
--- a/tools/wakeuptime.py
+++ b/tools/wakeuptime.py
@@ -71,6 +71,8 @@
     type=positive_nonzero_int,
     help="the amount of time in microseconds under which we " +
          "store traces (default U64_MAX)")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 folded = args.folded
 duration = int(args.duration)
@@ -155,8 +157,10 @@
 bpf_text = bpf_text.replace('MINBLOCK_US_VALUE', str(args.min_block_time))
 bpf_text = bpf_text.replace('MAXBLOCK_US_VALUE', str(args.max_block_time))
 
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # initialize BPF
 b = BPF(text=bpf_text)
diff --git a/tools/xfsdist.py b/tools/xfsdist.py
index 18d5a8e..f409f90 100755
--- a/tools/xfsdist.py
+++ b/tools/xfsdist.py
@@ -37,6 +37,8 @@
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 pid = args.pid
 countdown = int(args.count)
@@ -126,8 +128,10 @@
     bpf_text = bpf_text.replace('FILTER_PID', 'pid != %s' % pid)
 else:
     bpf_text = bpf_text.replace('FILTER_PID', '0')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # load BPF program
 b = BPF(text=bpf_text)
diff --git a/tools/xfsslower.py b/tools/xfsslower.py
index 3fbc96d..59dc246 100755
--- a/tools/xfsslower.py
+++ b/tools/xfsslower.py
@@ -48,6 +48,8 @@
     help="trace this PID only")
 parser.add_argument("min_ms", nargs="?", default='10',
     help="minimum I/O duration to trace, in ms (default 10)")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 min_ms = int(args.min_ms)
 pid = args.pid
@@ -229,8 +231,10 @@
     bpf_text = bpf_text.replace('FILTER_PID', 'pid != %s' % pid)
 else:
     bpf_text = bpf_text.replace('FILTER_PID', '0')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # kernel->user event data: struct data_t
 DNAME_INLINE_LEN = 32   # linux/dcache.h
diff --git a/tools/zfsdist.py b/tools/zfsdist.py
index 9c6d3e0..5d5645a 100755
--- a/tools/zfsdist.py
+++ b/tools/zfsdist.py
@@ -37,6 +37,8 @@
     help="output interval, in seconds")
 parser.add_argument("count", nargs="?", default=99999999,
     help="number of outputs")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 pid = args.pid
 countdown = int(args.count)
@@ -126,8 +128,10 @@
     bpf_text = bpf_text.replace('FILTER_PID', 'pid != %s' % pid)
 else:
     bpf_text = bpf_text.replace('FILTER_PID', '0')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # load BPF program
 b = BPF(text=bpf_text)
diff --git a/tools/zfsslower.py b/tools/zfsslower.py
index 1e61de7..dbd8575 100755
--- a/tools/zfsslower.py
+++ b/tools/zfsslower.py
@@ -51,6 +51,8 @@
     help="trace this PID only")
 parser.add_argument("min_ms", nargs="?", default='10',
     help="minimum I/O duration to trace, in ms (default 10)")
+parser.add_argument("--ebpf", action="store_true",
+    help=argparse.SUPPRESS)
 args = parser.parse_args()
 min_ms = int(args.min_ms)
 pid = args.pid
@@ -233,8 +235,10 @@
     bpf_text = bpf_text.replace('FILTER_PID', 'pid != %s' % pid)
 else:
     bpf_text = bpf_text.replace('FILTER_PID', '0')
-if debug:
+if debug or args.ebpf:
     print(bpf_text)
+    if args.ebpf:
+        exit()
 
 # kernel->user event data: struct data_t
 DNAME_INLINE_LEN = 32   # linux/dcache.h