Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tracing) Introducing USDT probes in Wasmer #2152

Closed
wants to merge 3 commits into from

Conversation

Hywan
Copy link
Contributor

@Hywan Hywan commented Mar 1, 2021

See original description to get the context

Description

Introducing wasmer-tracing (719f37d)

This is a proof-of-concept, or at best a work-in-progress, of
integrating USDT probes inside Wasmer through the new wasmer-tracing
crate.

USDT stands for Userland Statically Defined Tracing. USDT probes are
probes originally designed by DTrace, but now sucessfully implemented
in many environments, like Darwin, Solaris, Linux, Illumos, and even
Windows. It allows dynamic tracing at low-cost (a
probe is a noop, except when run with dtrace where a special section
of the object file is read to get the real probes and to instrument
the executable code, in some cases).

USDT aren't tied to DTrace only. On Linux for example, eBPF
understands USDT probes.

The process of generating and linking the probes is automated, but the
FFI bridge (probes_ffi.c and lib.rs) must be completed by hand for
each new added probe. It's not an issue as a few number of strategic
probes are going to be implemented.

This patch provides a new crate: wasmer-tracing.

The current set of probes (instance_start, instance_end,
function_start, function_invoke2 and function_end) is only
present to showcase the idea.

The scripts/tracing.d script showcases how to read data from those
probes to trace the execution of the VM itself with a DTrace script.

