8

我正在学习 JDB 并遇到了一个悖论。启动 JDB(使用“jdb ClassName”)后,大多数教程都会告诉我输入

> 方法类名

查看可用方法的列表,以便我可以设置断点。如果我这样做,JDB 会回复

在使用“run”命令启动 VM 之前,命令“methods”无效

当然,如果我在设置任何断点之前说“运行”,它会直接运行;不是很有帮助。我唯一能得出的结论是 jdb 希望你设置你的断点盲目,但这似乎是一个严重的疏忽,我坚持认为我只是错过了一个命令。

非常感谢!!乔伊斯

4

3 回答 3

3

请注意,有两种方法可以创建调试会话(请参阅jdb 文档)。

  1. 附加- 我们将程序加载到虚拟机中,它会暂停侦听端口(例如 8000)。然后在另一个终端会话中,我们加载 jdb 并通过指定端口将其附加到 JVM 会话。
    • 在一个学期会议中:java -Xdebug -agentlib:jdwp=transport=dt_socket, address=8000,server=y,suspend=y ClassName
    • 在第二个终端会话中:jdb -attach 8000
  2. 启动- 加载 jdb 并告诉它要加载的类的名称。
    • 在单个终端会话中:jdb ClassName

如果要附加,则不需要使用该run命令。
但是,如果您正在启动,那么您确实需要使用该run命令(虚拟机尚未启动)。


这种行为可以从man jdb

run - 启动jdb并设置任何必要的断点后,使用此命令开始执行已调试的应用程序。此命令仅在jdb启动已调试的应用程序时可用(而不是附加到现有 VM)

这就是您收到错误消息的原因。您 启动了调试器,但没有使用run command. 有些教程可能会错误地告诉您启动jdb,但忘记告诉您执行run命令。


下面显示了如何获取方法列表(假设您main在名为 的类中有方法ClassName)。


  1. jdb -attach 8000
    main[1] stop in ClassName.main
    main[1] cont
    main[1] methods ClassName

  2. 启动
    jdb ClassName
    > stop in ClassName.main
    > run
    main[1] methods ClassName

提示:查看 jdb 的命令提示符。有时是>,有时像main[1]。如果是>,则 VM 尚未启动,并且在您使用该命令之前,诸如classes、之类的命令methods将不起作用run。如果提示符是main[1],则 VM 已启动并且所需的命令将起作用。


我唯一能得出的结论是 jdb 期望你设置你的断点盲目

单独使用调试器很难设置断点。您需要在其他地方查看您的源代码。您可能知道至少一种要中断的方法的名称,因此使用 stop in ClassName.MethodName. 如果你不知道在哪里中断,你总是可以在你的 main 方法上使用stop in ClassName.Main. 请记住,在调试器运行时,您可以设置更多断点。此外,您可能会发现该list命令很有用 - 它显示与当前断点命中对应的源代码。

于 2015-02-04T15:09:55.923 回答
1

如果您正在调试的是您自己的程序,我想您会知道类名!

如果它是一个您没有源代码的程序,那么要运行它,您必须知道包含main(). 如果它在以 开头的 jarjava -jar中,则该类的名称在 jar 内的清单中。

但实际上你是在跑步jdb ClassName,所以你知道你会跑步的方法ClassName.main()。正确的?

如果它是 Web 服务中的 servlet,则 servlet 的类在web.xml.

因此,在任何一种情况下,您至少应该能够获得第一种方法。到达那里后,您可以找到其余部分。

于 2010-07-17T21:17:07.193 回答
0

我有完全相同的问题。

所以运行后:

jdb -classpath build -sourcepath src MyClass

我输入的文本在jdb会话下方以粗体显示:

>停在 MyClass.main
推迟断点 MyClass.main。
它将在加载类后设置。
>运行
运行 MyClass
设置未捕获的 java.lang.Throwable
设置延迟未捕获的 java.lang.Throwable
>
VM 已启动:设置延迟断点 MyClass.main

断点命中:“thread=main”,MyClass.main(),line=798 bci=0
第798章

主 [1]列表
第797章
798 => MyClass 单例 = new MyClass();
799         
于 2013-10-09T15:37:39.883 回答