如何确定是否已安装带有调试符号的OpenJDK

15 浏览
0 Comments

如何确定是否已安装带有调试符号的OpenJDK

我在RedHat Linux Server 8+上安装了相同主/次版本的openjdk-developenjdk-devel-debuginfo。我想确保OpenJDK运行时具有用于调试的符号。安装后,我运行了以下命令:\n

[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:     文件格式 elf64-x86-64
符号表:
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位 LSB共享对象,x86-64,版本1(SYSV),动态链接,解释器/lib64/ld-linux-x86-64.so.2,适用于GNU/Linux 3.2.0,BuildID[sha1]=613871d1514ba05fa2914c22c10f1dfe01d3d2e8,未剥离
[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:     文件格式 elf64-x86-64
符号表:
没有符号
[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位 LSB共享对象,x86-64,版本1(SYSV),动态链接,解释器\004,适用于GNU/Linux 3.2.0,BuildID[sha1]=613871d1514ba05fa2914c22c10f1dfe01d3d2e8,带有debug_info,未剥离

\n如上所述,我看到javaobjdump打印出了某种符号表,但我读到输出中应该还要查找.debug*,而我在SYMBOL TABLE部分的剩余部分(为简洁起见省略了几十行)中没有看到。我看到/usr/lib/debug/..../java...debugfile带有debug_info,但我需要确认Java安装是否有符号。

0
0 Comments

如何确定是否使用调试符号安装了OpenJDK

Java可执行文件只是一个简单的启动器。您在其中找不到JVM符号。

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

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

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

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

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

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

谢谢您分享这个。不幸的是,我们的环境需要批准这个新的分析器,这可能是一个漫长的过程(尽管尝试过后,我认为我会努力使用它)。我们有没有其他项目使用async-profiler的参考?我将尝试观看/阅读一些相关资源,以更好地了解它的能力,但这看起来非常强大,所以谢谢您分享这个。

至于您关于Java方法的评论,您是正确的。我希望我们可以看到本机调用被调用的位置以确定罪魁祸首。一旦找到了这个本机方法,我们可能可以使用它来重复使用jstack来转储Java堆栈,就像在这篇文章中演示的那样。但我想您的async-profile实际上是侵入性的。

如果调试信息在/usr/lib/debug中,这个nm命令就不相关了。我没有使用openjdk-devel-debuginfo,但是openjdk-8-dbg安装到/usr/lib/debug中:

dpkg -L openjdk-8-dbg输出类似于/usr/lib/debug/.build-id/03/17f517a518dee47febb310f62e609737e1dc63.debug的条目。

是的。我通常使用gdb来检查符号的存在-它既适用于嵌入的symtab,也适用于外部debuginfo。

0