开发者

JDB -- How to get a list of methods before running the program?

I'm learning JDB and running into a bit of a paradox. After starting JDB (with "jdb ClassName") most tutorials will tell me to type

> methods ClassName

to see a list of available methods so that I can set my breakpoints. If I do that, JDB replies

Command 'methods' is not valid until the VM is started with the 'run' command

Of course, if I say "run" before setting any breakpoints, it runs straight through; not very helpful. The only thing I can conclude is that jdb expects you to set your breakpoints blind, but this seems like such a gross oversight, I'm开发者_StackOverflow holding out that I'm simply missing a command.

Many thanks!! Joyce


Note that there are two ways to create a debugging session (see the jdb documentation).

  1. Attaching - We load the program into a virtual machine, it pauses listening on a port (e.g. 8000). Then in another terminal session, we load jdb and attach it to the JVM session by specifying the port.
    • in one termial session:java -Xdebug -agentlib:jdwp=transport=dt_socket, address=8000,server=y,suspend=y ClassName
    • in a second terminal session: jdb -attach 8000
  2. Launching - Load jdb and tell it the name of the class to load.
    • in a single terminal session: jdb ClassName

If you are attaching, then you don't need to use the run command.
However, if you are launching, then you do need to use the run command (the virtual machine hasn't been started yet).


This behaviour can be inferred from man jdb:

run - After starting jdb, and setting any necessary breakpoints, use this command to start the execution of the debugged application. This command is available only when jdb launches the debugged application (as opposed to attaching to an existing VM).

This is why you have the error message. You launched the debugger but didn't use the run command. Some tutorials may incorrectly tell you to launch jdb, but forget to tell you to execute the run command.


Below shows how to get the list of methods (assuming you have main method in a class called ClassName).

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

  2. Launching:
    jdb ClassName
    > stop in ClassName.main
    > run
    main[1] methods ClassName

Hint: look at jdb's command prompt. Sometimes it's >, sometimes it's like main[1]. If it's >, then the VM hasn't started and commands such as classes, methods won't work until you have used the run command. If the prompt is main[1], the VM has been started and desired commands will work.


The only thing I can conclude is that jdb expects you to set your breakpoints blind

It is difficult to set breakboints using the debugger alone. You need to be looking at your source code elsewhere. You will likely know the name of at least one method to break at and thus set an initial breakpoint using stop in ClassName.MethodName. If you don't know where to break, you can always set a breakpoint on your main method using stop in ClassName.Main. Remember that while the debugger is running, you can set more breakpoints. Also, you may find, the list command useful - it shows the source code corresponding to the current breakpoint hit.


If it's your own program you're debugging, I'd think you'd know the class names!

If it's a program for which you don't have the source code, then to run it you must know the class name containing main(). If it's in a jar started with java -jar, the name of that class is in the manifest inside the jar.

But in fact you're running jdb ClassName, so you know you'll be running method ClassName.main(). Right?

If it's a servlet in a web service, the class of the servlet is in web.xml.

So in any of those cases you should at least be able to get the very first method. Once there, you can find the rest.


I had exactly the same question.

So after running:

jdb -classpath build -sourcepath src MyClass

the text I entered is in bold below in the jdb session:

> 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         
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