Most of you whipper-snappers probably use Eclipse to do your debugging these days. And that works quite well as long as you happened to compile the code you're debugging. But what happens when you didn't compile the code you're debugging? With Eclipse, you're pretty much screwed. Even if you create a fake project and link in the source, it still never really works quite right. Breakpoints often don't break. Eclipse often can't figure out which line you're actually executing. Etc.
So let's talk about going old-school - enter jdb. Never really intended to be more that a proof of concept for the JPDA, it actually turns out to be surprisingly useful when you need to debug something you don't have source code for and/or didn't compile yourself.
One nice thing about jdb is that if you have a JDK, then you have a copy of it. It's been a standard tool since Java 1.2. If you're on Windows, Unix, a Mac and have installed a JDK, then jdb(.exe) will be waiting in $JDK_HOME/bin/.
Another thing you may be surprised to hear about jdb is that it can do remote socket debug just like Eclipse can. This isn't well documented, so I'll give you the magic invocation here:
First you start the remote program you want to debug on myserver.com with something like:
Then on your local machine, run:
jdb -connect com.sun.jdi.SocketAttach:hostname=myserv
Here's a quick cheat-sheet to get you started with the obvious stuff:
stop in com.mydomain.mypackage.myclass.mymethod # Set breakpoint on method entry clear # List (no args) or clear (with args) breakpoints use /home/mydir/sourcecodedir/ # Set source code path list # List source code lines next # steps OVER method calls step # steps INTO method calls step up # run until current method returns cont # continue exection after breakpoint print (somevar) # Show current value of somevar
All pretty standard, I know. But it should be noted that all of the above work whether you have source code or not, which beats the hell out of Eclipse. Now, how about some stuff that's a little more fun?
classpath # Print JVM's classpath disablegc (expr) # prevent garbage collection of an object classes # list all currently loaded classes class org.package.class # show details of named class methods com.this.class # list a class's methods fields com.that.class # list a class's fields eval (java expression) # Run arbitrary java code, alter program state at will redefine com.some.class newcode.class # Load new .class file to redefine an existing class
Some interesting possibilities there, eh?
evalis particularly fun. Need to delete an item out of a HashMap? Just
eval myHashMap.remove("thiskey")and you're done. (And yes, Eclipse's debug perspective can do this too if you know how... but how many people do?)
The possibilities for
redefineare especially amusing to contemplate...