2022-08-31 11:31:55 +02:00
|
|
|
|
# Tracing a new program
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
2022-08-31 11:31:55 +02:00
|
|
|
|
Read carefully this document before using libovni to instrument a new
|
|
|
|
|
component. There are a few rules you must follow to ensure the runtime
|
|
|
|
|
trace is correct.
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
2022-08-29 17:10:38 +02:00
|
|
|
|
## Trace processes and threads
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
2022-12-13 13:11:44 +01:00
|
|
|
|
- Call `ovni_version_check()` once before calling any ovni function.
|
|
|
|
|
|
2022-08-29 17:10:38 +02:00
|
|
|
|
- Call `ovni_proc_init()` when a new process begins the execution.
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
2022-08-29 17:10:38 +02:00
|
|
|
|
- Call `ovni_thread_init()` when a new thread begins the execution
|
2023-11-09 15:10:13 +01:00
|
|
|
|
(including the main process thread).
|
|
|
|
|
|
|
|
|
|
- Call `ovni_thread_require()` with the required model version before
|
|
|
|
|
emitting events for that model.
|
|
|
|
|
|
|
|
|
|
- Call `ovni_flush()` and `ovni_thread_free()` when it finishes (in that
|
|
|
|
|
order).
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
2022-08-29 17:10:38 +02:00
|
|
|
|
- Call `ovni_proc_fini()` when a process ends, after all threads have
|
2023-11-09 15:10:13 +01:00
|
|
|
|
finished.
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
2022-08-29 16:24:29 +02:00
|
|
|
|
You can use `ovni_ev_emit()` to record a new event. If you need more
|
2022-08-29 17:10:38 +02:00
|
|
|
|
than 16 bytes of payload, use `ovni_ev_jumbo_emit()`. See the [trace
|
|
|
|
|
specification](../trace_spec) for more details.
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
2022-08-29 16:24:29 +02:00
|
|
|
|
Compile and link with libovni. When you run your program, a new
|
2022-08-29 17:10:38 +02:00
|
|
|
|
directory ovni will be created in the current directory `$PWD/ovni`
|
2022-08-29 16:24:29 +02:00
|
|
|
|
which contains the execution trace.
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
2023-10-17 15:44:07 +02:00
|
|
|
|
You can change the trace directory by defining the `OVNI_TRACEDIR`
|
|
|
|
|
environment variable. The envar accepts a trace directory name, a
|
|
|
|
|
relative path to the trace directory, or its absolute path. In the
|
|
|
|
|
first case, the trace directory will be created in the current
|
|
|
|
|
directory `$PWD`.
|
|
|
|
|
|
2022-08-29 16:24:29 +02:00
|
|
|
|
## Rules
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
|
|
|
|
Follow these rules to avoid losing events:
|
|
|
|
|
|
|
|
|
|
1. No event may be emitted until the process is initialized with
|
2022-08-29 16:24:29 +02:00
|
|
|
|
`ovni_proc_init()` and the thread with `ovni_thread_init()`.
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
2022-08-29 16:24:29 +02:00
|
|
|
|
2. When a thread ends the execution, it must call `ovni_flush()` to write the
|
2022-01-12 12:39:25 +01:00
|
|
|
|
events in the buffer to disk.
|
|
|
|
|
|
2022-08-29 16:24:29 +02:00
|
|
|
|
3. All threads must have flushed its buffers before calling `ovni_proc_fini()`.
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
2022-08-29 16:24:29 +02:00
|
|
|
|
## Select a fast directory
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
|
|
|
|
During the execution of your program, a per-thread buffer is kept where the new
|
|
|
|
|
events are being recorded. When this buffer is full, it is written to disk and
|
|
|
|
|
emptied, an operation known as flush. This may take a while depending on the
|
|
|
|
|
underliying filesystem.
|
|
|
|
|
|
|
|
|
|
Keep in mind that the thread will be blocked until the flush ends, so if your
|
|
|
|
|
filesystem is slow it would interrupt the execution of your program for a long
|
|
|
|
|
time. It is advisable to use the fastest filesystem available (see the tmpfs(5)
|
|
|
|
|
and df(1) manual pages).
|
|
|
|
|
|
|
|
|
|
You can select the trace directory where the buffers will be flushed during the
|
2022-08-29 16:24:29 +02:00
|
|
|
|
execution by setting the environment variable `OVNI_TMPDIR`. The last directory
|
2022-01-12 12:39:25 +01:00
|
|
|
|
will be created if doesn't exist. In that case, as soon as a process calls
|
2022-08-29 16:24:29 +02:00
|
|
|
|
`ovni_proc_fini()`, the traces of all its threads will be moved to the final
|
|
|
|
|
directory at `$PWD/ovni`. Example:
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
2022-08-29 16:24:29 +02:00
|
|
|
|
OVNI_TMPDIR=$(mktemp -u /dev/shm/ovni.XXXXXX) srun ./your-app
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|
|
|
|
|
To test the different filesystem speeds, you can use hyperfine and dd. Take a
|
|
|
|
|
closer look at the max time:
|
|
|
|
|
|
2022-08-29 16:24:29 +02:00
|
|
|
|
```
|
2022-01-12 12:39:25 +01:00
|
|
|
|
$ hyperfine 'dd if=/dev/zero of=/gpfs/projects/bsc15/bsc15557/kk bs=2M count=10'
|
|
|
|
|
Benchmark 1: dd if=/dev/zero of=/gpfs/projects/bsc15/bsc15557/kk bs=2M count=10
|
|
|
|
|
Time (mean ± σ): 71.7 ms ± 130.4 ms [User: 0.8 ms, System: 10.2 ms]
|
|
|
|
|
Range (min … max): 14.7 ms … 1113.2 ms 162 runs
|
|
|
|
|
|
|
|
|
|
Warning: Statistical outliers were detected. Consider re-running this
|
|
|
|
|
benchmark on a quiet PC without any interferences from other programs. It
|
|
|
|
|
might help to use the '--warmup' or '--prepare' options.
|
|
|
|
|
|
|
|
|
|
$ hyperfine 'dd if=/dev/zero of=/tmp/kk bs=2M count=10'
|
|
|
|
|
Benchmark 1: dd if=/dev/zero of=/tmp/kk bs=2M count=10
|
|
|
|
|
Time (mean ± σ): 56.2 ms ± 5.7 ms [User: 0.6 ms, System: 14.8 ms]
|
|
|
|
|
Range (min … max): 45.8 ms … 77.8 ms 63 runs
|
|
|
|
|
|
|
|
|
|
$ hyperfine 'dd if=/dev/zero of=/dev/shm/kk bs=2M count=10'
|
|
|
|
|
Benchmark 1: dd if=/dev/zero of=/dev/shm/kk bs=2M count=10
|
|
|
|
|
Time (mean ± σ): 11.4 ms ± 0.4 ms [User: 0.5 ms, System: 11.1 ms]
|
|
|
|
|
Range (min … max): 9.7 ms … 12.5 ms 269 runs
|
2022-08-29 16:24:29 +02:00
|
|
|
|
```
|
2022-01-12 12:39:25 +01:00
|
|
|
|
|