2011-03-11 42 views
3

我们需要调试一个Java应用程序,它随机做它不应该做的事情。如何在调用特定Java方法时转储堆栈跟踪?

要了解问题的根源,我们需要得到一个每当一个特定的方法被调用堆栈跟踪。这听起来很简单(在此特定方法中添加Thread.dumpStack()),但是这是来自JDK的代码类,因此我们并不真正想要混淆它(即使我们确实可以)。

有谁知道,如果我们可以实现JVM中的某种“听众”的,将在一个特定的方法被调用检测并转储堆栈跟踪?

这是一个生产系统,因此,如果解决方案是我们需要有一些对性能的影响非常有限调试器。

谢谢您的输入。

+1

最简单的解决方案是修改提到的jdk类..我认为它不会造成问题.. – 2011-03-11 13:21:50

+1

使用AOP可以将附加的运行时代码附加到特定的方法。 – anubhava 2011-03-11 13:30:20

回答

0

取决于有多少不同位置的方法是从所谓的,你可以把一个包装周围并从包装中做一个堆栈转储。

0

我的东西为简单起见,做的是以下行添加到我的代码

log.info("Method called", new Throwable("HERE")); 
0

而是有问题的类的实例,使用的java.lang.reflect.Proxy一个实例。这允许您在将所有方法调用转发给实例之前拦截所有方法调用并执行某些操作。

我觉得这是至少1 AOP框架的心脏。

1

“有谁知道,如果我们可以实现某种‘在JVM监听器’,将检测当特定方法被调用和转储堆栈跟踪?

这是一个生产系统,因此,如果该解决方案是一个调试器,我们需要对性能影响非常有限的东西。“

这些要求是矛盾的。无论你如何做,倾倒堆栈都很昂贵。海事组织,你真正需要做的是建立一个测试服务器并在那里运行你的调查。

FWIW,最简单和可能最便宜的方式做这样的事情是插入其中的一个作为方法的第一个语句:

log.info("Method called", new Throwable()); 

    new Throwable("method called").printStackTrace(System.out); 
0

我用这目的是java instrumentation api

与Java仪表API,您可以在运行时修改任何类的字节码,你可以添加一些代码(如AOP)。我的github上提供了一个使用javassist在运行时测试java类和方法的示例。

https://github.com/kreyssel/maven-examples/tree/master/javaagent

你可以简单地修改LoggerAgent.java和删除记录语句并添加Thread.dumpStack()

你在生产运行时更改的唯一一件事就是代理jar添加到Java命令行。

-javaagent:jarpath[=options] 

另一篇博文可以阅读here

2

使用Byteman。它可以很容易地将跟踪代码注入正在运行的服务器。我们的支持团队喜欢它。 http://www.jboss.org/byteman