How to enable UDST in java?

764 Views Asked by At

I have created a new GCP instance and used defaulted Debian system. Then, I use apt to install the default-java package, but they're no USDT in libjvm.so. I don't know why?

information:

$ uname -a
Linux bpf-test1 4.19.0-18-cloud-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64 GNU/Linux

$ whereis java
java: /usr/share/java /usr/lib/jvm/java-11-openjdk-amd64/bin/java /usr/share/man/man1/java.1.gz

$ java -version
openjdk version "11.0.13" 2021-10-19
OpenJDK Runtime Environment (build 11.0.13+8-post-Debian-1deb10u1)
OpenJDK 64-Bit Server VM (build 11.0.13+8-post-Debian-1deb10u1, mixed mode, sharing)

$ readelf -n $JAVA_HOME/lib/server/libjvm.so
Displaying notes found in: .note.gnu.build-id
  Owner                 Data size   Description
  GNU                  0x00000014   NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: 5a4af8c3edd4e64e7fd351d2e18dce9947db4d22

$ ps -ef|grep java
xxx   23001 22956  1 13:08 pts/0    00:00:30 java -jar xxx.jar
xxx   23157 23042  0 13:44 pts/1    00:00:00 grep java

$ sudo javathreads-bpfcc  23001
Error attaching USDT probes: the specified pid might not contain the
given language's runtime, or the runtime was not built with the required
USDT probes. Look for a configure flag similar to --with-dtrace or
--enable-dtrace. To check which probes are present in the process, use the
tplist tool.

$ cat /boot/config-$(uname -r) | grep BPF
CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_SYSCALL=y
# CONFIG_BPF_JIT_ALWAYS_ON is not set
CONFIG_IPV6_SEG6_BPF=y
CONFIG_NETFILTER_XT_MATCH_BPF=m
# CONFIG_BPFILTER is not set
CONFIG_NET_CLS_BPF=m
CONFIG_NET_ACT_BPF=m
CONFIG_BPF_JIT=y
CONFIG_BPF_STREAM_PARSER=y
CONFIG_LWTUNNEL_BPF=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_BPF_EVENTS=y
# CONFIG_BPF_KPROBE_OVERRIDE is not set
# CONFIG_TEST_BPF is not set

$ cat /boot/config-$(uname -r) | grep TRACEPOINT
CONFIG_TRACEPOINTS=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
# CONFIG_TRACEPOINT_BENCHMARK is not set
1

There are 1 best solutions below

0
Slava Bacherikov On

Kernel has nothing to do USDT probes, since these have to be in the libjvm.so. Unfortunately you didn't specify your debian version, and as far as I know there is no default-java package in the debian (although there is default-[jdk|jre] package). From your java version I could guess that you using this package. Anyway, in order to have USDT probes openjdk has to be complied with --enable-dtrace flag, which isn't used in that package. When openjdk is compiled with this flag you'll have this:

readelf -n /path/to/openjdk/lib/server/libjvm.so

  stapsdt              0x0000002f       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__yield
    Location: 0x000000000098745b, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments: 
  stapsdt              0x0000003d       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__sleep__begin
    Location: 0x000000000098ff64, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments: -8@%r12
  stapsdt              0x00000039       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__sleep__end
    Location: 0x000000000098ffa3, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments: -4@$0
  stapsdt              0x00000039       NT_STAPSDT (SystemTap probe descriptors)
    Provider: hotspot
    Name: thread__sleep__end
    Location: 0x0000000000990100, Base: 0x000000000107e7f4, Semaphore: 0x0000000000000000
    Arguments: -4@$1

So your options is either, build openjdk yourself and ensure to use --enable-dtrace flag (this would require systemtap as dependency) or use package that has been provided by someone else. As for prebuild package, I can recommend this prebuild package. Unfortunately, there is no *.deb package there (there is only .tar.gz), but I know for sure that it has been built with --enable-dtrace. I'm recommending this because I know that certain distros using these packages (for example Gentoo).