implement upt-trace wrapper
Stefan Schuermans

Stefan Schuermans commited on 2020-05-22 13:32:43
Showing 11 changed files, with 210 additions and 14 deletions.


also add test to trace build, add readme
... ...
@@ -8,4 +8,5 @@ enable_testing()
8 8
 add_subdirectory(dump)
9 9
 add_subdirectory(libuptev)
10 10
 add_subdirectory(libuptpl)
11
+add_subdirectory(upt-trace)
11 12
 add_subdirectory(tests)
... ...
@@ -0,0 +1,102 @@
1
+# UProcTrace: User-space Process Tracing
2
+
3
+UProcTrace traces process executions and process ends on Linux systems.
4
+
5
+On process starts, UProcTrace records the time, the entire command line,
6
+working directory and environment. On process end, it logs the CPU time used by
7
+the process (split by user and kernel time) and the peak memory usage.
8
+
9
+UProcTrace is implemented in user-space, so does not reuire any special kernel
10
+modules.  This means it can also be used in containers (e.g. docker) without
11
+any changes the to conteiner host.  The implementation is based on the
12
+`LD_PRELOAD` mechanism.  A shared library is injected into each process
13
+started. This libarary records trace events at begin of the process (when the
14
+preload library is initialized) and at the end of the process (when the library
15
+is de-initiazlied).
16
+
17
+## Building
18
+
19
+UProcTrace is developed on Debian Linux 10 "buster".
20
+
21
+Install the prerequisites:
22
+
23
+```
24
+apt-get install -y build-essential cmake gcc \
25
+                   libprotobuf-c-dev libprotobuf-dev
26
+                   ninja-build \
27
+                   protobuf-c-compiler protobuf-compiler \
28
+                   python3 python3-protobuf
29
+```
30
+
31
+Change to the directory of this `REAMDE.md` file.
32
+
33
+Configure a build directory:
34
+
35
+```
36
+mkdir build
37
+cd build
38
+cmake -G Ninja -D CMAKE_BUILD_TYPE=Release ..
39
+```
40
+
41
+Build:
42
+
43
+```
44
+ninja
45
+```
46
+
47
+Run tests:
48
+
49
+```
50
+ctest
51
+```
52
+
53
+## Tracing Applications
54
+
55
+To trace an application, prefix the command with `upt-trace` and the
56
+file name for the trace.  For example, to trace the command
57
+```
58
+/usr/bin/printf "trace me"
59
+```
60
+run the following command:
61
+```
62
+<build dir>/bin/upt-trace mytrace.proto /usr/bin/printf "trace me"
63
+```
64
+
65
+To show the recorded events, run:
66
+```
67
+<build dir>/dump/dump.py mytrace.proto
68
+```
69
+
70
+## Example: Trace Build Process
71
+
72
+To show the capabilities of the UProcTrace, a process that calls several child
73
+processes is required. In this example, the build of UProcTrace is used for
74
+this purpose.
75
+
76
+Change to the build directory.
77
+
78
+Start a new shell to be traced:
79
+```
80
+bin/upt-trace mytrace.proto bash
81
+```
82
+
83
+Configure another build directory for this tracing example and run the build:
84
+
85
+```
86
+mkdir example_trace_build
87
+cd example_trace_build
88
+cmake -G Ninja -D CMAKE_BUILD_TYPE=Release ../..
89
+ninja
90
+```
91
+
92
+Stop tracing by ending the shell:
93
+
94
+```
95
+exit
96
+```
97
+
98
+Show traced information:
99
+```
100
+dump/dump.py mytrace.proto
101
+```
102
+
... ...
@@ -1 +1,2 @@
1 1
 add_subdirectory(first)
2
+add_subdirectory(trace_build)
... ...
@@ -2,18 +2,5 @@ add_test(
2 2
   NAME
3 3
   first
4 4
   COMMAND
5
-  bash -c
6
-  "
7
-    set -eux -o pipefail
8
-    > out.proto
9
-    (
10
-      export UPTPL_OUTPUT=out.proto
11
-      export LD_PRELOAD=${CMAKE_BINARY_DIR}/libuptpl/libuptpl.so
12
-      /bin/true a b 'c d'
13
-      /usr/bin/printf '' e f 'g h'
14
-    )
15
-    ls -l out.proto
16
-    ${CMAKE_BINARY_DIR}/dump/dump.py out.proto | tee out.dump
17
-    grep '^ *event *{ *$' out.dump | wc -l | grep '^4$'
18
-  "
5
+  ${CMAKE_CURRENT_SOURCE_DIR}/first.bash ${CMAKE_BINARY_DIR}
19 6
 )
