如何确定是否已安装带有调试符号的OpenJDK
如何确定是否已安装带有调试符号的OpenJDK
我在RedHat Linux Server 8+上安装了相同主/次版本的openjdk-devel
和openjdk-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如上所述,我看到java
的objdump
打印出了某种符号表,但我读到输出中应该还要查找.debug*
,而我在SYMBOL TABLE
部分的剩余部分(为简洁起见省略了几十行)中没有看到。我看到/usr/lib/debug/..../java...debug
的file
说带有debug_info
,但我需要确认Java安装是否有符号。
如何确定是否使用调试符号安装了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。