如何调试Java应用程序中的静默故障?

如何调试Java应用程序中的静默故障?,java,eclipse,debugging,remote-debugging,Java,Eclipse,Debugging,Remote Debugging,我正在尝试调试Java应用程序中的一个问题,该问题不会抛出错误、异常,甚至不会使应用程序崩溃(似乎故障发生在单独的线程中) 问题似乎出在对库函数的调用中(如果这很重要的话,它是JAXBContext.newInstance(String))。程序将在通话前到达线路,但不会在通话后到达线路。我的catch块没有输入,程序只是继续运行 问题发生在尝试对通过Struts传入的web请求呈现XML响应时。请求已被处理,代码应封送响应对象。客户机立即得到响应(因此代码似乎不会挂起在循环中),但它只是空的

我正在尝试调试Java应用程序中的一个问题,该问题不会抛出错误、异常,甚至不会使应用程序崩溃(似乎故障发生在单独的线程中)

问题似乎出在对库函数的调用中(如果这很重要的话,它是
JAXBContext.newInstance(String)
)。程序将在通话前到达线路,但不会在通话后到达线路。我的
catch
块没有输入,程序只是继续运行

问题发生在尝试对通过Struts传入的web请求呈现XML响应时。请求已被处理,代码应封送响应对象。客户机立即得到响应(因此代码似乎不会挂起在循环中),但它只是空的

我在有问题的行之前设置了一个断点,但调试器只是在它上面运行,我不知道为什么

我使用的是eclipse,应用程序在一个OSGi容器(ApacheFelix)中运行,该容器由
-Xdebug-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y
启动。然后,我在Eclipse中使用“远程Java应用程序”的调试设置来连接调试器


解决这样一个问题的技术是什么?

可能在调用内部发生了Infite循环,这就是为什么您没有进一步了解的原因-但这可能不会导致崩溃(除非每个循环中都使用了内存)。

如果您确定问题在该方法中的某个地方,您可以尝试查看

编辑:

好吧,如果它变得非常糟糕,您可以使用调试工具构建自己的私有副本。我希望您不必求助于此。

您可以尝试获取一个-它将告诉您是否有任何方法正在阻塞(例如,等待输入)。[编辑:重新阅读您的原始问题,获取线程转储可能不会有帮助,因为看起来似乎没有任何东西实际阻塞。但我将它留在这里,因为我发现它在许多其他情况下都很有用!]


如果您认为错误发生在另一个线程中,您也可以设置一个来尝试并捕获它。

这可能是一个明显的问题,但您确定正在捕获Throwable吗?未经检查的异常可能很容易导致相关线程死亡(假设调用堆栈中您上面的人也没有捕获到它)

由于您正在使用调试参数在启动时挂起VM,因此我假定您已确认调试器已正确连接。您说调试器跳过调用的事实是非常可疑的。您能在此应用程序中命中任何断点吗?这个班怎么样?这条线怎么样

在没有调试器的情况下,您是如何缩小问题范围的?打印/调试到文件

你能粘贴有问题的方法的代码片段吗

您可以通过在问题发生之前创建第二个线程并将其连接到您认为正在消亡的线程来确认线程正在消亡的理论。然后第二个线程的run()方法将在有问题的线程退出时被调用,您会知道它已死亡(但仍然不知道原因)


为了回答您的一般问题,当我在Java应用程序中遇到无法在调试器中重现的错误时(由于各种原因,这种情况时有发生),我会使用sysout printlns或输出到文件来增量修改代码。如有必要,我还可以修改我的代码正在调用的代码。如果您没有所调用代码的源代码,您可以尝试多种BCI框架中的一种,将您的字节码注入到所讨论的方法中。这是一个乏味的过程,但只是偶尔发生。

你确定IDE指向的源代码与在服务器上形成二进制文件的源代码相同吗?是的,都在我的本地机器上,OSGi容器直接从我的IDE的输出目录运行代码。我不熟悉OSGi容器,是吗,像JBoss一样,是否将已部署的二进制文件移动到另一个目录?我会尝试对您的代码、System.out.println或类似的东西进行更改,然后确保它得到执行以确认这一点。我通常发现调试器跳过代码行表明IDE和服务器彼此不同步。是的,这听起来似乎有道理,但我不知道它们应该如何不同步。源代码只有一个副本,运行的二进制文件是IDE生成的。如果这是问题所在,那么您认为正在运行的二进制文件不是实际运行的二进制文件。服务器通常会将归档文件解包到另一个目录。对于JBoss,这是非常可靠的,但是在一个不断部署的开发环境中,我看到热部署停止工作了——JBoss停止解压新的归档文件,服务器继续在旧的二进制文件上运行。我想你也会遇到类似的问题。在JBoss上,您可以通过删除归档文件、跳转服务器然后重新部署来解决这个问题。对OSGI不确定,但我会试试。不,我不这么认为。错误发生在处理通过Struts传入的web请求时,客户机立即得到一个结果(为空)。因此,应用程序不会挂起,它会跳出处理过程。好吧,我会尝试一下,但如果没有调试器介入,我可能会遇到困难。阻止:不,这次不是。UncaughtExceptionHandler是个好主意,不幸的是,它也没有捕获任何东西。+1不是所有的可丢弃文件都是异常,我们通常捕获异常;这很容易从我们身边溜走。