... ...
@@ -0,0 +1,22 @@
1
+#! /bin/bash
2
+
3
+set -eux -o pipefail
4
+
5
+if (( $# < 1 ))
6
+then
7
+  echo "usage: $0 <UPT_HOME>" >&2
8
+  exit 2
9
+fi
10
+UPT_HOME="$1"
11
+
12
+SCRIPT_DIR="$(dirname "$0")"
13
+
14
+rm -rf out.proto
15
+
16
+"$UPT_HOME/bin/upt-trace" out.proto "$SCRIPT_DIR/traceme.bash"
17
+
18
+ls -l out.proto
19
+
20
+"$UPT_HOME/dump/dump.py" out.proto | tee out.dump
21
+grep '^ *event *{ *$' out.dump | wc -l | tee out.event_cnt
22
+grep '^6$' out.event_cnt
... ...
@@ -0,0 +1,3 @@
1
+#! /bin/bash
2
+/bin/true a b 'c d'
3
+/usr/bin/printf '' e f 'g h'
... ...
@@ -0,0 +1,7 @@
1
+add_test(
2
+  NAME
3
+  trace_build
4
+  COMMAND
5
+  ${CMAKE_CURRENT_SOURCE_DIR}/trace_build.bash ${CMAKE_SOURCE_DIR}
6
+                                               ${CMAKE_BINARY_DIR}
7
+)
... ...
@@ -0,0 +1,16 @@
1
+#! /bin/bash
2
+
3
+set -eux -o pipefail
4
+
5
+if (( $# < 1 ))
6
+then
7
+  echo "usage: $0 <SOURCE_DIR>" >&2
8
+  exit 2
9
+fi
10
+SOURCE_DIR="$(readlink -f "$1")"
11
+
12
+
13
+mkdir build
14
+cd build
15
+cmake -G Ninja -D CMAKE_BUILD_TYPE=Release "$SOURCE_DIR"
16
+ninja
... ...
@@ -0,0 +1,24 @@
1
+#! /bin/bash
2
+
3
+set -eux -o pipefail
4
+
5
+if (( $# < 2 ))
6
+then
7
+  echo "usage: $0 <SOURCE_DIR> <UPT_HOME>" >&2
8
+  exit 2
9
+fi
10
+SOURCE_DIR="$(readlink -f "$1")"
11
+UPT_HOME="$(readlink -f "$2")"
12
+
13
+SCRIPT_DIR="$(dirname "$0")"
14
+
15
+rm -rf out.proto build
16
+
17
+"$UPT_HOME/bin/upt-trace" out.proto "$SCRIPT_DIR/run_build.bash" "$SOURCE_DIR"
18
+
19
+ls -l out.proto
20
+
21
+"$UPT_HOME/dump/dump.py" out.proto | tee out.dump
22
+grep -A 1 '^ *cmdline {$' out.dump | grep '^ *s: "mkdir"$'
23
+grep '^ *s: "proc_begin.c"$' out.dump
24
+grep '^ *s: "libuptpl.so"$' out.dump
... ...
@@ -0,0 +1,16 @@
1
+add_custom_command(
2
+  OUTPUT
3
+  ${CMAKE_BINARY_DIR}/bin/upt-trace
4
+  DEPENDS
5
+  ${CMAKE_CURRENT_SOURCE_DIR}/upt-trace.bash
6
+  COMMAND
7
+  cp -a ${CMAKE_CURRENT_SOURCE_DIR}/upt-trace.bash
8
+        ${CMAKE_BINARY_DIR}/bin/upt-trace
9
+)
10
+
11
+add_custom_target(
12
+  upt-trace
13
+  ALL
14
+  DEPENDS
15
+  ${CMAKE_BINARY_DIR}/bin/upt-trace
16
+)
... ...
@@ -0,0 +1,17 @@
1
+#! /bin/bash
2
+
3
+if (( $# < 2 ))
4
+then
5
+  echo "usage: $0 <upt-trace-file.proto> <command> [<arg> [...]]" >&2
6
+  exit 2
7
+fi
8
+TRACE_FILE="$1"
9
+shift
10
+
11
+UPT_HOME="$(readlink -f "$(dirname "$(dirname "$0")")")"
12
+
13
+touch "$TRACE_FILE"
14
+export UPTPL_OUTPUT="$(readlink -f "$TRACE_FILE")"
15
+export LD_PRELOAD="$UPT_HOME/libuptpl/libuptpl.so"
16
+
17
+exec "$@"
0 18