如何判断OpenJDK是否安装了调试符号

How to Determine Whether OpenJDK Installed with Debugging Symbols

我为 RedHat Linux Server 8+ 中的架构安装了相同 major/minor 版本的 openjdk-developenjdk-devel-debuginfo。我想确保 OpenJDK 运行时具有用于调试的符号。安装后,我运行如下:

[root@localhost bin]# objdump --syms /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el8_1.x86_64/jre/bin/java

/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el8_1.x86_64/jre/bin/java:     file format elf64-x86-64

SYMBOL TABLE:
0000000000000270 l    d  .interp    0000000000000000              .interp
0000000000000290 l    d  .note.gnu.property 0000000000000000              .note.gnu.property
00000000000002b0 l    d  .note.ABI-tag  0000000000000000              .note.ABI-tag
00000000000002d0 l    d  .note.gnu.build-id 0000000000000000              .note.gnu.build-id
00000000000002f8 l    d  .hash  0000000000000000              .hash
0000000000000348 l    d  .gnu.hash  0000000000000000              .gnu.hash
0000000000000370 l    d  .dynsym    0000000000000000              .dynsym
....
....
....

[root@localhost etc]# file /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el8_1.x86_64/jre/bin/java
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el8_1.x86_64/jre/bin/java: 
ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=613871d1514ba05fa2914c22c10f1dfe01d3d2e8, not stripped


[root@localhost bin]# objdump --syms /usr/lib/debug/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el8_1.x86_64/bin/java-1.8.0.242.b08-0.el8_1.x86_64.debug

/usr/lib/debug/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el8_1.x86_64/bin/java-1.8.0.242.b08-0.el8_1.x86_64.debug:     file format elf64-x86-64

SYMBOL TABLE:
no symbols

[root@localhost bin]# file /usr/lib/debug/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el8_1.x86_64/bin/java-1.8.0.242.b08-0.el8_1.x86_64.debug
/usr/lib/debug/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-0.el8_1.x86_64/bin/java-1.8.0.242.b08-0.el8_1.x86_64.debug: 
ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter [=10=]4, for GNU/Linux 3.2.0, BuildID[sha1]=613871d1514ba05fa2914c22c10f1dfe01d3d2e8, with debug_info, not stripped

正如上面所暗示的,我看到 objdump for java 打印出某种符号 table,但我读到过也应该寻找 .debug* 在输出中,我在 SYMBOL TABLE 部分的剩余部分中没有看到(为简洁起见,上面的输出省略了几十行)。

我看到 /usr/lib/debug/..../java...debugfilewith debug_info,但我需要确认 Java 安装确实有符号。

java 可执行文件只是一个 simple launcher。您不会在那里找到 JVM 符号。

要查看 JVM 是否有调试符号,请改为检查 libjvm.so

nm /usr/lib/jvm/jre/lib/amd64/server/libjvm.so

My ultimate goal is to load a malloc profiler alongside my server and try to trace the native memory allocations. In this case, if the calls are traced back to JVM, I need to know which method is getting called.

好吧,如果你从 这个 问题开始,你就不会落入 XY problem 陷阱。

即使使用 JVM 调试符号,本机内存分析器(例如 jemalloc)也无法显示 Java 方法。他们根本不知道如何展开 Java 堆栈,因此跟踪可能会在某些随机的十六进制地址处中断,例如 .

我建议尝试 async-profiler to profile malloc, mprotect and mmap calls. This tool can show mixed Java+native stack traces. Here is an example of using async-profiler to profile native allocations. This video 还演示了 async-profiler 如何帮助查找本机内存泄漏。