不使用调试参数启动JVM来调试Java应用程序

101

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

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

如果我想要调试一个没有在调试模式下启动的进程,我该怎么办?

这种情况会发生在生产系统(即在没有调试参数的情况下启动)出现“随机”错误(我松散使用此术语)。因此,我无法使用适当的参数重新启动jvm,因为没有人知道如何再次重现该错误。在这种情况下,无法连接到JVM吗?

只是为了澄清,除非已经以调试模式启动,否则无法像jdb这样的工具连接到已经运行的JVM。

来自JVM man页面:

 

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


5个回答

51
你可以使用jsadebugd(JDK)将调试服务器附加到进程上(在Windows上可用,需要安装Debugging Tools for Windows)。它被标记为实验性功能,所以建议先在测试机上尝试一下。
使用方法:
jsadebugd <pid>
jdb -connect sun.jvm.hotspot.jdi.SADebugServerAttachingConnector:debugServerName=localhost

可以使用jdb -listconnectors命令查找带有参数的连接器名称。


1
我正在使用Linux,因此这似乎是最有前途的解决方案。 - hhafez
有什么相关经验可以分享的吗? - Thorbjørn Ravn Andersen
1
我的经验是,在我需要它的时候,它运行良好。与此同时,软件工厂中的所有实例默认情况下都没有配置为使用jvm调试选项启动,因此我们可以使用支持的方法。 - hhafez
在Java 11中,jsadebugdjhsdb debugd所取代。因此,命令变为jhsdb debugd --pid <pid>。请参阅jhsdb演示文稿jhsdb文档 - Delthas
似乎SADebugServerAttachingConnector也从jdb中删除了,我认为替代品应该是jhsdb hsdb / jhsdb clhsdb。我找不到任何关于如何给jhsdb clhsdb传递参数的文档。 - Delthas

33

仅想澄清一点,除非已经以调试模式启动了 JVM,否则无法使用类似 jdb 的工具连接到已经运行的 JVM。

在苏联俄罗斯,源代码阅读你。

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

1
那是“支持的”答案,但我接受了实验性的答案,因此它可以用不支持的方式完成。 - hhafez

7

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


链接不起作用....也许你应该在 https:// 前面删除 http://... 我本来想这样做的,但我还没有足够的声望。 - Newtopian
+1 VisualVM 看起来非常有趣。顺便说一下:链接现在已经修复。 - sleske

6

使用jstack(在死锁情况下很有用)或btrace VisualVM插件也可以解决问题。


-5

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


3
我一直认为,除非使用允许调试连接的参数启动jvm,否则无法使用jdb连接jvm。我错了吗? - hhafez
据我所知,你提到的选项是为了“启用”你的“java”命令(虚拟机)的远程调试。但你也可以使用jdb命令。因此,你可以像这样输入jdb MyApp(并进行交互式调试、设置断点、运行、停止、监视等等)。 - OscarRyz
1
我认为根据jdb手册,这不正确。-- 开始引用 使用jdb的另一种方式是将其附加到已经运行的Java VM上。要使用jdb调试的VM必须使用以下选项启动: -- 结束引用 - hhafez
使用正确的连接器(目前不支持)jdb可以连接到正在运行的进程。 - Thorbjørn Ravn Andersen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接