Note that for the moment, the probes —as implemented— are designed to
be used in Rust. It means we can only analyze the
compilation-step/compile-time of a Wasm module into executable code,
and some runtime operations. More work is required to implement probes
inside the executable code we generate with the compilers, i.e for the
entire execution-step/runtime (LLVM has XRay Instrumentation for
example, not sure it's the path we must follow but it exists).

Showcasing how to use wasmer-tracing (773ded6)

This patch showcases wasmer-tracing inside wasmer itself. Let's
see:

$ make build-wasmer
$ sudo dtrace -l -c ./target/release/wasmer | rg wasmer
54242 wasmer38542            wasmer wasmer_tracing_probe_function_end function-end
54243 wasmer38542            wasmer wasmer_tracing_probe_function_invoke2 function-invoke2
54244 wasmer38542            wasmer wasmer_tracing_probe_function_start function-start
54245 wasmer38542            wasmer wasmer_tracing_probe_instance_end instance-end
54246 wasmer38542            wasmer wasmer_tracing_probe_instance_start instance-start

See, Wasmer has USDT probes now! Now, let's use the
lib/tracing/scripts/tracing.d script (it's not fabulous, it just
showcases the principle):

$ sudo ./lib/tracing/scripts/tracing.d -c './target/release/wasmer run ./tests/examples/add.wat --invoke add -- 39 3'
From DTrace (wasmer-tracing)
42
instance starts
function starts
function invoked with arg0=39, arg1=3
function ends
instance ends

The first output line (“From DTrace (wasmer-tracing)”) is from the
tracing.d script. The second output line (“42”) is from Wasmer (it's
the sum of 39 and 3). The rest of the output is from the tracing.d
script.

Notice how the wasmer*:::function-invoke2 block receives the
arguments of the add exported function, inside arg0 and arg1.

I'm totally aware that wasmer isn't the correct place to declare
probes. Ideally, the VM, the compilers and the engines are better
places. Remember that it's just to showcase wasmer-tracing.

Description

This patch introduces USDT probes inside Wasmer (not inside the code generated by the compilers). Originally, this patch was doing it with wasmer-tracing, a new crate. There was a limitation though: We need to add clearly a lot of probes, and maintaining them by hand was complex, especially because the declaration of the probes was centralized in a single crate while they were being used in multiple crates. This patch has been updated to use sonde, a crate we wrote to address all our needs and previous limitations.

The resulting diff is much (much) smaller and easier to review.

Review

  • Add a short description of the the change to the CHANGELOG.md file

This is a proof-of-concept, or at best a work-in-progress, of
integrating USDT probes inside Wasmer through the new `wasmer-tracing`
crate.

USDT stands for Userland Statically Defined Tracing. USDT probes are
probes originally designed by DTrace, but now sucessfully implemented
in many environments, like Darwin, Solaris, Linux, Illumos, and even
[Windows][windows-dtrace]. It allows dynamic tracing at low-cost (a
probe is a noop, except when run with `dtrace` where a special section
of the object file is read to get the real probes and to instrument
the executable code, in some cases).

USDT aren't tied to DTrace only now. On Linux for example, eBPF
understands USDT probes. The process of generating and linking the
probes is automated, but the FFI bridge (`probes_ffi.c` and `lib.rs`)
must be completed by hand for each new added probe. It's not an issue
as a few number of strategic probes are going to be implemented.

This patch provides a new crate: `wasmer-tracing`.

The current set of probes (`instance_start`, `instance_end`,
`function_start`, `function_invoked2` and `function_end`) is only
present to showcase the idea.

The `scripts/tracing.d` script showcases how to read data from those
probes to trace the execution of the VM itself with a DTrace script.

Note that for the moment, the probes —as implemented— are designed to
be used in Rust. It means we can only analyze the
compilation-step/compile-time of a Wasm module into executable code,
and some runtime operations. More work is required to implement probes
inside the executable code we generate with the compilers, i.e for the
entire execution-step/runtime (LLVM has [XRay Instrumentation] for
example, not sure it's the path we must follow but it exists).

The next commit showcases how to use `wasmer-tracing`.

[windows-dtrace]: https://techcommunity.microsoft.com/t5/windows-kernel-internals/dtrace-on-windows/ba-p/362902
[XRay Instrumentation]: https://www.llvm.org/docs/XRay.html
This patch showcases `wasmer-tracing` inside `wasmer` itself. Let's
see:

```sh
$ make build-wasmer
$ sudo dtrace -l -c ./target/release/wasmer | rg wasmer
54242 wasmer38542            wasmer wasmer_tracing_probe_function_end function-end
54243 wasmer38542            wasmer wasmer_tracing_probe_function_invoke2 function-invoke2
54244 wasmer38542            wasmer wasmer_tracing_probe_function_start function-start
54245 wasmer38542            wasmer wasmer_tracing_probe_instance_end instance-end
54246 wasmer38542            wasmer wasmer_tracing_probe_instance_start instance-start
```

See, Wasmer has USDT probes now! Now, let's use the
`lib/tracing/scripts/tracing.d` script (it's not fabulous, it just
showcases the principle):

```sh
$ sudo ./lib/tracing/scripts/tracing.d -c './target/release/wasmer run ./tests/examples/add.wat --invoke add -- 39 3'
From DTrace (wasmer-tracing)
42
instance starts
function starts
function invoked with arg0=39, arg1=3
function ends
instance ends
```

The first output line (“From DTrace (wasmer-tracing)”) is from the
`tracing.d` script. The second output line (“42”) is from Wasmer (it's
the sum of 39 and 3). The rest of the output is from the `tracing.d`
script.

Notice how the `wasmer*:::function-invoked2` block receives the
arguments of the `add` exported function, inside `arg0` and `arg1`.

I'm totally aware that `wasmer` isn't the correct place to declare
probes. Ideally, the VM, the compilers and the engines are better
places. Remember that it's just to showcase `wasmer-tracing`.
@Hywan Hywan added the 🎉 enhancement New feature! label Mar 1, 2021
@Hywan Hywan self-assigned this Mar 1, 2021
@Hywan
Copy link
Contributor Author

Hywan commented Mar 9, 2021

Next step, remove wasmer-tracing and use https://github.com/Hywan/sonde-rs in all our crates where we need to add probes.

@Hywan Hywan changed the title feat(tracing) Introducing wasmer-tracing feat(tracing) Introducing USDT probes in Wasmer Mar 11, 2021
To make our lives simpler, we have created `sonde`
(https://github.com/Hywan/sonde-rs). It replaces `wasmer-tracing`.
@Hywan Hywan added this to 🌱 In progress in Wasmer Runtime Issue Board via automation Jul 19, 2021
@wchaudry wchaudry moved this from 🌱 In progress to 📬 Backlog in Wasmer Runtime Issue Board Oct 28, 2021
@syrusakbary
Copy link
Member

Closing this

Wasmer Runtime Issue Board automation moved this from 📬 Backlog to 🎉 Done Oct 28, 2021
@Nav196 Nav196 mentioned this pull request Jan 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🎉 enhancement New feature!
Projects
Development

Successfully merging this pull request may close these issues.

None yet

2 participants