All of lore.kernel.org
 help / color / mirror / Atom feed
From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
To: Pierrick Bouvier <pierrick.bouvier@linaro.org>, qemu-devel@nongnu.org
Cc: "Mahmoud Mandour" <ma.mandourr@gmail.com>,
	"Philippe Mathieu-Daudé " <philmd@linaro.org>,
	"rowan Hart" <rowanbhart@gmail.com>,
	"Gustavo Romero" <gustavo.romero@linaro.org>,
	"Manos Pitsidianakis" <manos.pitsidianakis@linaro.org>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"Alexandre Iooss" <erdnaxe@crans.org>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Richard Henderson" <richard.henderson@linaro.org>
Subject: Re: [PATCH v5 9/9] contrib/plugins/uftrace: add documentation
Date: Fri, 08 Aug 2025 12:46:52 +0300	[thread overview]
Message-ID: <t0o659.1do94331ogqw5@linaro.org> (raw)
In-Reply-To: <20250808020702.410109-10-pierrick.bouvier@linaro.org>

On Fri, 08 Aug 2025 05:07, Pierrick Bouvier <pierrick.bouvier@linaro.org> wrote:
>This documentation summarizes how to use the plugin, and present two
>examples of the possibilities offered by it, in system and user mode.
>
>As well, it explains how to rebuild and reproduce those examples.
>
>Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>---
> docs/about/emulation.rst | 197 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 197 insertions(+)
>
>diff --git a/docs/about/emulation.rst b/docs/about/emulation.rst
>index 456d01d5b08..9ce47ac2712 100644
>--- a/docs/about/emulation.rst
>+++ b/docs/about/emulation.rst
>@@ -816,6 +816,203 @@ This plugin can limit the number of Instructions Per Second that are executed::
>       The lower the number the more accurate time will be, but the less efficient the plugin.
>       Defaults to ips/10
> 
>+Uftrace
>+.......
>+
>+``contrib/plugins/uftrace.c``
>+
>+This plugin generates a binary trace compatible with
>+`uftrace <https://github.com/namhyung/uftrace>`_.
>+
>+Plugin supports aarch64 and x64, and works in user and system mode, allowing to
>+trace a system boot, which is not something possible usually.

Now it is!

>+
>+In user mode, the memory mapping is directly copied from ``/proc/self/maps`` at
>+the end of execution. Uftrace should be able to retrieve symbols by itself,
>+without any additional step.
>+In system mode, the default memory mapping is empty, and you can generate
>+one (and associated symbols) using ``contrib/plugins/uftrace_symbols.py``.
>+Symbols must be present in ELF binaries.
>+
>+It tracks the call stack (based on frame pointer analysis). Thus, your program
>+and its dependencies must be compiled using ``-fno-omit-frame-pointer
>+-mno-omit-leaf-frame-pointer``. In 2024, `Ubuntu and Fedora enabled it by
>+default again on x64
>+<https://www.brendangregg.com/blog/2024-03-17/the-return-of-the-frame-pointers.html>`_.
>+On aarch64, this is less of a problem, as they are usually part of the ABI,
>+except for leaf functions. That's true for user space applications, but not
>+necessarily for bare metal code. You can read this `section
>+<uftrace_build_system_example>` to easily build a system with frame pointers.
>+
>+When tracing long scenarios (> 1 min), the generated trace can become very long,
>+making it hard to extract data from it. In this case, a simple solution is to
>+trace execution while generating a timestamped output log using
>+``qemu-system-aarch64 ... | ts "%s"``. Then, ``uftrace --time-range=start~end``
>+can be used to reduce trace for only this part of execution.
>+
>+Performance wise, overhead compared to normal tcg execution is around x5-x15.
>+
>+.. list-table:: Uftrace plugin arguments
>+  :widths: 20 80
>+  :header-rows: 1
>+
>+  * - Option
>+    - Description
>+  * - trace-privilege-level=[on|off]
>+    - Generate separate traces for each privilege level (Exception Level +
>+      Security State on aarch64, Rings on x64).
>+
>+.. list-table:: uftrace_symbols.py arguments
>+  :widths: 20 80
>+  :header-rows: 1
>+
>+  * - Option
>+    - Description
>+  * - elf_file [elf_file ...]
>+    - path to an ELF file. Use /path/to/file:0xdeadbeef to add a mapping offset.
>+  * - --prefix-symbols
>+    - prepend binary name to symbols
>+
>+Example user trace
>+++++++++++++++++++
>+
>+As an example, we can trace qemu itself running git::
>+
>+    $ ./build/qemu-aarch64 -plugin \
>+      build/contrib/plugins/libuftrace.so \
>+      ./build/qemu-aarch64 /usr/bin/git --help
>+
>+    # and generate a chrome trace directly
>+    $ uftrace dump --chrome | gzip > ~/qemu_aarch64_git_help.json.gz
>+
>+For convenience, you can download this trace `qemu_aarch64_git_help.json.gz
>+<https://fileserver.linaro.org/s/N8X8fnZ5yGRZLsT/download/qemu_aarch64_git_help.json.gz>`_.

