On Linux distros, the following commands will build and install uftrace from source.
$ sudo misc/install-deps.sh # optional for advanced features
$ ./configure # --prefix can be used to change install dir
$ make
$ sudo make install
For more information, please see below.
The latest version of uftrace is available at Github.
https://github.com/namhyung/uftrace
The uftrace is written in C and tried to minimize external dependencies. Currently, uftrace can be built without any external libraries. But in order to use more advanced features, it'd be better to install them like below.
Firstly, please make sure pkg-config
is installed on the system to properly
detect the dependencies of uftrace. Otherwise, some packages may not be
detected even if they are already installed, causing some features of
uftrace to be disabled.
Historically, uftrace depended on the libelf
from elfutils project for ELF
file manipulation. While it's not mandatory anymore, we recommend you to
install it for better handling of ELF binaries. Also libdw
library is
recommended to be installed in order to process DWARF debug information. The
libdw itself depends on the libelf
, so you can just install libdw
.
On debian based systems (like Ubuntu), libdw-dev
package will provide the
required libraries/files.
$ sudo apt-get install libdw-dev
On redhat based systems (like Fedora, RHEL), it'll be elfutils-devel
.
$ sudo dnf install elfutils-devel
uftrace also uses libstdc++ library to demangle C++ symbols in full detail. But it's not mandatory as uftrace has its own demangler for shorter symbol name (it omits arguments, templates and so on).
The ncursesw library is used to implement text user interface (TUI) on console.
The ncurses(w) library provides terminal handling routines which uftrace tui
command is built on top of. As it improves user experience of trace data
analysis, you should consider installing it if you do things like uftrace graph
or uftrace report
frequently.
Also uftrace needs pandoc
to build man pages from the markdown document.
To build uftrace, you need to install basic software development tools first - like gcc and make. And you also need to install dependent packages. Please see DEPENDENCY section for more details.
Once you have installed the required software(s), you need to run configure
to set
the install directory and other features. It installs the uftrace under /usr/local
by default. If you want install it to some other location, you can set the prefix
variable (see below).
$ ./configure --prefix=/usr
It will show the prefix directory and detected features like:
uftrace detected system features:
... prefix: /usr
... libelf: [ on ] - more flexible ELF data handling
... libdw: [ on ] - DWARF debug info support
... libpython: [ on ] - python scripting support
... libluajit: [ OFF ] - luajit scripting support
... libncursesw: [ on ] - TUI support
... cxa_demangle: [ on ] - full demangler support with libstdc++
... perf_event: [ on ] - perf (PMU) event support
... schedule: [ on ] - scheduler event support
... capstone: [ on ] - full dynamic tracing support
... libunwind: [ OFF ] - stacktrace support (optional for debugging)
Then you can run make
to build the source.
$ make
It builds uftrace, placing the resulting binaries in the current directory. This is good for testing, but you'll want to install it for normal use.
$ sudo make install
The output of the build looks like linux kernel style, and users can see the original build command lines with V=1 (like kernel).
$ make V=1
The uftrace implements its own version of configure script to save user
preferences. The config file (named .config
) is created, if it doesn't exist,
at build time with default options. User can set custom installation
directories or build directory with this script.
$ ./configure --help
Usage: ./configure [<options>]
--help print this message
--prefix=<DIR> set install root dir as <DIR> (default: /usr/local)
--bindir=<DIR> set executable install dir as <DIR> (default: ${prefix}/bin)
--libdir=<DIR> set library install dir as <DIR> (default: ${prefix}/lib/uftrace)
--mandir=<DIR> set manual doc install dir as <DIR> (default: ${prefix}/share/man)
--objdir=<DIR> set build dir as <DIR> (default: ${PWD})
--sysconfdir=<DIR> override the etc dir as <DIR>
--with-elfutils=<DIR> search for elfutils in <DIR>/include and <DIR>/lib
--without-libelf build without libelf (and libdw) (even if found on the system)
--without-libdw build without libdw (even if found on the system)
--without-libstdc++ build without libstdc++ (even if found on the system)
--without-libpython build without libpython (even if found on the system)
--without-libluajit build without libluajit (even if found on the system)
--without-libncurses build without libncursesw (even if found on the system)
--without-capstone build without libcapstone (even if found on the system)
--without-perf build without perf event (even if available)
--without-schedule build without scheduler event (even if available)
--arch=<ARCH> set target architecture (default: system default arch)
e.g. x86_64, aarch64, i386, or arm
--cross-compile=<CROSS_COMPILE>
Specify the compiler prefix during compilation
e.g. CC is overridden by $(CROSS_COMPILE)gcc
--cflags=<CFLAGS> pass extra C compiler flags
--ldflags=<LDFLAGS> pass extra linker flags
-p preserve old setting
Some influential environment variables:
ARCH Target architecture e.g. x86_64, aarch64, i386, or arm
CROSS_COMPILE Specify the compiler prefix during compilation
e.g. CC is overridden by $(CROSS_COMPILE)gcc
CFLAGS C compiler flags
LDFLAGS linker flags
Also you can set the target architecture and compiler options like CC, CFLAGS.
It's also possible to disable some features that depend on external libraries or
system behaviors. For example --without-libpython option will disable scripting
feature - uftrace script
command will still exist but won't work.
For cross compilation, you may want to setup the toolchain to something like below:
$ export CROSS_COMPILE=/path/to/cross/toolchain/arm-unknown-linux-gnueabihf-
$ ARCH=arm CFLAGS='--sysroot /path/to/sysroot' ./configure
or
$ ./configure --arch=arm --cflags='--sysroot /path/to/sysroot' \
--cross-compile=/path/to/cross/toolchain/arm-unknown-linux-gnueabihf-
This assumes you already installed the cross-built libelf
on the sysroot
directory. Otherwise, you can also build it from source (please see below) or
use it on a different path using --with-elfutils=<PATH>
.
To compile for Android 9+, export the CC environment variable and disable the not yet implemented python and libstdc++ support. E.g. to configure for Android AArch64 do
$ export CC=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android33-clang
$ export LD=$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/ld.lld
$ ./configure --arch=aarch64 --cross-compile=aarch64-linux-gnu- --without-libpython --without-libstdc++
It's recommended to compile instrumented program with
-fpatchable-function-entry
on Android. You could also use
-finstrument-functions
or -pg
but in that case you also need to link program
with -Wl,-z,undefs
because Android runtime does not include
__cyg_profile_func_enter
or mcount
.
Note that Android has been tested on AArch64 and x86_64 so far.
It may be useful to manually compile libelf/libdw for uftrace build if the
target system doesn't have them installed. misc/install-elfutils.sh
provides
a way to download and build libelf and libdw, which are libraries in elfutils.
The below is the way to compile uftrace together with libelf/libdw.
$ export CROSS_COMPILE=arm-linux-gnueabi-
$ export ARCH=arm
$ export CFLAGS="-march=armv7-a"
$ ./misc/install-elfutils.sh --prefix=/path/to/install
$ ./configure --prefix=/path/to/install --with-elfutils=/path/to/install
$ make
$ make install
misc/install-elfutils.sh
downloads and builds elfutils and installs both
libelf and libdw to prefix directory. The installed libelf and libdw can be
found using --with-elfutils
in the configure
script.