简体   繁体   English

有什么办法可以打印外部Java程序的堆栈跟踪

[英]Is there any way to print the stack trace of an external java program

I want to write a java program A that runs another program B and prints the stack trace of B. 我想编写一个运行另一个程序B并打印B的堆栈跟踪的Java程序A。

I know that I can print the stack trace of A with the below code 我知道我可以使用以下代码打印A的堆栈跟踪

for( i = 0; i < Thread.currentThread().getStackTrace().length; i++ ) {
            System.out.println(Thread.currentThread().getStackTrace()[i].
            getMethodName());
}

But is it possible to print the stack trace of program B if i am executing it like this from A 但是如果我从A执行这样的程序,是否可以打印程序B的堆栈跟踪

Process pr = Runtime.getRuntime().exec("javac B.java");
pr.waitFor();
pr = Runtime.getRuntime().exec("java B").printStackTrace();
 pr.waitFor();

SHORT ANSWER: 简短答案:

NO 没有

LONG ANSWER: 长答案:

Program A only execute whatever program B does. 程序A仅执行程序B所做的任何事情。 it doesn't know how it does things internally. 它不知道它如何在内部做事。 Only thing that A can know about B is whatever the B 's output stream and error stream can produce. A唯一了解B的东西就是Boutput streamerror stream可以产生什么。 if you want to know a bit more about it (eg how much memory B uses and etc), you can try to find it's PID and ask OS about some information 如果您想了解更多(例如B使用了多少内存等),可以尝试找到它的PID并询问OS一些信息

The JDK contains the commandline tool jstack : JDK包含命令行工具jstack

Prints Java thread stack traces for a Java process, core file, or remote debug server. 打印Java进程,核心文件或远程调试服务器的Java线程堆栈跟踪。 This command is experimental and unsupported. 此命令是实验性的,不受支持。

When you call jstack you need to provide the process id of the Java process for which you want to get a stracktrace. 调用jstack时,需要提供要获取stracktrace的Java进程的进程ID

You might want to experiment if you can run jstack from your master Java program. 如果可以从主Java程序运行jstack,则可能要尝试一下。

Yes. 是。 A JVM process can be accessed in different manners by another (Java) program. 另一个(Java)程序可以以不同的方式访问JVM进程。

A very generic way of accessing another Java program is by writing a Java agent / using the Instrumentation API . 访问另一个Java程序的一种非常通用的方法是通过编写Java代理 /使用Instrumentation API Using this API, it is possible to change a running Java program by modifying the executed code of this program. 使用此API,可以通过修改该程序的已执行代码来更改正在运行的Java程序。 For example, you can redefine existing methods to include additional instructions that expose the stack trace any time a given execution point is reached. 例如,您可以重新定义现有方法以包括其他指令,这些指令在到达给定执行点时会公开堆栈跟踪。 Alternatively, you could simply instruct to print the stack trace directly. 或者,您可以简单地指示直接打印堆栈跟踪。 This is also how the mentioned JStack application works . 这也是上述JStack应用程序的工作方式

A simpler alternative would be to expose a JMX bean from the running application that allows to trigger the printing of the stack trace. 一个更简单的选择是从正在运行的应用程序中暴露一个JMX bean ,该JMX bean允许触发堆栈跟踪的打印。

Both access modes does however require some tricks for accessing the other VM's process ID what is not trivial in Java . 但是,这两种访问模式都需要一些技巧来访问其他VM的进程ID, 这在Java中并不简单

You could look into writing an Agent. 您可以考虑编写代理。 There is a tutorial here . 有一个教程在这里 Agents let you insert code into any running java program and see what is going on. 代理使您可以将代码插入任何正在运行的Java程序中,并查看发生了什么。 That is how remote debugging works. 这就是远程调试的工作方式。 As an example you start JBoss or Tomcat with -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n to insert the debugging agent. 例如,您使用-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n启动JBoss或Tomcat来插入调试代理。 You can do the same by writing an agent and then inserting your agent into a running process at startup time. 您可以通过编写代理,然后在启动时将代理插入正在运行的进程中来执行相同的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM