首页 > 解决方案 > 如何判断 OpenJDK 是否安装了调试符号

问题描述

我为 RedHat Linux Server 8+ 中的架构安装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 \004, for GNU/Linux 3.2.0, BuildID[sha1]=613871d1514ba05fa2914c22c10f1dfe01d3d2e8, with debug_info, not stripped

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

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

标签: javadebuggingjvm

解决方案


java可执行文件只是一个简单的启动器。你不会在那里找到 JVM 符号。

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

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

我的最终目标是在我的服务器旁边加载一个 malloc 分析器并尝试跟踪本机内存分配。在这种情况下,如果调用追溯到 JVM,我需要知道调用了哪个方法。

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

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

我建议尝试使用async-profiler进行profilemalloc和调用。这个工具可以显示混合的 Java+native 堆栈跟踪。这是一个使用 async-profiler 来分析本机分配的示例。该视频还演示了 async-profiler 如何帮助查找本机内存泄漏。mprotectmmap


推荐阅读