[java-gnome-hackers] improve debug experience
Brought to you by:
afcowie
From: Andrew C. <an...@op...> - 2009-02-19 05:57:01
|
Those of you who have followed the development of our thread safety mechanisms over the years will be aware that we wrap every call into GTK with a synchronized block. The key one turns out to be the one around our call to gtk_main(), ie, in GtkMain.java we see: synchronized (lock) { gtk_main(); } nothing earth shattering here. When debugging in Eclipse, I've been noticing something a bit strange of late. Everytime I'm debugging something deep down inside some application of mine, and I do something that throws an uncaught exception (me throwing IllegalStateException or whatever) Eclipse's debugger was stopping with its current instruction pointer at the synchronzied block in GtkMain, not at whereever the exception was thrown as we're all used to seeing. Weird. At first I thought it was a behaviour change on Eclipse's part, but hunting around for a configuration flag to change it back to "normal" didn't turn anything up. And then I noticed that this was only happening in java-gnome programs, not others. A lot of searching around the net led me to the conclusion that this is deliberate on Eclipse's part - apparently this sort of stopping behaviour helps when debugging thread lock problems. Ok, fair enough. But that's not the sort of problem we're dealing with here; and meanwhile it's screwing up normal debugging (where it is really handy to get a thread suspended right in the method where the exception gets thrown, not umpteen layers back with most of the stack unwound) Hm. I experimented with things a bit, and came to a somewhat surprising notion for how to work around this. People who are *really* detail oriented might have seen the notes about how the stack thinks that that thread holds the Gdk lock when it doesn't. We did EXTENSIVE testing on that a couple years ago, and it's all good - the actual blocked, holding, and waiting states are all correct [even better, Eclipse gets it right, actually; it knows which thread really holds the lock]. For some time I've mumbled in the back of my mind that maybe we should take the cosmetic step to take the monitor on the JNI side before calling the gtk_main() function, which would result in the thread stack dumps looking a smidge more correct. I resisted the temptation because entering that lock before calling gtk_main() is *SO* important and having it appear exactly the same as every other native call seemed a good idea. But having run into this strange debugging behaviour, I remembered this temptation and for the heck of it tried it out. Sure enough, Eclipse's debugger now behaves the way I'd expect it to. I tested rather extensively. === modified file 'src/bindings/org/gnome/gtk/GtkMain.java' static final void main() { - synchronized (lock) { - gtk_main(); - } + // monitor entry on JNI side + gtk_main(); + // monitor exited } private static native final void gtk_main(); === modified file 'src/bindings/org/gnome/gtk/GtkMain.c' { // call function + gdk_threads_enter(); gtk_main(); + gdk_threads_leave(); } So the question I have to ask: is this a good idea? That it seems to result in a better debugging experience for people developing an application that happens to have its UI in java-gnome is obviously something very desirable. The fact that it breaks the parallel clarity that we strive incredibly hard to maintain throughout the library bothers me very much. Doing it this way is still "correct" as far as thread safety goes; I have no worries about that. It just breaks symmetry. Ok, no big deal, but given that more than any other call in the library having this call inside the lock is the most crucial aspect of achieving thread safety, it bothers me to be other than crystal clear about it. And while development-experience-in-IDE is something we've heavily optimized for, I don't necessarily want to see us jumping though hoops like this just because of strange things Eclipse is doing this week. But before accepting it for 'mainline' I thought I would mention what I had run into and see if anyone else actively developing java-gnome applications or hacking on the library itself had any thoughts. [If someone can tell me an Eclipse setting I've overlooked then that would simplify matters :)] The patch is at: bzr://research.operationaldynamics.com/bzr/java-gnome/hackers/andrew/monitor-entry-jni/ AfC Sydney |