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
... | ... |
@@ -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 |
+ |
... | ... |
@@ -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,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 |