This Blog entry was provided by Eugene Loh
Oracle has been working in recent years on porting DTrace, the dynamic tracing tool, to Linux. DTrace offers easy-to-use, powerful, safe, and unintrusive tracing. Oracle's initial focus was the Oracle Unbreakable Enterprise Kernel (UEK), but DTrace runs on upstream Linux kernels and other distributions' Linux kernels as well. Note that at the moment, Oracle is in the process of upstreaming DTrace-related work and reimplementing DTrace itself on top of existing kernel infrastructure such as eBPF. (More on this in future blogs.)
Here, we illustrate how to build DTrace on Fedora on x86. While you can cut and paste commands from this blog into your command-line window, these steps are also available on GitHub as a script, which may be much easier to run. Keep in mind that this script is intended as a tutorial rather than a robust, turn-key utility. Read and understand the steps as you execute them. The steps are similar to what one does to build DTrace on other Linux distributions.
Useful references on building a custom Fedora kernel include:
The overall process is:
In the script, we pick a Fedora release, the DTrace branch to use (determined by the Linux version on which the Fedora release is based), and the number of DTrace patches on that branch:
# pick one # DTrace patches change relatively infrequently. # So DTrace_branch might not have to match your Fedora kernel version exactly. #fedora_release=f29; DTrace_branch=5.2.7 ; num_DTrace_patches=19 fedora_release=f30; DTrace_branch=5.2.7 ; num_DTrace_patches=19
The Compact Type Format originated on Solaris. It is used by DTrace, and this is the Linux port.
sudo dnf install -y git git clone https://github.com/oracle/libdtrace-ctf.git cd libdtrace-ctf sudo dnf builddep -y libdtrace-ctf.spec # install dependencies make sudo make install cd ..
The kernel repository has the "secret sauce" that turns upstream Linux into Fedora. There is a .spec file (listing patches, dependencies, and so on) as well as patches and .config files. It also points at one tarball that provides the base Linux code and another with patches to bring Linux up to rev.
sudo dnf install -y fedora-packager fedpkg co -a kernel # anonymous clone of Fedora patches cd kernel git checkout origin/$fedora_release fedpkg sources # download tarballs of kernel sources sudo dnf builddep -y kernel.spec # install dependencies cd ..
Now we download DTrace kernel code. This is a repository that applies DTrace patches to an upstream Linux version. We checkout the branch that corresponds to the Linux version on which the chosen Fedora release was based.
git clone https://github.com/oracle/dtrace-linux-kernel.git cd dtrace-linux-kernel/ git checkout origin/$DTrace_branch
The DTrace patches will be the most recent commits. Make sure you use all of them but nothing before that. Make sure the top patches are DTrace and the next one after them is the Linux baseline you want. E.g., the top commits here are DTrace, and the last one is Linux upstream.
git log -n $(($num_DTrace_patches + 1)) --oneline [...] 66f76fef08e3 dtrace: modular components and x86 support 25f11bb97fb9 dtrace: core and x86 3c5af76fa5fb waitfd: new syscall implementing waitpid() over fds e95e4350d02b kallsyms: introduce new /proc/kallmodsyms including builtin modules too 86e43efc644c ctf: generate CTF information for the kernel a3b22b9f11d9 (tag: v5.0-rc7) Linux 5.0-rc7
Generate the DTrace patches:
git format-patch -$num_DTrace_patches cd ..
First we untar the Linux base code. Earlier, fedpkg sources downloaded either a *.xz or *.gz file:
if [ -e kernel/linux-*.xz ]; then /usr/bin/xz -dc kernel/linux-*.tar.xz | /usr/bin/tar -xof - else tar xzf kernel/linux-*.tar.gz fi
Next, we turn this untarred directory into a git repo so patches can be applied.
cd linux-* git init git config user.email "kernel-team@fedoraproject.org" git config user.name "Fedora Kernel Team" git config gc.auto 0 git add . git commit -a -q -m "baseline"
if [ -e ../kernel/patch-*.xz ]; then xzcat ../kernel/patch-*.xz | patch -p1 -F1 -s git commit -a -m "Stable update" fi
for x in `awk '/^Patch/ {print $2}' ../kernel/kernel.spec`; do git am ../kernel/$x done
for x in ../dtrace-linux-kernel/00*.patch; do git am $x if [ $? -ne 0 ]; then echo DTrace patch did not apply cleanly exit 1 fi done
We modify the version tag in the Makefile:
sed -i.old \ 's/^EXTRAVERSION =.*$/EXTRAVERSION = -200.DTrace_'$fedora_release'.x86_64/' \ Makefile
We use the Fedora config file, though we modify it for DTrace. Specifically, we use CONFIG_UNWINDER_FRAME_POINTER instead of CONFIG_UNWINDER_ORC and add various DTrace options. You can use make listnewconfig before modifying the file to check which DTrace options must be defined and then after to make sure they were all set.
cp ../kernel/kernel-x86_64.config .config sed -i \ -e 's/# CONFIG_UNWINDER_FRAME_POINTER is not set/CONFIG_UNWINDER_FRAME_POINTER=y/' \ -e 's/CONFIG_UNWINDER_ORC=y/# CONFIG_UNWINDER_ORC is not set/' .config echo "CONFIG_DTRACE=y" >> .config echo "CONFIG_DT_CORE=m" >> .config echo "CONFIG_DT_FASTTRAP=m" >> .config echo "CONFIG_DT_PROFILE=m" >> .config echo "CONFIG_DT_SDT=m" >> .config echo "CONFIG_DT_SDT_PERF=y" >> .config echo "CONFIG_DT_FBT=m" >> .config echo "CONFIG_DT_SYSTRACE=m" >> .config echo "CONFIG_DT_DT_TEST=m" >> .config echo "CONFIG_DT_DT_PERF=m" >> .config echo "CONFIG_DT_DEBUG=y" >> .config echo "# CONFIG_DT_DEBUG_MUTEX is not set" >> .config
This step could take hours.
make olddefconfig make -j4 make -j4 ctf
Then install as root.
sudo make modules_install sudo make install sudo make INSTALL_HDR_PATH=/usr headers_install cd ..
Reboot to the new Fedora kernel.
sudo reboot
Next we want to build the DTrace userspace utility dtrace, which is the command-line tool you will probably want to use to trace kernel activity.
git clone https://github.com/oracle/dtrace-utils.git cd dtrace-utils
Next, we install build dependencies for this software. The DTrace packages are missing from Fedora repos, and we just built that software ourselves. So eliminate those packages from the .spec file before calling dnf builddep.
sed -i.old \ -e 's/-devel libdtrace-ctf-devel >= [0-9\.]*/-devel/' \ -e '/^BuildRequires: dtrace-kernel-headers = [0-9\.]*$/d' dtrace-utils.spec sudo dnf builddep -y dtrace-utils.spec
And now we build
make sudo make install cd ..
Now, we can use DTrace on Fedora! (Notice that it is installed at /usr/sbin/dtrace. Some other utility is at /usr/bin/dtrace.) You must be logged in as root to use DTrace. The first thing to do is to list the available probes:
# /usr/sbin/dtrace -l ID PROVIDER MODULE FUNCTION NAME 1 dtrace BEGIN 2 dtrace END 3 dtrace ERROR 5 fbt isofs isofs_hashi entry 6 fbt isofs isofs_hashi return 7 fbt isofs isofs_statfs entry 8 fbt isofs isofs_statfs return 9 fbt isofs isofs_iget5_test entry 10 fbt isofs isofs_iget5_test return [...thousands of lines omitted...]
Next, check out the Oracle DTrace Guide for simple examples and more information.
If you have any questions and for further updates on DTrace, please contact us at dtrace-devel at oss dot oracle dot com.
Elena Zannoni is a Senior Director in Oracle, responsible for Linux Toolchain and tracing development.
Previous Post
Next Post