在不使用调试参数启动JVM的情况下调试Java应用程序


95

通常,要将调试器附加到正在运行的jvm,您需要使用以下参数启动jvm:

> java -Xdebug -Xrunjdwp:transport=dt_socket,address=1000,server=y,suspend=n

现在,如果我要调试不是在调试模式下启动的进程,该怎么办?

当生产系统(即在没有调试args的情况下启动)出现“随机”(我宽松地使用术语)错误时,就会出现这种情况。因此,我无法使用适当的参数重新启动jvm,因为没人知道如何再次再现该错误。在这种情况下是否不可能附加到JVM?

只是为了澄清,除非将它们以调试方式启动,否则无法使用jdb之类的工具来附加至已在运行的JVM。

从JVM手册页

使用jdb的另一种方法是将其附加到已经运行的Java VM。使用jdb调试的VM必须使用以下选项启动:


Answers:


47

您可能可以使用jsadebugdJDK)将调试服务器附加到进程(在Windows上可通过Windows的调试工具获得)。它被标记为实验性的,因此您可能需要首先在测试机上进行尝试。

用法:

jsadebugd <pid>
jdb -connect sun.jvm.hotspot.jdi.SADebugServerAttachingConnector:debugServerName=localhost

可以使用找到带有arg的连接器名称jdb -listconnectors


1
我正在使用linux,所以这似乎是最有前途的解决方案
hhafez

有什么经验可以分享吗?
托尔比约恩Ravn的安徒生

1
我的经验是,它在我需要的时间运行良好,同时默认情况下,该软件的所有出厂实例都未配置为使用jvm调试选项启动,因此我们可以使用受支持的方法。
hhafez 2012年

在Java 11上jsadebugd被替换为jhsdb debugd。这样就变成了jhsdb debugd --pid <pid>。见谈话呈现jhsdb的幻灯片,并为jhsdb的文档
Delthas

它似乎SADebugServerAttachingConnector也已从中删除jdb,我认为替换应该是jhsdb hsdb/ jhsdb clhsdb。我找不到有关要提供什么参数的文档jhsdb clhsdb
Delthas

32

只是为了澄清,除非使用调试模式启动jdb之类的工具,否则无法将它们附加到已运行的JVM>>

在苏联俄罗斯的消息中读到你

jdb -connect sun.jvm.hotspot.jdi.SAPIDAttachingConnector:pid=9426

1
好,那是“受支持的”答案,但实验性的答案是我接受的答案,因此可以在不受支持的方式下完成
hhafez 2010年

7

VisualVM不是调试器,但是您可以从中获得线程转储和堆转储,这对于诊断某些问题很有用。最有用的功能需要JVM 5或6。


链接不起作用。...也许您将https:// ...之前的http://删除了,但我还没有足够的声誉
Newtopian

+1 VisualVM看起来真的很有趣。顺便说一句:链接现已修复。
sleske 2010年

5

使用jstack(在发生死锁时很有用)或btrace VisualVM插件也可以解决问题


-5

您总是可以使用jdb并手动调试:P


2
我一直以为,除非启动了jvm以允许调试连接,否则无法使用jdb附加到jvm。
哈菲兹

据我了解,您提到的选项是“启用”“ java”命令(VM)的远程调试,但是您也可以改用jdb命令。因此,代替java MyApp,您会像jdb MyApp一样(并进行交互式调试,设置断点,运行,停止,监视等)
OscarRyz

1
根据jdb手册页,我认为这是不正确的-引用另一种使用jdb的方法是将其附加到已经运行的Java VM。使用jdb调试的VM必须使用以下选项启动:-结束引用
hhafez

使用正确的连接器(目前不支持),jdb可以连接到正在运行的进程。
托尔比约恩Ravn的安德森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.