如何将调试器附加到与Commons Daemon Service Runner一起运行的Java程序?

问题描述:

我想对运行在Windows上的Java程序进行一些调试:回溯,打印一些变量,设置断点,通过关键函数单步执行。如何将调试器附加到与Commons Daemon Service Runner一起运行的Java程序?

我尝试的第一件事是jdb -attach 5312。这失败了“shmemBase_attach失败:系统找不到指定的文件”。我发现了一些关于该错误消息的relatedquestions,但他们似乎在讨论涉及单独主机上调试器和目标的更复杂情况。

我正在做的是一个本地进程附加,所以我认为它应该更容易。但有些事情会让事情变得更加困难。

目标进程不作为java -jar foo.jar或任何类似的东西正常运行。这是一个包装java代码的特定于应用程序的EXE文件。它在进程列表中标识为“Commons Daemon Service Runner”并查看其中的字符串,似乎是the prunsrv program from Apache Commons Daemon

Process Explorer告诉我没有命令行参数,并且该进程是services.exe的子进程。我有能力从Windows服务启动和停止它,但我不知道如何执行其他任何操作。

jps命令不显示此过程,但我知道它是一个Java程序...轻轻包装。有什么方法可以调试它吗?

尝试_JAVA_OPTIONS变量设置为这样的事情:

_JAVA_OPTIONS "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=32887"

此变量应该由JVM而它开始有所回升。

然后,您可以通过调用

jdb -attach 32887

,其中32887是由调试器使用的任意端口号尝试连接到此JVM(编号必须一致)。

更新:

您可以使用连接的不同方式。随你便。我给你的只是许多不同设置方式的一个例子。看看此处了解详情:

https://docs.oracle.com/javase/8/docs/technotes/guides/jpda/conninv.html

您还可以使用VisualVM的。在这种情况下,您需要让运行VisualVM的用户看到JVM进程。

+0

我必须改变程序的运行方式以使其可调试?我必须使用远程调试协议来调试本地进程?这对我来说似乎很奇怪,习惯于在unix上使用gdb,我可以通过PID附加到任何进程,而不需要任何合作(如果我是所有者或root)。我会尝试一下... –

+0

它接受来自所有人的远程连接,使用[无论身份验证](http://blog.ioactive.com/2014/04/hacking-java-debug-wire-protocol-or- how.html)!这不可用。 –

+1

查看了几个选项后,我发现了这个组合:'jdb -connector com.sun.jdi.SocketListen:port = 12345',然后使用'prunmgr'配置目标服务,并添加选项'-agentlib:jdwp = transport = dt_socket,地址127.0.0.1 =:12345,服务器= N,暂停= y'。我认为让世界未经验证的访问权作为调试对象连接到我的调试器比其他方式更加愚蠢。仍然感到惊讶的是没有简单的'PTRACE_ATTACH'风格的界面。 –