1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
# Copyright 2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=8
inherit edo flag-o-matic linux-info systemd toolchain-funcs udev
DESCRIPTION="Dynamic BPF-based system-wide tracing tool"
HOMEPAGE="https://github.com/oracle/dtrace-utils https://wiki.gentoo.org/wiki/DTrace"
if [[ ${PV} == 9999 ]]; then
EGIT_BRANCH="devel"
EGIT_REPO_URI="https://github.com/oracle/dtrace-utils"
inherit git-r3
else
SRC_URI="https://github.com/oracle/dtrace-utils/archive/refs/tags/${PV}.tar.gz -> ${P}.tar.gz"
S="${WORKDIR}"/dtrace-utils-${PV}
KEYWORDS="-* ~amd64 ~arm64"
fi
LICENSE="UPL-1.0"
SLOT="0"
IUSE="systemd test-install"
# XXX: right now, we auto-adapt to whether multilibs are present:
# should we force them to be? how?
#
# TODO: can we make the wireshark dep conditional?
DEPEND="
dev-libs/elfutils
dev-libs/libbpf
dev-libs/libpfm:=
net-analyzer/wireshark[dumpcap]
net-libs/libpcap
>=sys-fs/fuse-3.2.0:3
>=sys-libs/binutils-libs-2.42:=
sys-libs/zlib
systemd? ( sys-apps/systemd )
"
RDEPEND="
${DEPEND}
!dev-debug/systemtap[dtrace-symlink(+)]
net-analyzer/wireshark
test-install? (
app-alternatives/bc
app-editors/vim-core
dev-build/make
dev-lang/perl
dev-util/perf
net-fs/nfs-utils
sys-apps/coreutils
sys-fs/xfsprogs
sys-process/time
virtual/jdk
virtual/perl-IO-Socket-IP
)
"
BDEPEND="
dev-build/make
sys-apps/gawk
sys-devel/bison
>=sys-devel/bpf-toolchain-14.1.0
sys-devel/flex
"
# This isn't yet optional, valgrind.h is included unconditionally
# https://github.com/oracle/dtrace-utils/issues/80
DEPEND+=" dev-debug/valgrind"
QA_PRESTRIPPED="
usr/.*/dtrace/testsuite/test/triggers/.*
"
QA_FLAGS_IGNORED="
usr/.*/dtrace/testsuite/test/triggers/.*
"
# TODO: report upstream (bug #938221) although it seems like it's
# not relevant given it's a BPF object.
QA_EXECSTACK="
usr/*/dtrace/bpf_dlib.*
"
pkg_pretend() {
# TODO: optional kernel patches
# Basics for debugging information, BPF
local CONFIG_CHECK="~BPF ~DEBUG_INFO_BTF ~KALLSYMS_ALL"
CONFIG_CHECK+=" ~CUSE"
# Tracing
CONFIG_CHECK+=" ~TRACING"
CONFIG_CHECK+=" ~UPROBES ~UPROBE_EVENTS"
CONFIG_CHECK+=" ~FTRACE ~FTRACE_SYSCALLS ~DYNAMIC_FTRACE ~FUNCTION_TRACER"
CONFIG_CHECK+=" ~FPROBE"
# DTrace can fallback to kprobes for fbt but people often want them off
# for security and newer kernels work fine with BPF for that, so
# let's omit it. kprobes are slower and scale poorly.
# https://gcc.gnu.org/PR84052
CONFIG_CHECK+=" !GCC_PLUGIN_RANDSTRUCT"
if use test-install ; then
# See test/modules
CONFIG_CHECK+=" ~EXT4_FS ~ISO9660_FS ~NFS_FS ~RDS ~TUN"
fi
check_extra_config
}
pkg_setup() {
eval unset ${!LC_*} LANG
}
src_configure() {
if tc-is-cross-compiler; then
die "DTrace does not yet support cross-compilation."
fi
tc-export CC
# https://github.com/oracle/dtrace-utils/issues/78
tc-enables-fortify-source && append-cppflags -U_FORTIFY_SOURCE
# lld does this by default, so fix that, although lld fails anyway...
# 'LIBDTRACE_1.0' to symbol 'dtrace_provider_modules' failed: symbol not defined
append-ldflags $(test-flags-CCLD -Wl,--undefined-version)
# mold and lld can't cope with some relocation types used, e.g.
# 'test-triggers--usdt-tst-forker-prov.o:(.SUNW_dof): unknown relocation: R_X86_64_GLOB_DAT'
tc-ld-force-bfd
# -fno-semantic-interposition seems to lead to a broken dtrace
# that can't actually obtain results from probes, even trivial examples
# just hang.
filter-flags -fno-semantic-interposition
# https://github.com/oracle/dtrace-utils/issues/86
filter-lto
local confargs=(
# TODO: Maybe we should set the UNPRIV_UID to something? -3 is a bit... kludgy
--prefix="${EPREFIX}"/usr
# See https://github.com/oracle/dtrace-utils/issues/106 for man8 suffix
--mandir="${EPREFIX}"/usr/share/man/man8
--docdir="${EPREFIX}"/usr/share/doc/${PF}
HAVE_LIBCTF=yes
HAVE_LIBSYSTEMD=$(usex systemd)
HAVE_BPFV3=yes
)
edo ./configure "${confargs[@]}"
}
src_compile() {
# -j1: https://github.com/oracle/dtrace-utils/issues/82
emake verbose=1 -j1 $(usev !test-install TRIGGERS='')
}
src_test() {
# Needs root and is also very time-consuming
:;
}
src_install() {
emake DESTDIR="${D}" -j1 install $(usev test-install install-test)
# Stripping the BPF libs breaks them
dostrip -x "/usr/$(get_libdir)"
# It's a binary (TODO: move it?)
docompress -x /usr/share/doc/${PF}/showUSDT
newinitd "${FILESDIR}"/dtprobed.init dtprobed
}
pkg_postinst() {
# We need a udev reload to pick up the CUSE device node rules.
udev_reload
if [[ -n ${REPLACING_VERSIONS} ]]; then
# TODO: Make this more intelligent wrt comparison
# One option for this is to detect when it's needed (DOF stash layout changes)
# and then e.g. sleep and restart for the user.
if systemd_is_booted ; then
einfo "Restart the DTrace 'dtprobed' service after upgrades once all dtraces are stopped with:"
einfo " systemctl try-restart dtprobed"
else
einfo "Restart the DTrace 'dtprobed' service after upgrades once all dtraces are stopped with:"
einfo " /etc/init.d/dtprobed restart"
fi
else
einfo "See https://wiki.gentoo.org/wiki/DTrace for getting started."
# We can't do magic for people with ROOT=.
if [[ -n ${ROOT} ]] ; then
einfo "Enable and start the DTrace 'dtprobed' service for systemd with:"
einfo " systemctl enable --now dtprobed"
einfo
einfo "Enable and start the DTrace 'dtprobed' service for OpenRC with:"
einfo " rc-update add dtprobed"
einfo " /etc/init.d/dtprobed start"
return
fi
# For first installs, we enable the service and start it.
#
# This is unusual, but the behaviour without dtprobed running
# is untested/unsupported. It's not a network service, it
# has no configuration, reads a single device node, and
# does all parsing within a seccomp jail. It also leads
# to hard-to-diagnose issues because USDT probes won't
# be registered and an application might have already
# started up which needs to be traced.
if systemd_is_booted ; then
ebegin "Enabling & starting DTrace 'dtprobed' service"
systemctl enable --now dtprobed
eend $?
else
ebegin "Enabling DTrace 'dtprobed' service"
rc-update add dtprobed
eend $?
ebegin "Starting DTrace 'dtprobed' service"
rc-service start dtprobed
eend $?
fi
fi
}
pkg_postrm() {
udev_reload
}
|