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