Add Perl support for ucalls / uflow / ustat (#1959)
Sort language entries while at it.
diff --git a/tools/lib/ucalls.py b/tools/lib/ucalls.py
index 97d60f2..b2d165c 100755
--- a/tools/lib/ucalls.py
+++ b/tools/lib/ucalls.py
@@ -4,7 +4,7 @@
# ucalls Summarize method calls in high-level languages and/or system calls.
# For Linux, uses BCC, eBPF.
#
-# USAGE: ucalls [-l {java,python,ruby,php}] [-h] [-T TOP] [-L] [-S] [-v] [-m]
+# USAGE: ucalls [-l {java,perl,php,python,ruby}] [-h] [-T TOP] [-L] [-S] [-v] [-m]
# pid [interval]
#
# Copyright 2016 Sasha Goldshtein
@@ -18,7 +18,7 @@
from time import sleep
import os
-languages = ["java", "python", "ruby", "php"]
+languages = ["java", "perl", "php", "python", "ruby"]
examples = """examples:
./ucalls -l java 185 # trace Java calls and print statistics on ^C
@@ -69,6 +69,18 @@
read_method = "bpf_usdt_readarg(4, ctx, &method);"
extra_message = ("If you do not see any results, make sure you ran java"
" with option -XX:+ExtendedDTraceProbes")
+elif language == "perl":
+ entry_probe = "sub__entry"
+ return_probe = "sub__return"
+ read_class = "bpf_usdt_readarg(2, ctx, &clazz);" # filename really
+ read_method = "bpf_usdt_readarg(1, ctx, &method);"
+elif language == "php":
+ entry_probe = "function__entry"
+ return_probe = "function__return"
+ read_class = "bpf_usdt_readarg(4, ctx, &clazz);"
+ read_method = "bpf_usdt_readarg(1, ctx, &method);"
+ extra_message = ("If you do not see any results, make sure the environment"
+ " variable USE_ZEND_DTRACE is set to 1")
elif language == "python":
entry_probe = "function__entry"
return_probe = "function__return"
@@ -80,13 +92,6 @@
return_probe = "method__return"
read_class = "bpf_usdt_readarg(1, ctx, &clazz);"
read_method = "bpf_usdt_readarg(2, ctx, &method);"
-elif language == "php":
- entry_probe = "function__entry"
- return_probe = "function__return"
- read_class = "bpf_usdt_readarg(4, ctx, &clazz);"
- read_method = "bpf_usdt_readarg(1, ctx, &method);"
- extra_message = ("If you do not see any results, make sure the environment"
- " variable USE_ZEND_DTRACE is set to 1")
elif not language or language == "none":
if not args.syscalls:
print("Nothing to do; use -S to trace syscalls.")
diff --git a/tools/lib/ucalls_example.txt b/tools/lib/ucalls_example.txt
index fffc76f..69d401a 100644
--- a/tools/lib/ucalls_example.txt
+++ b/tools/lib/ucalls_example.txt
@@ -2,8 +2,9 @@
ucalls summarizes method calls in various high-level languages, including Java,
-Python, Ruby, PHP, and Linux system calls. It displays statistics on the most
-frequently called methods, as well as the latency (duration) of these methods.
+Perl, PHP, Python, Ruby, and Linux system calls. It displays statistics on the
+most frequently called methods, as well as the latency (duration) of these
+methods.
Through the syscalls support, ucalls can provide basic information on a
process' interaction with the system including syscall counts and latencies.
@@ -60,7 +61,7 @@
USAGE message:
# ./ucalls.py -h
-usage: ucalls.py [-h] [-l {java,python,ruby,php,none}] [-T TOP] [-L] [-S] [-v]
+usage: ucalls.py [-h] [-l {java,perl,php,python,ruby,none}] [-T TOP] [-L] [-S] [-v]
[-m]
pid [interval]
@@ -72,7 +73,7 @@
optional arguments:
-h, --help show this help message and exit
- -l {java,python,ruby,php,none}, --language {java,python,ruby,php,none}
+ -l {java,perl,php,python,ruby,none}, --language {java,perl,php,python,ruby,none}
language to trace (if none, trace syscalls only)
-T TOP, --top TOP number of most frequent/slow calls to print
-L, --latency record method latency from enter to exit (except
diff --git a/tools/lib/uflow.py b/tools/lib/uflow.py
index 025a193..8419c88 100755
--- a/tools/lib/uflow.py
+++ b/tools/lib/uflow.py
@@ -4,7 +4,7 @@
# uflow Trace method execution flow in high-level languages.
# For Linux, uses BCC, eBPF.
#
-# USAGE: uflow [-C CLASS] [-M METHOD] [-v] {java,python,ruby,php} pid
+# USAGE: uflow [-C CLASS] [-M METHOD] [-v] {java,perl,php,python,ruby} pid
#
# Copyright 2016 Sasha Goldshtein
# Licensed under the Apache License, Version 2.0 (the "License")
@@ -18,7 +18,7 @@
import time
import os
-languages = ["java", "python", "ruby", "php"]
+languages = ["java", "perl", "php", "python", "ruby"]
examples = """examples:
./uflow -l java 185 # trace Java method calls in process 185
@@ -127,6 +127,20 @@
enable_probe("method__return", "java_return",
"bpf_usdt_readarg(2, ctx, &clazz);",
"bpf_usdt_readarg(4, ctx, &method);", is_return=True)
+elif language == "perl":
+ enable_probe("sub__entry", "perl_entry",
+ "bpf_usdt_readarg(2, ctx, &clazz);",
+ "bpf_usdt_readarg(1, ctx, &method);", is_return=False)
+ enable_probe("sub__return", "perl_return",
+ "bpf_usdt_readarg(2, ctx, &clazz);",
+ "bpf_usdt_readarg(1, ctx, &method);", is_return=True)
+elif language == "php":
+ enable_probe("function__entry", "php_entry",
+ "bpf_usdt_readarg(4, ctx, &clazz);",
+ "bpf_usdt_readarg(1, ctx, &method);", is_return=False)
+ enable_probe("function__return", "php_return",
+ "bpf_usdt_readarg(4, ctx, &clazz);",
+ "bpf_usdt_readarg(1, ctx, &method);", is_return=True)
elif language == "python":
enable_probe("function__entry", "python_entry",
"bpf_usdt_readarg(1, ctx, &clazz);", # filename really
@@ -147,13 +161,6 @@
enable_probe("cmethod__return", "ruby_creturn",
"bpf_usdt_readarg(1, ctx, &clazz);",
"bpf_usdt_readarg(2, ctx, &method);", is_return=True)
-elif language == "php":
- enable_probe("function__entry", "php_entry",
- "bpf_usdt_readarg(4, ctx, &clazz);",
- "bpf_usdt_readarg(1, ctx, &method);", is_return=False)
- enable_probe("function__return", "php_return",
- "bpf_usdt_readarg(4, ctx, &clazz);",
- "bpf_usdt_readarg(1, ctx, &method);", is_return=True)
else:
print("No language detected; use -l to trace a language.")
exit(1)
diff --git a/tools/lib/uflow_example.txt b/tools/lib/uflow_example.txt
index 557d972..fae52f3 100644
--- a/tools/lib/uflow_example.txt
+++ b/tools/lib/uflow_example.txt
@@ -4,8 +4,8 @@
uflow traces method entry and exit events and prints a visual flow graph that
shows how methods are entered and exited, similar to a tracing debugger with
breakpoints. This can be useful for understanding program flow in high-level
-languages such as Java, Python, Ruby, and PHP, which provide USDT probes for
-method invocations.
+languages such as Java, Perl, PHP, Python, and Ruby, which provide USDT
+probes for method invocations.
For example, trace all Ruby method calls in a specific process:
@@ -88,7 +88,7 @@
USAGE message:
# ./uflow -h
-usage: uflow.py [-h] [-l {java,python,ruby,php}] [-M METHOD] [-C CLAZZ] [-v]
+usage: uflow.py [-h] [-l {java,perl,php,python,ruby}] [-M METHOD] [-C CLAZZ] [-v]
pid
Trace method execution flow in high-level languages.
@@ -98,7 +98,7 @@
optional arguments:
-h, --help show this help message and exit
- -l {java,python,ruby,php}, --language {java,python,ruby,php}
+ -l {java,perl,php,python,ruby}, --language {java,perl,php,python,ruby}
language to trace
-M METHOD, --method METHOD
trace only calls to methods starting with this prefix
diff --git a/tools/lib/ustat.py b/tools/lib/ustat.py
index 34cc019..8b2f80f 100755
--- a/tools/lib/ustat.py
+++ b/tools/lib/ustat.py
@@ -5,7 +5,7 @@
# method calls, class loads, garbage collections, and more.
# For Linux, uses BCC, eBPF.
#
-# USAGE: ustat [-l {java,python,ruby,node,php}] [-C]
+# USAGE: ustat [-l {java,node,perl,php,python,ruby}] [-C]
# [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d]
# [interval [count]]
#
@@ -132,7 +132,7 @@
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=examples)
parser.add_argument("-l", "--language",
- choices=["java", "python", "ruby", "node", "php"],
+ choices=["java", "node", "perl", "php", "python", "ruby"],
help="language to trace (default: all languages)")
parser.add_argument("-C", "--noclear", action="store_true",
help="don't clear the screen")
@@ -151,18 +151,30 @@
def _create_probes(self):
probes_by_lang = {
+ "java": Probe("java", ["java"], {
+ "gc__begin": Category.GC,
+ "mem__pool__gc__begin": Category.GC,
+ "thread__start": Category.THREAD,
+ "class__loaded": Category.CLOAD,
+ "object__alloc": Category.OBJNEW,
+ "method__entry": Category.METHOD,
+ "ExceptionOccurred__entry": Category.EXCP
+ }),
"node": Probe("node", ["node"], {
"gc__start": Category.GC
}),
- "python": Probe("python", ["python"], {
- "function__entry": Category.METHOD,
- "gc__start": Category.GC
+ "perl": Probe("perl", ["perl"], {
+ "sub__entry": Category.METHOD
}),
"php": Probe("php", ["php"], {
"function__entry": Category.METHOD,
"compile__file__entry": Category.CLOAD,
"exception__thrown": Category.EXCP
}),
+ "python": Probe("python", ["python"], {
+ "function__entry": Category.METHOD,
+ "gc__start": Category.GC
+ }),
"ruby": Probe("ruby", ["ruby", "irb"], {
"method__entry": Category.METHOD,
"cmethod__entry": Category.METHOD,
@@ -176,15 +188,6 @@
"load__entry": Category.CLOAD,
"raise": Category.EXCP
}),
- "java": Probe("java", ["java"], {
- "gc__begin": Category.GC,
- "mem__pool__gc__begin": Category.GC,
- "thread__start": Category.THREAD,
- "class__loaded": Category.CLOAD,
- "object__alloc": Category.OBJNEW,
- "method__entry": Category.METHOD,
- "ExceptionOccurred__entry": Category.EXCP
- })
}
if self.args.language:
diff --git a/tools/lib/ustat_example.txt b/tools/lib/ustat_example.txt
index 79f67fd..8a9ee87 100644
--- a/tools/lib/ustat_example.txt
+++ b/tools/lib/ustat_example.txt
@@ -4,7 +4,7 @@
ustat is a "top"-like tool for monitoring events in high-level languages. It
prints statistics about garbage collections, method calls, object allocations,
and various other events for every process that it recognizes with a Java,
-Python, Ruby, Node, or PHP runtime.
+Node, Perl, PHP, Python, and Ruby runtime.
For example:
@@ -48,7 +48,7 @@
USAGE message:
# ./ustat.py -h
-usage: ustat.py [-h] [-l {java,python,ruby,node,php}] [-C]
+usage: ustat.py [-h] [-l {java,node,perl,php,python,ruby}] [-C]
[-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d]
[interval] [count]
@@ -60,7 +60,7 @@
optional arguments:
-h, --help show this help message and exit
- -l {java,python,ruby,node,php}, --language {java,python,ruby,node,php}
+ -l {{java,node,perl,php,python,ruby}}, --language {java,node,perl,php,python,ruby}
language to trace (default: all languages)
-C, --noclear don't clear the screen
-S {cload,excp,gc,method,objnew,thread}, --sort {cload,excp,gc,method,objnew,thread}
diff --git a/tools/perlcalls.sh b/tools/perlcalls.sh
new file mode 100755
index 0000000..74c6b03
--- /dev/null
+++ b/tools/perlcalls.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ucalls.py -l perl "$@"
diff --git a/tools/perlcalls_example.txt b/tools/perlcalls_example.txt
new file mode 120000
index 0000000..22b0fb3
--- /dev/null
+++ b/tools/perlcalls_example.txt
@@ -0,0 +1 @@
+lib/ucalls_example.txt
\ No newline at end of file
diff --git a/tools/perlflow.sh b/tools/perlflow.sh
new file mode 100755
index 0000000..4fd2397
--- /dev/null
+++ b/tools/perlflow.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/uflow.py -l perl "$@"
diff --git a/tools/perlflow_example.txt b/tools/perlflow_example.txt
new file mode 120000
index 0000000..bc71efc
--- /dev/null
+++ b/tools/perlflow_example.txt
@@ -0,0 +1 @@
+lib/uflow_example.txt
\ No newline at end of file
diff --git a/tools/perlstat.sh b/tools/perlstat.sh
new file mode 100755
index 0000000..4bb417f
--- /dev/null
+++ b/tools/perlstat.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ustat.py -l perl "$@"
diff --git a/tools/perlstat_example.txt b/tools/perlstat_example.txt
new file mode 120000
index 0000000..544e5ad
--- /dev/null
+++ b/tools/perlstat_example.txt
@@ -0,0 +1 @@
+lib/ustat_example.txt
\ No newline at end of file