We should be able to add static files in the docs/ folder that sphinx 
html can link to for images and json. WDYT?

>+Download it and open this trace on https://ui.perfetto.dev/. You can zoom in/out
>+using w,a,s,d keys. Some sequences taken from this trace:

You can use :kbd:`W` etc for nice key formatting

>+
>+- Loading program and its interpreter
>+
>+.. image:: https://fileserver.linaro.org/s/fie8JgX76yyL5cq/preview
>+   :height: 200px
>+
>+- open syscall
>+
>+.. image:: https://fileserver.linaro.org/s/rsXPTeZZPza4PcE/preview
>+   :height: 200px
>+
>+- TB creation
>+
>+.. image:: https://fileserver.linaro.org/s/GXY6NKMw5EeRCew/preview
>+   :height: 200px
>+
>+It's usually better to use ``uftrace record`` directly. However, tracing
>+binaries through qemu-user can be convenient when you don't want to recompile
>+them (``uftrace record`` requires instrumentation), as long as symbols are
>+present.
>+
>+Example system trace
>+++++++++++++++++++++
>+
>+A full trace example (chrome trace, from instructions below) generated from a
>+system boot can be found `here
>+<https://fileserver.linaro.org/s/WsemLboPEzo24nw/download/aarch64_boot.json.gz>`_.
>+Download it and open this trace on https://ui.perfetto.dev/. You can see code
>+executed for all privilege levels, and zoom in/out using w,a,s,d keys. You can
>+find below some sequences taken from this trace:
>+
>+- Two first stages of boot sequence in Arm Trusted Firmware (EL3 and S-EL1)
>+
>+.. image:: https://fileserver.linaro.org/s/kkxBS552W7nYESX/preview
>+   :height: 200px
>+
>+- U-boot initialization (until code relocation, after which we can't track it)
>+
>+.. image:: https://fileserver.linaro.org/s/LKTgsXNZFi5GFNC/preview
>+   :height: 200px
>+
>+- Stat and open syscalls in kernel
>+
>+.. image:: https://fileserver.linaro.org/s/dXe4MfraKg2F476/preview
>+   :height: 200px
>+
>+- Timer interrupt
>+
>+.. image:: https://fileserver.linaro.org/s/TM5yobYzJtP7P3C/preview
>+   :height: 200px
>+
>+- Poweroff sequence (from kernel back to firmware, NS-EL2 to EL3)
>+
>+.. image:: https://fileserver.linaro.org/s/oR2PtyGKJrqnfRf/preview
>+   :height: 200px
>+
>+Build and run system example
>+++++++++++++++++++++++++++++
>+
>+.. _uftrace_build_system_example:
>+
>+Building a full system image with frame pointers is not trivial.
>+
>+We provide a `simple way <https://github.com/pbo-linaro/qemu-linux-stack>`_ to
>+build an aarch64 system, combining Arm Trusted firmware, U-boot, Linux kernel
>+and debian userland. It's based on containers (``podman`` only) and
>+``qemu-user-static (binfmt)`` to make sure it's easily reproducible and does not depend
>+on machine where you build it.
>+
>+You can follow the exact same instructions for a x64 system, combining edk2,
>+Linux, and Ubuntu, simply by switching to
>+`x86_64 <https://github.com/pbo-linaro/qemu-linux-stack/tree/x86_64>`_ branch.
>+
>+To build the system::
>+
>+    # Install dependencies
>+    $ sudo apt install -y podman qemu-user-static
>+
>+    $ git clone https://github.com/pbo-linaro/qemu-linux-stack
>+    $ cd qemu-linux-stack
>+    $ ./build.sh
>+
>+    # system can be started using:
>+    $ ./run.sh /path/to/qemu-system-aarch64
>+
>+To generate a uftrace for a system boot from that::
>+
>+    # run true and poweroff the system
>+    $ env INIT=true ./run.sh path/to/qemu-system-aarch64 \
>+      -plugin path/to/contrib/plugins/libuftrace.so,trace-privilege-level=on
>+
>+    # generate symbols and memory mapping
>+    $ path/to/contrib/plugins/uftrace_symbols.py \
>+      --prefix-symbols \
>+      arm-trusted-firmware/build/qemu/debug/bl1/bl1.elf \
>+      arm-trusted-firmware/build/qemu/debug/bl2/bl2.elf \
>+      arm-trusted-firmware/build/qemu/debug/bl31/bl31.elf \
>+      u-boot/u-boot:0x60000000 \
>+      linux/vmlinux
>+
>+    # inspect trace with
>+    $ uftrace replay
>+
>+Uftrace allows to filter the trace, and dump flamegraphs, or a chrome trace.
>+This last one is very interesting to see visually the boot process::
>+
>+    $ uftrace dump --chrome > boot.json
>+    # Open your browser, and load boot.json on https://ui.perfetto.dev/.
>+
>+Long visual chrome traces can't be easily opened, thus, it might be
>+interesting to generate them around a particular point of execution::
>+
>+    # execute qemu and timestamp output log
>+    $ env INIT=true ./run.sh path/to/qemu-system-aarch64 \
>+      -plugin path/to/contrib/plugins/libuftrace.so,trace-privilege-level=on |&
>+      ts "%s" | tee exec.log
>+
>+    $ cat exec.log  | grep 'Run /init'
>+      1753122320 [   11.834391] Run /init as init process
>+      # init was launched at 1753122320
>+
>+    # generate trace around init execution (2 seconds):
>+    $ uftrace dump --chrome --time-range=1753122320~1753122322 > init.json
>+
> Other emulation features
> ------------------------
> 
>-- 
>2.47.2
>


Sounds comprehensive all in all. I will try to follow the instructions 
and post a Tested-by

For the doc text:

Reviewed-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org> 


  reply	other threads:[~2025-08-08  9:54 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-08  2:06 [PATCH v5 0/9] contrib/plugins: uftrace Pierrick Bouvier
2025-08-08  2:06 ` [PATCH v5 1/9] contrib/plugins/uftrace: skeleton file Pierrick Bouvier
2025-08-08  8:14   ` Manos Pitsidianakis
2025-08-08 16:19     ` Pierrick Bouvier
2025-08-08 16:34       ` Manos Pitsidianakis
2025-08-08 17:28     ` Pierrick Bouvier
2025-08-08  2:06 ` [PATCH v5 2/9] contrib/plugins/uftrace: define cpu operations and implement aarch64 Pierrick Bouvier
2025-08-08  8:28   ` Manos Pitsidianakis
2025-08-08 16:27     ` Pierrick Bouvier
2025-08-08 16:36       ` Manos Pitsidianakis
2025-08-08  2:06 ` [PATCH v5 3/9] contrib/plugins/uftrace: track callstack Pierrick Bouvier
2025-08-08  8:49   ` Manos Pitsidianakis
2025-08-08 16:36     ` Pierrick Bouvier
2025-08-08  2:06 ` [PATCH v5 4/9] contrib/plugins/uftrace: implement tracing Pierrick Bouvier
2025-08-08  9:11   ` Manos Pitsidianakis
2025-08-08 16:38     ` Pierrick Bouvier
2025-08-08 18:03     ` Pierrick Bouvier
2025-08-08 18:13       ` Manos Pitsidianakis
2025-08-08 18:23         ` Pierrick Bouvier
2025-08-08 18:29           ` Manos Pitsidianakis
2025-08-08 18:24     ` Pierrick Bouvier
2025-08-08  2:06 ` [PATCH v5 5/9] contrib/plugins/uftrace: implement privilege level tracing Pierrick Bouvier
2025-08-08  9:26   ` Manos Pitsidianakis
2025-08-08 16:41     ` Pierrick Bouvier
2025-08-08  2:06 ` [PATCH v5 6/9] contrib/plugins/uftrace: generate additional files for uftrace Pierrick Bouvier
2025-08-08  9:37   ` Manos Pitsidianakis
2025-08-08 16:42     ` Pierrick Bouvier
2025-08-08  2:07 ` [PATCH v5 7/9] contrib/plugins/uftrace: implement x64 support Pierrick Bouvier
2025-08-08  9:42   ` Manos Pitsidianakis
2025-08-08 16:52     ` Pierrick Bouvier
2025-08-08  2:07 ` [PATCH v5 8/9] contrib/plugins/uftrace_symbols.py Pierrick Bouvier
2025-08-08  2:07 ` [PATCH v5 9/9] contrib/plugins/uftrace: add documentation Pierrick Bouvier
2025-08-08  9:46   ` Manos Pitsidianakis [this message]
2025-08-08 16:59     ` Pierrick Bouvier
2025-08-08 20:45 ` [PATCH v5 0/9] contrib/plugins: uftrace Pierrick Bouvier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=t0o659.1do94331ogqw5@linaro.org \
    --to=manos.pitsidianakis@linaro.org \
    --cc=alex.bennee@linaro.org \
    --cc=erdnaxe@crans.org \
    --cc=gustavo.romero@linaro.org \
    --cc=ma.mandourr@gmail.com \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@linaro.org \
    --cc=pierrick.bouvier@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=rowanbhart@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.