summary refs log tree commit diff
path: root/ripple/tools/driver.pl
diff options
context:
space:
mode:
Diffstat (limited to 'ripple/tools/driver.pl')
-rwxr-xr-xripple/tools/driver.pl69
1 files changed, 69 insertions, 0 deletions
diff --git a/ripple/tools/driver.pl b/ripple/tools/driver.pl
new file mode 100755
index 0000000..7a8d164
--- /dev/null
+++ b/ripple/tools/driver.pl
@@ -0,0 +1,69 @@
+#! /usr/bin/perl
+# SPDX-FileCopyrightText: edef <edef@unfathomable.blue>
+# SPDX-License-Identifier: OSL-3.0
+
+use strict;
+use POSIX qw(mkfifo);
+
+@ARGV or die "Usage: $0 PROGRAM [ARG]... 2> [LOG FILE]";
+die "bpftrace does not support spaces in argv" if grep {/ /} @ARGV;
+
+unlink(my $fifo = "tracepipe");
+mkfifo($fifo, 0600) or die;
+
+my $script = do { local $/; <DATA> };
+defined(my $pid = fork) or die;
+
+if (!$pid) {
+    open(STDERR, ">&", STDOUT) or die;
+    exec(
+        'systemd-run', '--user', '--scope', '--',
+        # NOTE: this expects bpftrace to be SUID-root,
+        # and relies on shells dropping euid
+        'bpftrace', '-o', $fifo, '-e', $script, '-c',
+        join(' ', @ARGV)
+    ) or die;
+}
+
+my %count;
+
+# TODO(edef): if bpftrace fails, the FIFO will never open
+open(TRACE, '<', $fifo) or die;
+while (<TRACE>) {
+    chomp;
+    next if /^Attaching \d+ probes[.][.][.]$/ or /^$/;
+    /^@\[tracepoint:syscalls:sys_enter_(\w+), (.+)\]: (\d+)$/ or die $_;
+    $count{$1}{$2} += $3;
+}
+
+waitpid $pid, 0;
+
+foreach my $comm (sort keys %count) {
+    die "unhandled: $comm" if $comm =~ /\s/;
+    my $comm_count = $count{$comm};
+    foreach my $sys (sort keys %$comm_count) {
+        my $n = $comm_count->{$sys};
+        print STDERR "$comm\t$sys\t$n\n";
+    }
+}
+
+__DATA__
+BEGIN {
+    @cgroup = cgroup;
+    @self = pid;
+}
+
+tracepoint:syscalls:sys_enter_* /cgroup == @cgroup && pid != @self/ {
+    @[probe, comm] = count();
+}
+
+interval:s:1 {
+    print(@);
+    clear(@);
+}
+
+tracepoint:sched:sched_process_exit /tid == cpid/ {
+    clear(@cgroup);
+    clear(@self);
+    exit();
+}