|
5.9. The Java DebuggerHow can you stand using the SDK? It doesn't even have a debugger! Wrong. It has a debugger. It just has an extremely basic command-line debugger. Example 5.16 shows the output of its help. Again, we are not going to document everything here. That's what the online Sun Microsystems Java SDK documentation is for. Instead, we will use the debugger to step through the execution of our simple application and show you some of the debugger's basic operations. There are two ways to invoke jdb. One is to attach it to an already running JVM that has been started with remote debugging enabled. See the Java SDK documentation for details on that method. Here we'll show you the simpler case of invoking the program locally by running the application directly under the debugger. The basic invocation is: $ jdb You may optionally name the class whose main() is to be executed under the debugger, but we usually use the run from inside the debugger itself to do this. Remember that if you want to be able to view local variables in the debugger, you must have compiled your class or classes with the -g option of javac. In the rest of this section, we will examine an actual debug session. We will run our single-class application, FetchURL, and use it to retrieve the index.html file from the Web server on the laptop on which this chapter is being written. To refresh your memory, remember that the source code for FetchURL is at Example 3.30. Example 5.17 is what that file looks like. Example 5.16. The Java debugger help command output$ jdb GetUser Initializing jdb ... > help ** command list ** run [class [args]] -- start execution of application's main class threads [threadgroup] -- list threads thread <thread id> -- set default thread suspend [thread id(s)] -- suspend threads (default: all) resume [thread id(s)] -- resume threads (default: all) where [thread id] | all -- dump a thread's stack wherei [thread id] | all -- dump a thread's stack, with pc info up [n frames] -- move up a thread's stack down [n frames] -- move down a thread's stack kill <thread> <expr> -- kill a thread with the given exception object interrupt <thread> -- interrupt a thread print <expr> -- print value of expression dump <expr> -- print all object information eval <expr> -- evaluate expression (same as print) set <lvalue> = <expr> -- assign new value to field/variable/array element locals -- print all local variables in current stack frame classes -- list currently known classes class <class id> -- show details of named class methods <class id> -- list a class's methods fields <class id> -- list a class's fields threadgroups -- list threadgroups threadgroup <name> -- set current threadgroup stop in <class id>.<method>[(argument_type,...)] -- set a breakpoint in a method stop at <class id>:<line> -- set a breakpoint at a line clear <class id>.<method>[(argument_type,...)] -- clear a breakpoint in a method clear <class id>:<line> -- clear a breakpoint at a line clear -- list breakpoints catch [uncaught|caught|all] <exception-class id> -- break when specified exception occurs ignore [uncaught|caught|all] <exception-class id> -- cancel 'catch' for the specified exception watch [access|all] <class id>.<field name> -- watch access/modifications to a field unwatch [access|all] <class id>.<field name> -- discontinue watching access/modifications to a field trace methods [thread] -- trace method entry and exit untrace methods [thread] -- stop tracing method entry and exit step -- execute current line step up -- execute until the current method returns to its caller stepi -- execute current instruction next -- step one line (step OVER calls) cont -- continue execution from breakpoint list [line number|method] -- print source code use (or sourcepath) [source file path] -- display or change the source path exclude [class id ... | "none"] -- do not report step or method events for specified classes classpath -- print classpath info from target VM monitor <command> -- execute command each time the program stops monitor -- list monitors unmonitor <monitor#> -- delete a monitor read <filename> -- read and execute a command file lock <expr> -- print lock info for an object threadlocks [thread id] -- print lock info for a thread pop -- pop the stack through and including the current frame reenter -- same as pop, but current frame is reentered redefine <class id> <class filename> -- redefine the code for a class disablegc <expr> -- prevent garbage collection of an object enablegc <expr> -- permit garbage collection of an object !! -- repeat last command <n> <command> -- repeat command n times help (or ?) -- list commands version -- print version information exit (or quit) -- exit debugger <class id> or <exception-class id>: full class name with package qualifiers or a pattern with a leading or trailing wildcard ('*') NOTE: any wildcard pattern will be replaced by at most one full class name matching the pattern. <thread id>: thread number as reported in the 'threads' command <expr>: a Java(tm) Programming Language expression. Most common syntax is supported. Startup commands can be placed in either "jdb.ini" or ".jdbrc" in user.home or user.dir > Example 5.17. index.html used in jdb session<HTML> <HEAD> <TITLE>RedHat Linux Laptop</TITLE> </HEAD> <BODY> <H1>RedHat Linux Laptop</H1> <P>You have contacted Michael Schwarz's RedHat Linux Laptop. You would probably rather <A HREF="http://www.multitool.net/">see his permanent Web page</A> since this server goes up and down all the time, what with it being on a laptop.</P> </BODY> </HTML> Example 5.18 is an actual transcript of a real jdb session. It is annotated with explanatory comments. Our goal here is to get you going. The best way to learn jdb, or indeed any of these tools, is to use them. Obviously, this little session has merely scratched the surface of the Java debugger. You can debug multithreaded applications with commands that can suspend and resume individual threads, list the running threads, switch your "executable view" between threads, and so forth. You can trace method calls. You can monitor variables. You can execute expressions (including assignment expressions, allowing you to force variables to certain values). You can browse classes. You can dump all local variables with a single command. The debugger is quite capable, if a bit limited in user interface.[23] Learn it. Play with it. Step through your favorite Java program with it.
Example 5.18. An actual jdb session, with commentary$ jdb Initializing jdb ... > stop in FetchURL.main (1) Deferring breakpoint FetchURL.main. It will be set after the class is loaded. > run FetchURL http://localhost run FetchURL http://localhost Set uncaught java.lang.Throwable Set deferred uncaught java.lang.Throwable > VM Started: Set deferred breakpoint FetchURL.main Breakpoint hit: "thread=main", FetchURL.main(), line=48 bci=0 48 for (i = 0; i < args.length; i++) main[1] list 44 { 45 int i; 46 FetchURL f; 47 48 => (2) for (i = 0; i < args.length; i++) 49 { 50 System.out.println(args[i] + ":"); 51 System.out.println(new FetchURL(args[i])); 52 } 53 } main[1] step > Step completed: "thread=main", FetchURL.main(), line=50 bci=5 50 System.out.println(args[i] + ":"); main[1] step > http://localhost: Step completed: "thread=main", FetchURL.main(), line=51 bci=32 51 System.out.println(new FetchURL(args[i])); main[1] step > Step completed: "thread=main", FetchURL.<init>(), line=8 bci=0 8 { main[1] list 4 public class FetchURL { 5 private URL requestedURL; 6 7 public FetchURL(String urlName) 8 => { 9 try { 10 requestedURL = new URL(urlName); 11 } catch (Exception e) { 12 e.printStackTrace(); 13 } main[1] step > Step completed: "thread=main", FetchURL.<init>(), line=10 bci=4 10 requestedURL = new URL(urlName); main[1] step (3) > Step completed: "thread=main", FetchURL.<init>(), line=11 bci=16 11 } catch (Exception e) { main[1] step > Step completed: "thread=main", FetchURL.<init>(), line=14 bci=27 14 } main[1] step > Step completed: "thread=main", FetchURL.main(), line=51 bci=45 51 System.out.println(new FetchURL(args[i])); main[1] step > Step completed: "thread=main", FetchURL.toString(), line=19 bci=2 19 String rc = ""; main[1] list 15 16 17 public String toString() 18 { 19 => String rc = ""; 20 String line; 21 BufferedReader rdr; 22 23 try { 24 rdr = new BufferedReader( main[1] step > Step completed: "thread=main", FetchURL.toString(), line=24 bci=3 24 rdr = new BufferedReader( main[1] step > Step completed: "thread=main", FetchURL.toString(), line=30 bci=28 30 while ((line = rdr.readLine()) != null) main[1] step > Step completed: "thread=main", FetchURL.toString(), line=32 bci=31 32 rc = rc + line + "\n"; main[1] list 28 ); 29 30 while ((line = rdr.readLine()) != null) 31 { 32 => rc = rc + line + "\n"; 33 } 34 } catch (Exception e) { 35 e.printStackTrace(); 36 rc = null; 37 } main[1] step > Step completed: "thread=main", FetchURL.toString(), line=30 bci=55 30 while ((line = rdr.readLine()) != null) main[1] step > Step completed: "thread=main", FetchURL.toString(), line=32 bci=31 32 rc = rc + line + "\n"; main[1] step > Step completed: "thread=main", FetchURL.toString(), line=30 bci=55 30 while ((line = rdr.readLine()) != null) main[1] step > Step completed: "thread=main", FetchURL.toString(), line=32 bci=31 32 rc = rc + line + "\n"; main[1] dump this (4) this = { requestedURL: instance of java.net.URL(id=378) } main[1] dump rc (5) rc = "<HTML> <HEAD> " main[1] list 36 32 rc = rc + line + "\n"; 33 } 34 } catch (Exception e) { 35 e.printStackTrace(); 36 => rc = null; 37 } 38 39 return rc; 40 } 41 main[1] stop at FetchURL:39 (6) Set breakpoint FetchURL:39 main[1] cont > Breakpoint hit: "thread=main", FetchURL.toString(), line=39 bci=79 39 return rc; main[1] dump rc rc = "<HTML> <HEAD> <TITLE>RedHat Linux Laptop</TITLE> </HEAD> <BODY> <H1>RedHat Linux Laptop</H1> <P>You have contacted Michael Schwarz's RedHat Linux Laptop. You would probably rather <A HREF="http://www.multitool.net/">see his permanent Web page</A> since this server goes up and down all the time, what with it being on a laptop.</P> </BODY> </HTML> " main[1] step > <HTML> <HEAD> <TITLE>RedHat Linux Laptop</TITLE> </HEAD> <BODY> <H1>RedHat Linux Laptop</H1> <P>You have contacted Michael Schwarz's RedHat Linux Laptop. You would probably rather <A HREF="http://www.multitool.net/">see his permanent Web page</A> since this server goes up and down all the time, what with it being on a laptop.</P> </BODY> </HTML> Step completed: "thread=main", FetchURL.main(), line=48 bci=48 48 for (i = 0; i < args.length; i++) main[1] step > Step completed: "thread=main", FetchURL.main(), line=53 bci=57 53 } main[1] step > The application exited $
|
|