因此,我正在如下启动Java程序

java -agentlib:jdwp=transport=dt_socket,address=8000, server=y,suspend=n  MyClass

然后,我如下所示手动附加调试器
jdb -attach 8000

我想知道是否仍然需要设置jdb,以便在发生未捕获的异常的情况下自动将jdb附加到正在运行的进程中(仅)?

原因是我想避免调试器的开销,直到出现未捕获的异常。但是我现在面临的问题是,如果未附加调试器,则一旦出现未捕获的异常,JVM就会中止。

编辑:

从Oracle docs来看,以下命令似乎可以满足我的需要,但对于Windows计算机而言。
java -agentlib:jdwp=transport=dt_shmem,server=y,onuncaught=y,launch=d:\bin\debugstub.exe MyClass

有人知道Linux的等效版本吗?我已经尝试了以下命令。
java -agentlib:jdwp=transport=dt_socket,address=8000,server=y,onuncaught=y,suspend=n,launch=jdb MyClass

调试器似乎已连接,但立即引发IOError。
Initializing jdb ...

java.io.IOException: Input/output error
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:272)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:273)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
at java.io.BufferedReader.readLine(BufferedReader.java:382)
at com.sun.tools.example.debug.tty.TTY.<init>(TTY.java:751)
at com.sun.tools.example.debug.tty.TTY.main(TTY.java:1067)

最佳答案

确实要及时附加调试器确实会使用您建议的选项(launchonuncaught)。但是launch选项在Linux上还需要更多:



在您的情况下,由于启动了上下文,jdb无法打开它所需的终端TTY。根据运行它的环境,您将需要构造一个脚本来在新窗口中启动jdb或附加它到pseduo-tty,以便它可以正常运行。

我通过创建一个使用screen启动终端的脚本进行了测试

#!/bin/bash
# according to launch option doc, the first argument is the transport and
# the second argument will be the address
#
screen -dm -L -S autojdb jdb -attach $2

该脚本将在一个分离的屏幕中启动jdb,并为屏幕autojdb命名 session 。您可以使用screen -ls查看屏幕列表。当您要访问已启动的调试器时,请使用screen -r autojdb。确保将脚本放在您的路径中,或在启动选项中提供完整路径(以下为/home/me/screenjdb):
java -agentlib:jdwp=transport=dt_socket,address=8000,server=y,onuncaught=y,suspend=n,launch=/home/me/screenjdb MyClass

在我的脚本中,我还将-L传递给了记录 session 的屏幕。这将记录 session ,但也可以让您查看由于某种原因附加失败时发生的任何错误。

关于java - 在未捕获的异常上附加jdb,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28528325/

10-12 06:04