将jdb附加到未捕获的异常 [英] Attach jdb on uncaught exception

查看:163
本文介绍了将jdb附加到未捕获的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我正在开始一个Java程序如下

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

然后我手动附加一个调试器,如下所示

  jdb -attach 8000 

我想知道我是否有设置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,onunca = y,suspend = n,launch = jdb MyClass 

调试器似乎连接,但立即抛出一个IOError。

 初始化jdb ... 

java.io.IOException:输入/输出错误
在java.io.FileInputStream.readBytes(本机方法)
在java.io.FileInputStream.read(FileInputStream.java:272)
在java.io.BufferedInputStream.read1(BufferedInputStream。 java:273)
在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)
在java.io.InputStreamReader.read(InputStreamReader .java:184)
在java.io.BufferedReader.fill(BufferedReader.java:154)
在java.io.BufferedReader.readLine(Buff eredReader.java:317)
在java.io.BufferedReader.readLine(BufferedReader.java:382)
在com.sun.tools.example.debug.tty.TTY。< init>(TTY .java:751)
at com.sun.tools.example.debug.tty.TTY.main(TTY.java:1067)


解决方案

要及时附加调试器确实使用您建议的选项(启动 onuncaught )。但启动选项需要更多的linux:


请注意,启动的进程没有在自己的窗口中启动。在大多数情况下,启动的过程应该是一个小应用程序,它会在自己的窗口中启动调试器应用程序。


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



我通过创建一个使用屏幕启动终端

 #!/ bin / bash 
#根据启动选项doc,第一个参数是运输和
#第二个参数将是地址

屏幕-dm -L -S autojdb jdb -attach $ 2

此脚本将开始 jdb 在一个分离的屏幕上,并为屏幕 autoj的会话命名db 。您可以使用 screen -ls 查看屏幕列表。当您要访问已启动的调试器时,请使用屏幕-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 以屏幕记录会话。这将记录会话,但也让您看到由于某些原因附件失败时发生的任何错误。


So, I am starting a Java program as below

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

I then manually attach a debugger as below

jdb -attach 8000

I would like to know if there is anyway for me to set up jdb so that it automatically attaches to the running process (only) in the case of an uncaught exception?

The reason being that I would like to avoid the overhead of the debugger until an uncaught exception arises. But the problem I face now is that if the debugger is not attached, then the JVM aborts once an uncaught exception arises.

EDIT:

From the Oracle docs, it seems the below command does what I need, but for windows machines.

java -agentlib:jdwp=transport=dt_shmem,server=y,onuncaught=y,launch=d:\bin\debugstub.exe MyClass

Anyone knows the linux equivalent? I have tried the below command.

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

The debugger seems like it connects but it immediately throws an 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)

解决方案

To attach a debugger just in time does indeed use the options you suggest (launch and onuncaught). But the launch option needs more on linux:

Note that the launched process is not started in its own window. In most cases the launched process should be a small application which in turns launches the debugger application in its own window.

In your case, jdb is failing to open the terminal TTY it needs because of the context it is being started in. Depending on the environment where this is running, you will need to construct a script that launches jdb in a new window or attaches it to a pseduo-tty so that it can run properly.

I tested this by creating a script that uses screen to start the terminal

#!/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

This script will start jdb in a detached screen and name the session for the screen autojdb. You can see the list of your screens using screen -ls. When you want to access the debugger that has been started use screen -r autojdb. Make sure to put the script in your path or give the full path (/home/me/screenjdb below) in your launch option:

java -agentlib:jdwp=transport=dt_socket,address=8000,server=y,onuncaught=y,suspend=n,launch=/home/me/screenjdb MyClass

In my script I also passed -L to screen which logs the session. This will record the session but also let you see any errors that occurred if the attach fails for some reason.

这篇关于将jdb附加到未捕获的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