JDB - 如何在运行程序之前获取方法列表?

时间:2010-07-17 21:07:42

标签: java debugging jdb

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

  

>方法ClassName

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

  

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

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

非常感谢!! 乔伊斯

3 个答案:

答案 0 :(得分:1)

如果你正在调试你自己的程序,我想你会知道班级名称!

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

但实际上您正在运行jdb ClassName,因此知道您将运行方法ClassName.main()。正确?

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

所以在任何一种情况下,你至少应该能够获得第一种方法。到那里,你可以找到其余的。

答案 1 :(得分:1)

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

  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
  3. 如果您附加,则不需要使用run命令。
    但是,如果您启动,则执行需要使用run命令(虚拟机尚未启动)。


    此行为可以从man jdb推断:

      

    运行 -   启动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

    3. 提示:查看jdb的命令提示符。有时候它是>,有时它就像main[1]。如果它是>,则VM尚未启动,classesmethods之类的命令将无法运行,直到您使用{{1}命令。如果提示符为run,则表示VM已启动,并且所需命令将起作用。


        

      我唯一可以得出的结论是jdb希望你设置你的断点盲目

      单独使用调试器很难设置breakboints。您需要在其他地方查看源代码。您可能知道至少一个要破解的方法的名称,从而使用设置初始断点 main[1]。如果您不知道中断的位置,则始终可以使用stop in ClassName.MethodName在主方法上设置断点。 请记住,在调试器运行时,您可以设置更多断点。此外,您可能会发现stop in ClassName.Main命令很有用 - 它显示了与当前断点命中对应的源代码。

答案 2 :(得分:0)

我有完全相同的问题。

跑完后:

jdb -classpath build -sourcepath src MyClass

我输入的文字在jdb会话中以粗体显示:

> stop in MyClass.main
Deferring breakpoint MyClass.main.
It will be set after the class is loaded.
> run
run MyClass
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
> 
VM Started: Set deferred breakpoint MyClass.main

Breakpoint hit: "thread=main", MyClass.main(), line=798 bci=0
798         MyClass singleton = new MyClass();

main[1] list
797     public static void main(String[] args) {
798 =>      MyClass singleton = new MyClass();
799