| # Adding tracing to device drivers |
| |
| This document describes how to add tracing to device drivers. |
| |
| ## Overview |
| |
| Please read [Fuchsia tracing system](/docs/concepts/tracing/README.md) |
| for an overview of tracing. |
| |
| ## Trace Provider |
| |
| Drivers don't have to specify a Trace Provider, the devhost process |
| via `libdriver.so` provides it. It is mentioned here in case the topic |
| comes up. |
| |
| ## Adding trace records |
| |
| ### Source additions |
| |
| Trace records are easiest to add by invoking the `TRACE_*()` macros |
| from `ddk/trace/event.h`. |
| |
| There are various kinds of trace records that can be emitted. |
| Please see `trace/internal/event_common.h` for a description |
| of the various macros. |
| |
| Looking up macro documentation from internal implementation files |
| is a temporary situation. Ultimately such documentation will live |
| in a more appropriate place. |
| |
| Example: |
| |
| ```c++ |
| #include <ddk/trace/event.h> |
| |
| void DoSomething(int a, std::string b) { |
| TRACE_DURATION("example", "DoSomething", "a", a, "b", b); |
| |
| // Do something |
| } |
| ``` |
| |
| The first two arguments to most macros are the "category" and the |
| event name. Here they are "example" and "DoSomething" respectively. |
| |
| Trace categories are how the tracing system lets the user specify |
| what data to collect. If a category is not requested by the user |
| then the data is not collected. |
| |
| Categories don't need to be unique across the driver. |
| One typically groups several events under the same category. |
| |
| The event name is included in the trace to describe what the event |
| is about. It is typically unique for each event. |
| |
| ### BUILD.gn additions |
| |
| The following addition to your driver's `BUILD.gn` target is needed to |
| pick up tracing support: |
| |
| ```gn |
| driver_module("my_driver") { |
| deps = [ |
| ... |
| "//zircon/system/ulib/trace" |
| "//zircon/system/ulib/trace:trace-driver", |
| ] |
| } |
| ``` |
| |
| ## Building with tracing |
| |
| The following needs to be passed to fx set in order to trace drivers |
| that are loaded during boot: `--with-base=//garnet/packages/prod:tracing`. |
| |
| ```sh |
| $ fx set ${PRODUCT}.${BOARD} --with-base=//garnet/packages/prod:tracing |
| $ fx build |
| ``` |
| |
| The issue is that without this option then TraceManager won't be present |
| when the driver starts and thus the driver won't be able to participate |
| in tracing when TraceManager is started later. |
| |
| See the documentation for [fx](/docs/development/build/fx.md) |
| or even just the output of `fx help` and especially `fx help set` for further |
| documentation of running `fx` in general and `fx set` specifically. |
| |
| ## Booting with tracing |
| |
| To be conservative, tracing uses a kernel command line flag to enable it: |
| `driver.tracing.enable=1`. |
| `driver.tracing.enable=1` is the default. To disable participation |
| of drivers in Fuchsia tracing, boot the kernel with `driver.tracing.enable=0`. |
| |
| Then boot. See the documentation for your hardware or qemu for instructions |
| for booting the device. Tracing doesn't require anything special during boot. |
| |
| ## Using tracing |
| |
| Once the system is booted you can collect traces on the target and |
| then manually copy them to your development host. |
| These examples use the category from the source additions described above. |
| |
| Example: |
| |
| ```sh |
| fuchsia$ trace record --categories=example,kernel:sched,kernel:meta |
| host$ fx cp --to-host /data/trace.json trace.json |
| ``` |
| |
| However, it's easier to invoke the `traceutil` program on your development |
| host and it will copy the files directly to your host and prepare them for |
| viewing with the Chrome trace viewer. |
| |
| ```sh |
| host$ fx traceutil record \ |
| --categories=example,kernel:sched,kernel:meta |
| ``` |
| |
| The categories `kernel:sched,kernel:meta` should always be present if you |
| want to visualize the results. The visualizer wants to associate trace data |
| with threads and processes, and thus it needs the data provided by the kernel |
| via these categories. |
| |
| ## Further Reading |
| |
| See the [Tracing Documentation](/docs/development/tracing/README.md) |
| for further info. |