aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2020-07-10 12:53:46 -0400
committerNick Mathewson <nickm@torproject.org>2020-07-10 12:53:46 -0400
commit6fb1637255122dc3660486cf731c0f4640fd98db (patch)
tree3cfca259c7454c1322475b8fa907f769ecc12dfb /doc
parent1a4e475d5d86b0325914000889d5fd0dde42c2ad (diff)
parentdfaa0a82acdfbd65dde0a30fa8fd598304a86816 (diff)
downloadtor-6fb1637255122dc3660486cf731c0f4640fd98db.tar.gz
tor-6fb1637255122dc3660486cf731c0f4640fd98db.zip
Merge remote-tracking branch 'tor-gitlab/mr/29'
Diffstat (limited to 'doc')
-rw-r--r--doc/HACKING/Tracing.md150
1 files changed, 106 insertions, 44 deletions
diff --git a/doc/HACKING/Tracing.md b/doc/HACKING/Tracing.md
index e1e97abe6d..d898bee172 100644
--- a/doc/HACKING/Tracing.md
+++ b/doc/HACKING/Tracing.md
@@ -2,19 +2,44 @@
This document describes how the event tracing subsystem works in tor so
developers can add events to the code base but also hook them to an event
-tracing framework.
+tracing framework (i.e. tracer).
-## Basics
+## WARNING ##
-Event tracing is separated in two concepts, trace events and a tracer. The
-tracing subsystem can be found in `src/trace`. The `events.h` header file is
-the main file that maps the different tracers to trace events.
+Tracing the tor daemon **always** generates sensitive data if used in
+production (on the public network).
+
+It **is** ethical for researchers to use tracing for their own tor client (for
+example: building paths, timings, or performance).
+
+It is **NOT** ethical to archive, publish or keep data containing other users'
+activity such as relay data or anything that handles users' traffic. This
+of course includes any logs below notice level.
+
+Publishing analysis of tracing data containing user traffic is **NOT** safe
+either.
+
+In other words, tracing data that contains other users's activity is **NOT**
+safe to publish in any form.
+
+## Basics ###
+
+Tracing is separated in two different concepts. The tracing API and the
+tracing probes.
+
+The API is in `src/lib/trace/` which defines how to call tracepoints in the
+tor code. Every C files should include `src/lib/trace/events.h" if they want
+to call a tracepoint.
+
+The probes are what actually record the tracepoint data. Because they often
+need to access specific subsystem objects, the probes are within each
+subsystem. They are defined in the `trace-probes-<subsystem>.c` files.
### Events
-A trace event is basically a function from which we can pass any data that
-we want to collect. In addition, we specify a context for the event such as
-a subsystem and an event name.
+A trace event is basically a function from which we can pass any data that we
+want to collect. In addition, we specify a context for the event such as the
+subsystem and an event name.
A trace event in tor has the following standard format:
@@ -23,69 +48,106 @@ A trace event in tor has the following standard format:
The `subsystem` parameter is the name of the subsytem the trace event is in.
For example that could be "scheduler" or "vote" or "hs". The idea is to add
some context to the event so when we collect them we know where it's coming
-from. The `event_name` is the name of the event which helps a lot with
-adding some semantic to the event. Finally, `args` is any number of
-arguments we want to collect.
+from.
+
+The `event\_name` is the name of the event which adds better semantic to the
+event.
+
+The `args` can be any number of arguments we want to collect.
Here is an example of a possible tracepoint in main():
tor_trace(main, init_phase, argc)
-The above is a tracepoint in the `main` subsystem with `init_phase` as the
-event name and the `int argc` is passed to the event as well.
+The above is a tracepoint in the `main` subsystem with `init\_phase` as the
+event name and the `int argc` is passed to the event as one argument.
How `argc` is collected or used has nothing to do with the instrumentation
(adding trace events to the code). It is the work of the tracer so this is why
the trace events and collection framework (tracer) are decoupled. You _can_
have trace events without a tracer.
-### Tracer
+### Instrumentation ###
+
+In `src/lib/trace/events.h`, we map the high level `tor\_trace()` macro to one
+or many enabled instrumentation.
+
+Currently, we have 3 types of possible instrumentation:
-In `src/trace/events.h`, we map the `tor_trace()` function to the right
-tracer. A tracer support is only enabled at compile time. For instance, the
-file `src/trace/debug.h` contains the mapping of the generic tracing function
-`tor_trace()` to the `log_debug()` function. More specialized function can be
-mapped depending on the tracepoint.
+1. Debug
+
+ This will map every tracepoint to `log\_debug()`. However, none of the
+ arguments will be passed on because we don't know their type nor the string
+ format of the debug log. The output is standardized like this:
+
+ [debug] __FUNC__: Tracepoint <event_name> from subsystem <subsystem> hit.
+
+2. USDT
+
+ User Statically-Defined Tracing (USDT) is a kind of probe which can be
+ handled by a variety of tracers such as SystemTap, DTrace, perf, eBPF and
+ ftrace.
+
+ For each tracer, one will need to define the ABI in order for the tracer to
+ be able to extract the data from the tracepoint objects. For instance, the
+ tracer needs to know how to print the circuit state of a `circuit\_t`
+ object.
+
+3. LTTng-UST
+
+ LTTng Userspace is a tracer that has it own type of instrumentation. The
+ probe definitions are created within the C code and is strongly typed.
+
+ For more information, see https://lttng.org/docs.
## Build System
-This section describes how it is integrated into the build system of tor.
+This section describes how the instrumentation is integrated into the build
+system of tor.
+
+By default, every tracing events are disabled in tor that is `tor\_trace()` is
+a NOP thus has no execution cost time.
-By default, every tracing events are disabled in tor that is `tor_trace()`
-is a NOP.
+To enable a specific instrumentation, there are configure options:
-To enable a tracer, there is a configure option on the form of:
+1. Debug: `--enable-tracing-instrumentation-debug`
- --enable-tracing-<tracer>
+2. USDT: `--enable-tracing-instrumentation-usdt`
-We have an option that will send every trace events to a `log_debug()` (as
-mentionned above) which will print you the subsystem and name of the event but
-not the arguments for technical reasons. This is useful if you want to quickly
-see if your trace event is being hit or well written. To do so, use this
-configure option:
+3. LTTng: `--enable-tracing-instrumentation-lttng`
- --enable-tracing-debug
+They can all be used together or independently. If one of them is set,
+`HAVE\_TRACING` define is set. And for each instrumentation, a
+`USE\_TRACING\_INSTRUMENTATION\_<type>` is set.
-## Instrument Tor
+## Adding a Tracepoint ##
This is pretty easy. Let's say you want to add a trace event in
-`src/feature/rend/rendcache.c`, you only have to add this include statement:
+`src/feature/rend/rendcache.c`, you first need to include this file:
- #include "trace/events.h"
+ #include "lib/trace/events.h"
-Once done, you can add as many as you want `tor_trace()` that you need.
-Please use the right subsystem (here it would be `hs`) and a unique name that
-tells what the event is for. For example:
+Then, the `tor\_trace()` macro can be used with the specific format detailled
+before in a previous section. As an example:
tor_trace(hs, store_desc_as_client, desc, desc_id);
-If you look in `src/trace/events.h`, you'll see that if tracing is enabled it
-will be mapped to a function called:
+For `Debug` instrumentation, you have nothing else to do.
+
+For `USDT`, instrumentation, you will need to define the probes in a way the
+specific tracer can understand. For instance, SystemTap requires you to define
+a `tapset` for each tracepoints.
+
+For `LTTng`, you will need to define the probes in the
+`trace-probes-<subsystem>.{c|h}` file. See the `trace-probes-circuit.{c|h}`
+file as an example and https://lttng.org/docs/v2.11/#doc-instrumenting.
+
+## Performance ##
- tor_trace_hs_store_desc_as_client(desc, desc_id)
+A word about performance when a tracepoint is enabled. One of the goal of a
+tracepoint (USDT, LTTng-UST, ...) is that they can be enabled or disabled. By
+default, they are disabled which means the tracer will not record the data but
+it has to do a check thus the cost is basically the one of a `branch`.
-And the point of all this is for that function to be defined in a new file
-that you might want to add named `src/trace/hs.{c|h}` which would defined how
-to collect the data for the `tor_trace_hs_store_desc_as_client()` function
-like for instance sending it to a `log_debug()` or do more complex operations
-or use a userspace tracer like LTTng (https://lttng.org).
+If enabled, then the performance depends on the tracer. In the case of
+LTTng-UST, the event costs around 110nsec.