u* tools: per-language wrappers (#1086)
diff --git a/README.md b/README.md
index 499802c..1af2ae9 100644
--- a/README.md
+++ b/README.md
@@ -137,12 +137,12 @@
- tools/[tplist](tools/tplist.py): Display kernel tracepoints or USDT probes and their formats. [Examples](tools/tplist_example.txt).
- tools/[trace](tools/trace.py): Trace arbitrary functions, with filters. [Examples](tools/trace_example.txt).
- tools/[ttysnoop](tools/ttysnoop.py): Watch live output from a tty or pts device. [Examples](tools/ttysnoop_example.txt).
-- tools/[ucalls](tools/ucalls.py): Summarize method calls or Linux syscalls in high-level languages. [Examples](tools/ucalls_example.txt).
-- tools/[uflow](tools/uflow.py): Print a method flow graph in high-level languages. [Examples](tools/uflow_example.txt).
-- tools/[ugc](tools/ugc.py): Trace garbage collection events in high-level languages. [Examples](tools/ugc_example.txt).
-- tools/[uobjnew](tools/uobjnew.py): Summarize object allocation events by object type and number of bytes allocated. [Examples](tools/uobjnew_example.txt).
-- tools/[ustat](tools/ustat.py): Collect events such as GCs, thread creations, object allocations, exceptions and more in high-level languages. [Examples](tools/ustat_example.txt).
-- tools/[uthreads](tools/uthreads.py): Trace thread creation events in Java and raw pthreads. [Examples](tools/uthreads_example.txt).
+- tools/[ucalls](tools/lib/ucalls.py): Summarize method calls or Linux syscalls in high-level languages. [Examples](tools/lib/ucalls_example.txt).
+- tools/[uflow](tools/lib/uflow.py): Print a method flow graph in high-level languages. [Examples](tools/lib/uflow_example.txt).
+- tools/[ugc](tools/lib/ugc.py): Trace garbage collection events in high-level languages. [Examples](tools/lib/ugc_example.txt).
+- tools/[uobjnew](tools/lib/uobjnew.py): Summarize object allocation events by object type and number of bytes allocated. [Examples](tools/lib/uobjnew_example.txt).
+- tools/[ustat](tools/lib/ustat.py): Collect events such as GCs, thread creations, object allocations, exceptions and more in high-level languages. [Examples](tools/lib/ustat_example.txt).
+- tools/[uthreads](tools/lib/uthreads.py): Trace thread creation events in Java and raw pthreads. [Examples](tools/lib/uthreads_example.txt).
- tools/[vfscount](tools/vfscount.py) tools/[vfscount.c](tools/vfscount.c): Count VFS calls. [Examples](tools/vfscount_example.txt).
- tools/[vfsstat](tools/vfsstat.py) tools/[vfsstat.c](tools/vfsstat.c): Count some VFS calls, with column output. [Examples](tools/vfsstat_example.txt).
- tools/[wakeuptime](tools/wakeuptime.py): Summarize sleep to wakeup time by waker kernel stack. [Examples](tools/wakeuptime_example.txt).
diff --git a/man/man8/cobjnew.8 b/man/man8/cobjnew.8
new file mode 120000
index 0000000..b384265
--- /dev/null
+++ b/man/man8/cobjnew.8
@@ -0,0 +1 @@
+uobjnew.8
\ No newline at end of file
diff --git a/man/man8/javacalls.8 b/man/man8/javacalls.8
new file mode 120000
index 0000000..a9a6054
--- /dev/null
+++ b/man/man8/javacalls.8
@@ -0,0 +1 @@
+ucalls.8
\ No newline at end of file
diff --git a/man/man8/javaflow.8 b/man/man8/javaflow.8
new file mode 120000
index 0000000..84ccb94
--- /dev/null
+++ b/man/man8/javaflow.8
@@ -0,0 +1 @@
+uflow.8
\ No newline at end of file
diff --git a/man/man8/javagc.8 b/man/man8/javagc.8
new file mode 120000
index 0000000..219d8a3
--- /dev/null
+++ b/man/man8/javagc.8
@@ -0,0 +1 @@
+ugc.8
\ No newline at end of file
diff --git a/man/man8/javaobjnew.8 b/man/man8/javaobjnew.8
new file mode 120000
index 0000000..b384265
--- /dev/null
+++ b/man/man8/javaobjnew.8
@@ -0,0 +1 @@
+uobjnew.8
\ No newline at end of file
diff --git a/man/man8/javastat.8 b/man/man8/javastat.8
new file mode 120000
index 0000000..e3a3a29
--- /dev/null
+++ b/man/man8/javastat.8
@@ -0,0 +1 @@
+ustat.8
\ No newline at end of file
diff --git a/man/man8/javathreads.8 b/man/man8/javathreads.8
new file mode 120000
index 0000000..baf8205
--- /dev/null
+++ b/man/man8/javathreads.8
@@ -0,0 +1 @@
+uthreads.8
\ No newline at end of file
diff --git a/man/man8/nodegc.8 b/man/man8/nodegc.8
new file mode 120000
index 0000000..219d8a3
--- /dev/null
+++ b/man/man8/nodegc.8
@@ -0,0 +1 @@
+ugc.8
\ No newline at end of file
diff --git a/man/man8/nodestat.8 b/man/man8/nodestat.8
new file mode 120000
index 0000000..e3a3a29
--- /dev/null
+++ b/man/man8/nodestat.8
@@ -0,0 +1 @@
+ustat.8
\ No newline at end of file
diff --git a/man/man8/phpcalls.8 b/man/man8/phpcalls.8
new file mode 120000
index 0000000..a9a6054
--- /dev/null
+++ b/man/man8/phpcalls.8
@@ -0,0 +1 @@
+ucalls.8
\ No newline at end of file
diff --git a/man/man8/phpflow.8 b/man/man8/phpflow.8
new file mode 120000
index 0000000..84ccb94
--- /dev/null
+++ b/man/man8/phpflow.8
@@ -0,0 +1 @@
+uflow.8
\ No newline at end of file
diff --git a/man/man8/phpstat.8 b/man/man8/phpstat.8
new file mode 120000
index 0000000..e3a3a29
--- /dev/null
+++ b/man/man8/phpstat.8
@@ -0,0 +1 @@
+ustat.8
\ No newline at end of file
diff --git a/man/man8/pythoncalls.8 b/man/man8/pythoncalls.8
new file mode 120000
index 0000000..a9a6054
--- /dev/null
+++ b/man/man8/pythoncalls.8
@@ -0,0 +1 @@
+ucalls.8
\ No newline at end of file
diff --git a/man/man8/pythonflow.8 b/man/man8/pythonflow.8
new file mode 120000
index 0000000..84ccb94
--- /dev/null
+++ b/man/man8/pythonflow.8
@@ -0,0 +1 @@
+uflow.8
\ No newline at end of file
diff --git a/man/man8/pythongc.8 b/man/man8/pythongc.8
new file mode 120000
index 0000000..219d8a3
--- /dev/null
+++ b/man/man8/pythongc.8
@@ -0,0 +1 @@
+ugc.8
\ No newline at end of file
diff --git a/man/man8/pythonstat.8 b/man/man8/pythonstat.8
new file mode 120000
index 0000000..e3a3a29
--- /dev/null
+++ b/man/man8/pythonstat.8
@@ -0,0 +1 @@
+ustat.8
\ No newline at end of file
diff --git a/man/man8/rubycalls.8 b/man/man8/rubycalls.8
new file mode 120000
index 0000000..a9a6054
--- /dev/null
+++ b/man/man8/rubycalls.8
@@ -0,0 +1 @@
+ucalls.8
\ No newline at end of file
diff --git a/man/man8/rubyflow.8 b/man/man8/rubyflow.8
new file mode 120000
index 0000000..84ccb94
--- /dev/null
+++ b/man/man8/rubyflow.8
@@ -0,0 +1 @@
+uflow.8
\ No newline at end of file
diff --git a/man/man8/rubygc.8 b/man/man8/rubygc.8
new file mode 120000
index 0000000..219d8a3
--- /dev/null
+++ b/man/man8/rubygc.8
@@ -0,0 +1 @@
+ugc.8
\ No newline at end of file
diff --git a/man/man8/rubyobjnew.8 b/man/man8/rubyobjnew.8
new file mode 120000
index 0000000..b384265
--- /dev/null
+++ b/man/man8/rubyobjnew.8
@@ -0,0 +1 @@
+uobjnew.8
\ No newline at end of file
diff --git a/man/man8/rubystat.8 b/man/man8/rubystat.8
new file mode 120000
index 0000000..e3a3a29
--- /dev/null
+++ b/man/man8/rubystat.8
@@ -0,0 +1 @@
+ustat.8
\ No newline at end of file
diff --git a/man/man8/ucalls.8 b/man/man8/ucalls.8
index 0fc340f..3917af5 100644
--- a/man/man8/ucalls.8
+++ b/man/man8/ucalls.8
@@ -1,7 +1,16 @@
.TH ucalls 8 "2016-11-07" "USER COMMANDS"
.SH NAME
-ucalls \- Summarize method calls from high-level languages and Linux syscalls.
+ucalls, javacalls, pythoncalls, rubycalls, phpcalls \- Summarize method calls
+from high-level languages and Linux syscalls.
.SH SYNOPSIS
+.B javacalls [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
+.br
+.B pythoncalls [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
+.br
+.B rubycalls [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
+.br
+.B phpcalls [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
+.br
.B ucalls [-l {java,python,ruby,php}] [-h] [-T TOP] [-L] [-S] [-v] [-m] pid [interval]
.SH DESCRIPTION
This tool summarizes method calls from high-level languages such as Python,
diff --git a/man/man8/uflow.8 b/man/man8/uflow.8
index 4b24208..63b7c75 100644
--- a/man/man8/uflow.8
+++ b/man/man8/uflow.8
@@ -1,8 +1,17 @@
.TH uflow 8 "2016-11-07" "USER COMMANDS"
.SH NAME
-uflow \- Print a flow graph of method calls in high-level languages.
+uflow, javaflow, pythonflow, rubyflow, phpflow \- Print a flow graph of method
+calls in high-level languages.
.SH SYNOPSIS
-.B uflow [-h] [-M METHOD] [-C CLAZZ] [-v] {java,python,ruby,php} pid
+.B javaflow [-h] [-M METHOD] [-C CLAZZ] [-v] pid
+.br
+.B pythonflow [-h] [-M METHOD] [-C CLAZZ] [-v] pid
+.br
+.B rubyflow [-h] [-M METHOD] [-C CLAZZ] [-v] pid
+.br
+.B phpflow [-h] [-M METHOD] [-C CLAZZ] [-v] pid
+.br
+.B uflow [-h] [-M METHOD] [-C CLAZZ] [-v] [-l {java,python,ruby,php}] pid
.SH DESCRIPTION
uflow traces method calls and prints them in a flow graph that can facilitate
debugging and diagnostics by following the program's execution (method flow).
diff --git a/man/man8/ugc.8 b/man/man8/ugc.8
index 56a45f4..a4a7448 100644
--- a/man/man8/ugc.8
+++ b/man/man8/ugc.8
@@ -1,8 +1,17 @@
.TH ugc 8 "2016-11-07" "USER COMMANDS"
.SH NAME
-ugc \- Trace garbage collection events in high-level languages.
+ugc, javagc, pythongc, rubygc, nodegc \- Trace garbage collection events in
+high-level languages.
.SH SYNOPSIS
-.B ugc [-h] [-v] [-m] [-M MINIMUM] [-F FILTER] {java,python,ruby,node} pid
+.B javagc [-h] [-v] [-m] [-M MINIMUM] [-F FILTER] pid
+.br
+.B pythongc [-h] [-v] [-m] [-M MINIMUM] [-F FILTER] pid
+.br
+.B rubygc [-h] [-v] [-m] [-M MINIMUM] [-F FILTER] pid
+.br
+.B nodegc [-h] [-v] [-m] [-M MINIMUM] [-F FILTER] pid
+.br
+.B ugc [-h] [-v] [-m] [-M MINIMUM] [-F FILTER] [-l {java,python,ruby,node}] pid
.SH DESCRIPTION
This traces garbage collection events as they occur, including their duration
and any additional information (such as generation collected or type of GC)
diff --git a/man/man8/uobjnew.8 b/man/man8/uobjnew.8
index 1abaec4..dcb459a 100644
--- a/man/man8/uobjnew.8
+++ b/man/man8/uobjnew.8
@@ -1,8 +1,15 @@
.TH uobjnew 8 "2016-11-07" "USER COMMANDS"
.SH NAME
-uobjnew \- Summarize object allocations in high-level languages.
+uobjnew, javaobjnew, rubyobjnew, cobjnew \- Summarize object allocations in
+high-level languages.
.SH SYNOPSIS
-.B uobjnew [-h] [-C TOP_COUNT] [-S TOP_SIZE] [-v] {java,ruby,c} pid [interval]
+.B javaobjnew [-h] [-C TOP_COUNT] [-S TOP_SIZE] [-v] pid [interval]
+.br
+.B rubyobjnew [-h] [-C TOP_COUNT] [-S TOP_SIZE] [-v] pid [interval]
+.br
+.B cobjnew [-h] [-C TOP_COUNT] [-S TOP_SIZE] [-v] pid [interval]
+.br
+.B uobjnew [-h] [-C TOP_COUNT] [-S TOP_SIZE] [-v] [-l {java,ruby,c}] pid [interval]
.SH DESCRIPTION
uobjnew traces object allocations in high-level languages (including "malloc")
and prints summaries of the most frequently allocated types by number of
diff --git a/man/man8/ustat.8 b/man/man8/ustat.8
index f906a25..8eb231e 100644
--- a/man/man8/ustat.8
+++ b/man/man8/ustat.8
@@ -1,7 +1,18 @@
.TH ustat 8 "2016-11-07" "USER COMMANDS"
.SH NAME
-ustat \- Activity stats from high-level languages.
+ustat, javastat, pythonstat, rubystat, nodestat, phpstat \- Activity stats from
+high-level languages.
.SH SYNOPSIS
+.B javastat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
+.br
+.B pythonstat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
+.br
+.B rubystat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
+.br
+.B nodestat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
+.br
+.B phpstat [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
+.br
.B ustat [-l {java,python,ruby,node,php}] [-C] [-S {cload,excp,gc,method,objnew,thread}] [-r MAXROWS] [-d] [interval [count]]
.SH DESCRIPTION
This is "top" for high-level language events, such as garbage collections,
diff --git a/man/man8/uthreads.8 b/man/man8/uthreads.8
index 8d4d2bb..76f0602 100644
--- a/man/man8/uthreads.8
+++ b/man/man8/uthreads.8
@@ -1,7 +1,9 @@
.TH uthreads 8 "2016-11-07" "USER COMMANDS"
.SH NAME
-uthreads \- Trace thread creation events in Java or pthreads.
+uthreads, javathreads \- Trace thread creation events in Java or pthreads.
.SH SYNOPSIS
+.B javathreads [-h] [-v] pid
+.BR
.B uthreads [-h] [-l {java}] [-v] pid
.SH DESCRIPTION
This traces thread creation events in Java processes, or pthread creation
diff --git a/snapcraft/snapcraft.yaml b/snapcraft/snapcraft.yaml
index 9f4c4fb..c674ff6 100644
--- a/snapcraft/snapcraft.yaml
+++ b/snapcraft/snapcraft.yaml
@@ -16,7 +16,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
name: bcc
-version: 0.3.0-20170322-1719-aaab74e
+version: 0.3.0-20170401-1747-c5f48c9
summary: BPF Compiler Collection (BCC)
description: A toolkit for creating efficient kernel tracing and manipulation programs
confinement: strict
@@ -149,17 +149,59 @@
ttysnoop:
command: wrapper ttysnoop
ucalls:
- command: wrapper ucalls
+ command: wrapper lib/ucalls
uflow:
- command: wrapper uflow
+ command: wrapper lib/uflow
ugc:
- command: wrapper ugc
+ command: wrapper lib/ugc
uobjnew:
- command: wrapper uobjnew
+ command: wrapper lib/uobjnew
ustat:
- command: wrapper ustat
+ command: wrapper lib/ustat
uthreads:
- command: wrapper uthreads
+ command: wrapper lib/uthreads
+ cobjnew:
+ command: wrapper cobjnew
+ javacalls:
+ command: wrapper javacalls
+ javaflow:
+ command: wrapper javaflow
+ javagc:
+ command: wrapper javagc
+ javaobjnew:
+ command: wrapper javaobjnew
+ javastat:
+ command: wrapper javastat
+ javathreads:
+ command: wrapper javathreads
+ nodegc:
+ command: wrapper nodegc
+ nodestat:
+ command: wrapper nodestat
+ phpcalls:
+ command: wrapper phpcalls
+ phpflow:
+ command: wrapper phpflow
+ phpstat:
+ command: wrapper phpstat
+ pythoncalls:
+ command: wrapper pythoncalls
+ pythonflow:
+ command: wrapper pythonflow
+ pythongc:
+ command: wrapper pythongc
+ pythonstat:
+ command: wrapper pythonstat
+ rubycalls:
+ command: wrapper rubycalls
+ rubyflow:
+ command: wrapper rubyflow
+ rubygc:
+ command: wrapper rubygc
+ rubyobjnew:
+ command: wrapper rubyobjnew
+ rubystat:
+ command: wrapper rubystat
vfscount:
command: wrapper vfscount
vfsstat:
diff --git a/tests/python/test_tools_smoke.py b/tests/python/test_tools_smoke.py
index 885ffca..26e33e7 100755
--- a/tests/python/test_tools_smoke.py
+++ b/tests/python/test_tools_smoke.py
@@ -307,14 +307,14 @@
def test_ucalls(self):
# This attaches a large number (300+) kprobes, which can be slow,
# so use an increased timeout value.
- self.run_with_int("ucalls.py -l none -S %d" % os.getpid(),
+ self.run_with_int("lib/ucalls.py -l none -S %d" % os.getpid(),
timeout=30, kill_timeout=30)
@skipUnless(kernel_version_ge(4,4), "requires kernel >= 4.4")
def test_uflow(self):
# The Python installed on the Ubuntu buildbot doesn't have USDT
# probes, so we can't run uflow.
- # self.run_with_int("uflow.py -l python %d" % os.getpid())
+ # self.run_with_int("pythonflow.py %d" % os.getpid())
pass
@skipUnless(kernel_version_ge(4,4), "requires kernel >= 4.4")
@@ -325,15 +325,15 @@
@skipUnless(kernel_version_ge(4,4), "requires kernel >= 4.4")
def test_uobjnew(self):
- self.run_with_int("uobjnew.py -l c %d" % os.getpid())
+ self.run_with_int("cobjnew.sh %d" % os.getpid())
@skipUnless(kernel_version_ge(4,4), "requires kernel >= 4.4")
def test_ustat(self):
- self.run_with_duration("ustat.py 1 1")
+ self.run_with_duration("lib/ustat.py 1 1")
@skipUnless(kernel_version_ge(4,4), "requires kernel >= 4.4")
def test_uthreads(self):
- self.run_with_int("uthreads.py %d" % os.getpid())
+ self.run_with_int("lib/uthreads.py %d" % os.getpid())
def test_vfscount(self):
self.run_with_int("vfscount.py")
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 64321e5..77f96f7 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -1,11 +1,26 @@
file(GLOB C_FILES *.c)
file(GLOB PY_FILES *.py)
+file(GLOB SH_FILES *.sh)
file(GLOB TXT_FILES *.txt)
-list(REMOVE_ITEM TXT_FILES "CMakeLists.txt")
+list(REMOVE_ITEM TXT_FILES ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
foreach(FIL ${PY_FILES})
get_filename_component(FIL_WE ${FIL} NAME_WE)
install(PROGRAMS ${FIL} DESTINATION share/bcc/tools RENAME ${FIL_WE})
endforeach()
+foreach(FIL ${SH_FILES})
+ if(${FIL} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}/reset-trace.sh)
+ get_filename_component(FIL_WE ${FIL} NAME_WE)
+ install(PROGRAMS ${FIL} DESTINATION share/bcc/tools RENAME ${FIL_WE})
+ else()
+ file(READ ${FIL} CONTENT)
+ string(REPLACE ".py -l" " -l" CONTENT_WE ${CONTENT})
+ string(REPLACE "\"" "\\\"" CONTENT_WE ${CONTENT_WE})
+ get_filename_component(FIL_WE ${FIL} NAME_WE)
+ install(PROGRAMS ${FIL} DESTINATION share/bcc/tools RENAME ${FIL_WE})
+ install(CODE "file(WRITE \"\$ENV{DESTDIR}/\${CMAKE_INSTALL_PREFIX}/share/bcc/tools/${FIL_WE}\" \"${CONTENT_WE}\")")
+ endif()
+endforeach()
install(FILES ${C_FILES} DESTINATION share/bcc/tools)
install(FILES ${TXT_FILES} DESTINATION share/bcc/tools/doc)
+add_subdirectory(lib)
add_subdirectory(old)
diff --git a/tools/cobjnew.sh b/tools/cobjnew.sh
new file mode 100755
index 0000000..8bcdad3
--- /dev/null
+++ b/tools/cobjnew.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/uobjnew.py -l c "$@"
diff --git a/tools/cobjnew_example.txt b/tools/cobjnew_example.txt
new file mode 120000
index 0000000..a8a83c3
--- /dev/null
+++ b/tools/cobjnew_example.txt
@@ -0,0 +1 @@
+lib/uobjnew_example.txt
\ No newline at end of file
diff --git a/tools/javacalls.sh b/tools/javacalls.sh
new file mode 100755
index 0000000..701510b
--- /dev/null
+++ b/tools/javacalls.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ucalls.py -l java "$@"
diff --git a/tools/javacalls_example.txt b/tools/javacalls_example.txt
new file mode 120000
index 0000000..22b0fb3
--- /dev/null
+++ b/tools/javacalls_example.txt
@@ -0,0 +1 @@
+lib/ucalls_example.txt
\ No newline at end of file
diff --git a/tools/javaflow.sh b/tools/javaflow.sh
new file mode 100755
index 0000000..e39d153
--- /dev/null
+++ b/tools/javaflow.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/uflow.py -l java "$@"
diff --git a/tools/javaflow_example.txt b/tools/javaflow_example.txt
new file mode 120000
index 0000000..bc71efc
--- /dev/null
+++ b/tools/javaflow_example.txt
@@ -0,0 +1 @@
+lib/uflow_example.txt
\ No newline at end of file
diff --git a/tools/javagc.sh b/tools/javagc.sh
new file mode 100755
index 0000000..ad59188
--- /dev/null
+++ b/tools/javagc.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ugc.py -l java "$@"
diff --git a/tools/javagc_example.txt b/tools/javagc_example.txt
new file mode 120000
index 0000000..303ccbd
--- /dev/null
+++ b/tools/javagc_example.txt
@@ -0,0 +1 @@
+lib/ugc_example.txt
\ No newline at end of file
diff --git a/tools/javaobjnew.sh b/tools/javaobjnew.sh
new file mode 100755
index 0000000..e3f069b
--- /dev/null
+++ b/tools/javaobjnew.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/uobjnew.py -l java "$@"
diff --git a/tools/javaobjnew_example.txt b/tools/javaobjnew_example.txt
new file mode 120000
index 0000000..a8a83c3
--- /dev/null
+++ b/tools/javaobjnew_example.txt
@@ -0,0 +1 @@
+lib/uobjnew_example.txt
\ No newline at end of file
diff --git a/tools/javastat.sh b/tools/javastat.sh
new file mode 100755
index 0000000..f758dca
--- /dev/null
+++ b/tools/javastat.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ustat.py -l java "$@"
diff --git a/tools/javastat_example.txt b/tools/javastat_example.txt
new file mode 120000
index 0000000..544e5ad
--- /dev/null
+++ b/tools/javastat_example.txt
@@ -0,0 +1 @@
+lib/ustat_example.txt
\ No newline at end of file
diff --git a/tools/javathreads.sh b/tools/javathreads.sh
new file mode 100755
index 0000000..442d2c9
--- /dev/null
+++ b/tools/javathreads.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/uthreads.py -l java "$@"
diff --git a/tools/javathreads_example.txt b/tools/javathreads_example.txt
new file mode 120000
index 0000000..4e678a8
--- /dev/null
+++ b/tools/javathreads_example.txt
@@ -0,0 +1 @@
+lib/uthreads_example.txt
\ No newline at end of file
diff --git a/tools/lib/CMakeLists.txt b/tools/lib/CMakeLists.txt
new file mode 100644
index 0000000..3ed2730
--- /dev/null
+++ b/tools/lib/CMakeLists.txt
@@ -0,0 +1,8 @@
+file(GLOB PY_FILES *.py)
+file(GLOB TXT_FILES *.txt)
+list(REMOVE_ITEM TXT_FILES ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
+foreach(FIL ${PY_FILES})
+ get_filename_component(FIL_WE ${FIL} NAME_WE)
+ install(PROGRAMS ${FIL} DESTINATION share/bcc/tools/lib RENAME ${FIL_WE})
+endforeach()
+install(FILES ${TXT_FILES} DESTINATION share/bcc/tools/doc/lib)
diff --git a/tools/ucalls.py b/tools/lib/ucalls.py
similarity index 100%
rename from tools/ucalls.py
rename to tools/lib/ucalls.py
diff --git a/tools/ucalls_example.txt b/tools/lib/ucalls_example.txt
similarity index 100%
rename from tools/ucalls_example.txt
rename to tools/lib/ucalls_example.txt
diff --git a/tools/uflow.py b/tools/lib/uflow.py
similarity index 100%
rename from tools/uflow.py
rename to tools/lib/uflow.py
diff --git a/tools/uflow_example.txt b/tools/lib/uflow_example.txt
similarity index 100%
rename from tools/uflow_example.txt
rename to tools/lib/uflow_example.txt
diff --git a/tools/ugc.py b/tools/lib/ugc.py
similarity index 100%
rename from tools/ugc.py
rename to tools/lib/ugc.py
diff --git a/tools/ugc_example.txt b/tools/lib/ugc_example.txt
similarity index 100%
rename from tools/ugc_example.txt
rename to tools/lib/ugc_example.txt
diff --git a/tools/uobjnew.py b/tools/lib/uobjnew.py
similarity index 100%
rename from tools/uobjnew.py
rename to tools/lib/uobjnew.py
diff --git a/tools/uobjnew_example.txt b/tools/lib/uobjnew_example.txt
similarity index 100%
rename from tools/uobjnew_example.txt
rename to tools/lib/uobjnew_example.txt
diff --git a/tools/ustat.py b/tools/lib/ustat.py
similarity index 100%
rename from tools/ustat.py
rename to tools/lib/ustat.py
diff --git a/tools/ustat_example.txt b/tools/lib/ustat_example.txt
similarity index 100%
rename from tools/ustat_example.txt
rename to tools/lib/ustat_example.txt
diff --git a/tools/uthreads.py b/tools/lib/uthreads.py
similarity index 100%
rename from tools/uthreads.py
rename to tools/lib/uthreads.py
diff --git a/tools/uthreads_example.txt b/tools/lib/uthreads_example.txt
similarity index 100%
rename from tools/uthreads_example.txt
rename to tools/lib/uthreads_example.txt
diff --git a/tools/nodegc.sh b/tools/nodegc.sh
new file mode 100755
index 0000000..5453c2a
--- /dev/null
+++ b/tools/nodegc.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ugc.py -l node "$@"
diff --git a/tools/nodegc_example.txt b/tools/nodegc_example.txt
new file mode 120000
index 0000000..303ccbd
--- /dev/null
+++ b/tools/nodegc_example.txt
@@ -0,0 +1 @@
+lib/ugc_example.txt
\ No newline at end of file
diff --git a/tools/nodestat.sh b/tools/nodestat.sh
new file mode 100755
index 0000000..8a468f5
--- /dev/null
+++ b/tools/nodestat.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ustat.py -l node "$@"
diff --git a/tools/nodestat_example.txt b/tools/nodestat_example.txt
new file mode 120000
index 0000000..544e5ad
--- /dev/null
+++ b/tools/nodestat_example.txt
@@ -0,0 +1 @@
+lib/ustat_example.txt
\ No newline at end of file
diff --git a/tools/phpcalls.sh b/tools/phpcalls.sh
new file mode 100755
index 0000000..726ffcf
--- /dev/null
+++ b/tools/phpcalls.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ucalls.py -l php "$@"
diff --git a/tools/phpcalls_example.txt b/tools/phpcalls_example.txt
new file mode 120000
index 0000000..22b0fb3
--- /dev/null
+++ b/tools/phpcalls_example.txt
@@ -0,0 +1 @@
+lib/ucalls_example.txt
\ No newline at end of file
diff --git a/tools/phpflow.sh b/tools/phpflow.sh
new file mode 100755
index 0000000..5eb83f3
--- /dev/null
+++ b/tools/phpflow.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/uflow.py -l php "$@"
diff --git a/tools/phpflow_example.txt b/tools/phpflow_example.txt
new file mode 120000
index 0000000..bc71efc
--- /dev/null
+++ b/tools/phpflow_example.txt
@@ -0,0 +1 @@
+lib/uflow_example.txt
\ No newline at end of file
diff --git a/tools/phpstat.sh b/tools/phpstat.sh
new file mode 100755
index 0000000..455b308
--- /dev/null
+++ b/tools/phpstat.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ustat.py -l php "$@"
diff --git a/tools/phpstat_example.txt b/tools/phpstat_example.txt
new file mode 120000
index 0000000..544e5ad
--- /dev/null
+++ b/tools/phpstat_example.txt
@@ -0,0 +1 @@
+lib/ustat_example.txt
\ No newline at end of file
diff --git a/tools/pythoncalls.sh b/tools/pythoncalls.sh
new file mode 100755
index 0000000..e5fd65d
--- /dev/null
+++ b/tools/pythoncalls.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ucalls.py -l python "$@"
diff --git a/tools/pythoncalls_example.txt b/tools/pythoncalls_example.txt
new file mode 120000
index 0000000..22b0fb3
--- /dev/null
+++ b/tools/pythoncalls_example.txt
@@ -0,0 +1 @@
+lib/ucalls_example.txt
\ No newline at end of file
diff --git a/tools/pythonflow.sh b/tools/pythonflow.sh
new file mode 100755
index 0000000..a346772
--- /dev/null
+++ b/tools/pythonflow.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/uflow.py -l python "$@"
diff --git a/tools/pythonflow_example.txt b/tools/pythonflow_example.txt
new file mode 120000
index 0000000..bc71efc
--- /dev/null
+++ b/tools/pythonflow_example.txt
@@ -0,0 +1 @@
+lib/uflow_example.txt
\ No newline at end of file
diff --git a/tools/pythongc.sh b/tools/pythongc.sh
new file mode 100755
index 0000000..ca5baf3
--- /dev/null
+++ b/tools/pythongc.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ugc.py -l python "$@"
diff --git a/tools/pythongc_example.txt b/tools/pythongc_example.txt
new file mode 120000
index 0000000..303ccbd
--- /dev/null
+++ b/tools/pythongc_example.txt
@@ -0,0 +1 @@
+lib/ugc_example.txt
\ No newline at end of file
diff --git a/tools/pythonstat.sh b/tools/pythonstat.sh
new file mode 100755
index 0000000..2133207
--- /dev/null
+++ b/tools/pythonstat.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ustat.py -l python "$@"
diff --git a/tools/pythonstat_example.txt b/tools/pythonstat_example.txt
new file mode 120000
index 0000000..544e5ad
--- /dev/null
+++ b/tools/pythonstat_example.txt
@@ -0,0 +1 @@
+lib/ustat_example.txt
\ No newline at end of file
diff --git a/tools/rubycalls.sh b/tools/rubycalls.sh
new file mode 100755
index 0000000..bbea144
--- /dev/null
+++ b/tools/rubycalls.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ucalls.py -l ruby "$@"
diff --git a/tools/rubycalls_example.txt b/tools/rubycalls_example.txt
new file mode 120000
index 0000000..22b0fb3
--- /dev/null
+++ b/tools/rubycalls_example.txt
@@ -0,0 +1 @@
+lib/ucalls_example.txt
\ No newline at end of file
diff --git a/tools/rubyflow.sh b/tools/rubyflow.sh
new file mode 100755
index 0000000..fe1946a
--- /dev/null
+++ b/tools/rubyflow.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/uflow.py -l ruby "$@"
diff --git a/tools/rubyflow_example.txt b/tools/rubyflow_example.txt
new file mode 120000
index 0000000..bc71efc
--- /dev/null
+++ b/tools/rubyflow_example.txt
@@ -0,0 +1 @@
+lib/uflow_example.txt
\ No newline at end of file
diff --git a/tools/rubygc.sh b/tools/rubygc.sh
new file mode 100755
index 0000000..81a29f6
--- /dev/null
+++ b/tools/rubygc.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ugc.py -l ruby "$@"
diff --git a/tools/rubygc_example.txt b/tools/rubygc_example.txt
new file mode 120000
index 0000000..303ccbd
--- /dev/null
+++ b/tools/rubygc_example.txt
@@ -0,0 +1 @@
+lib/ugc_example.txt
\ No newline at end of file
diff --git a/tools/rubyobjnew.sh b/tools/rubyobjnew.sh
new file mode 100755
index 0000000..afeaa3a
--- /dev/null
+++ b/tools/rubyobjnew.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/uobjnew.py -l ruby "$@"
diff --git a/tools/rubyobjnew_example.txt b/tools/rubyobjnew_example.txt
new file mode 120000
index 0000000..a8a83c3
--- /dev/null
+++ b/tools/rubyobjnew_example.txt
@@ -0,0 +1 @@
+lib/uobjnew_example.txt
\ No newline at end of file
diff --git a/tools/rubystat.sh b/tools/rubystat.sh
new file mode 100755
index 0000000..7c777cd
--- /dev/null
+++ b/tools/rubystat.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+lib=$(dirname $0)/lib
+$lib/ustat.py -l ruby "$@"
diff --git a/tools/rubystat_example.txt b/tools/rubystat_example.txt
new file mode 120000
index 0000000..544e5ad
--- /dev/null
+++ b/tools/rubystat_example.txt
@@ -0,0 +1 @@
+lib/ustat_example.txt
\ No newline at end of file