GNOME Bugzilla – Bug 546542
Eclipse does not exit when Accessibility is enabled.
Last modified: 2014-11-13 17:33:53 UTC
When Accessibility is enabled in GNOME, Eclipse (www.eclipse.org, tested with version 3.4 on Ubuntu x86_64) does exit as a process when you close it. When you press Ctrl+C, and then "ps", you can see a "java" process that keeps running in the background. I am using java-6-sun-1.6.0.06 (packaged with Ubuntu) and Eclipse 3.4 (http://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops/R-3.4-200806172000/eclipse-SDK-3.4-linux-gtk-x86_64.tar.gz). Both java and eclipse are GTK+ apps, however I am not sure how to proceed further. I am happy to do any further tests requested.
I wonder why this bug is filed under atk?
(In reply to comment #1) > I wonder why this bug is filed under atk? > Because I have no clue where to file it. Do you want to say that there is another product under GNOME that is more relevant or that this issue has nothing to do with GNOME?
java-access-bridge maybe more relevant.
(In reply to comment #3) > java-access-bridge maybe more relevant. Why? Eclipse doesn't use the java access bridge as it uses SWT for the UI, and SWT uses the native platform's controls and accessibility API. Has this bug been filed anywhere else where it might get resolved? >
There is a report at https://bugs.eclipse.org/bugs/show_bug.cgi?id=241773 There was a side-discussion on this issue at gtk-devel a few months ago, which I cannot find at the moment. Java does not appear to be relevant here but rather the changes that take place when Assistive Technologies are enabled (I think it LD_PRELOADs some extra libraries?)
This has been affecting Ubuntu since 8.04 - maybe earlier. I can confirm this has been a long-standing issue. I was originally affected with it more than a year ago. I found the workaround then was to reset GTK_MODULES before launching Eclipse. I added: GTK_MODULES="" to the Eclipse shell launching script (/usr/bin/eclipse) and forgot about it even though Gnome's Assistive Technologies were enabled for the session. I've just hit this issue once again with Ubuntu 9.04 and Eclipse 3.4.2, with either OpenJDK 6 or Sun Java 1.6. The GTK_MODULES work-around no longer helps so today I've been digging in to the issue. Starting a clean Eclipse Java IDE session and then cancelling when prompted for the Workspace to use leaves the process in memory. The process list shows that several threads are waiting on a futex: ps -C java -Lf -ly S UID PID PPID LWP C NLWP PRI NI RSS SZ WCHAN STIME TTY TIME CMD S tj 15745 15738 15745 0 13 80 0 323732 380763 futex_ 17:25 pts/0 00:00:00 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15746 6 13 80 0 323732 380763 futex_ 17:25 pts/0 00:00:11 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15747 0 13 80 0 323732 380763 futex_ 17:25 pts/0 00:00:00 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15748 0 13 80 0 323732 380763 futex_ 17:25 pts/0 00:00:00 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15749 0 13 80 0 323732 380763 futex_ 17:25 pts/0 00:00:00 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15750 0 13 80 0 323732 380763 futex_ 17:25 pts/0 00:00:00 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15751 0 13 80 0 323732 380763 futex_ 17:25 pts/0 00:00:00 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15753 1 13 80 0 323732 380763 futex_ 17:25 pts/0 00:00:03 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15754 2 13 80 0 323732 380763 futex_ 17:25 pts/0 00:00:04 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15755 0 13 80 0 323732 380763 futex_ 17:25 pts/0 00:00:00 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15768 0 13 80 0 323732 380763 futex_ 17:26 pts/0 00:00:00 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15797 0 13 80 0 323732 380763 futex_ 17:26 pts/0 00:00:00 /usr/lib/jvm/java-6-openjdk/bin/java S tj 15745 15738 15812 0 13 80 0 323732 380763 poll 17:27 pts/0 00:00:00 /usr/lib/jvm/java-6-openjdk/bin/java I installed the Ubuntu debug symbols for the packages in use (none available for liborbit2 so built them locally) and then used gdb to attach to and inspect each process in turn, looking for anything that might relate to AT-SPI. I found this: gdb (gdb) attach 15749 (gdb) bt full
+ Trace 214406
This would seem to suggest the client is waiting for an AT-SPI message via CORBA? I don't pretend to understand all the ins and outs of AT-SPI gail and so forth, but this looks like an explanation. I'll do some further investigation of the source-code myself but if someone involved with these packages would take a look we might save a lot of time (and frustration for me!).
I've been looking at the Changelog and SVN diffs. Firstly, the change that introduced the offending g_cond_wait() on line 716 of src/orb/GIOP/giop-recv-buffer.c::giop_recv_buffer_get() is revision 2005 "Fix how we handle GIOP timeouts" http://svn.gnome.org/viewvc/ORBit2/trunk/src/orb/GIOP/giop-recv-buffer.c?annotate=2005#l716 which was how the function used to handle the else{} clause until revision 1972 http://svn.gnome.org/viewvc/ORBit2/trunk/src/orb/GIOP/giop-recv-buffer.c?r1=1919&r2=1972 In Changelog there is an explanation of the change(s): 2006-12-05 Jules Colding <colding@omesc.com> * ORBit2: The previous two ChangeLog entries are hiding a lot of details which I'll hereby try to expand upon. The rationale for these changes is that any and all occurrences of g_cond_wait() in ORBit2 has the potential to block forever if it waits for a connection attempt to complete if said connection attempt is made towards a remote server which happens to be physically disconnected or powered off. This blocking behavior can be demonstrated by invoking an operation on a remote object that is physically inaccessible such as when the remote server is powered down or physically disconnected. It goes on to say: The last statement above will block forever in g_cond_wait() while waiting for the recieve buffer to be ready if the remote server is, say, powered down. An exception is on the other hand immediately thrown if the server object is merely gone. The changes to the code therefore boils down to the implementation of the ex_CORBA_TIMEOUT system exception being thrown if g_cond_timed_wait() times out. Most occurrences of g_cond_wait() has been replaced by g_cond_timed_wait(). The only remaining instance of g_cond_wait() is found in link_exec_command(). However, we can see that there is the g_cond_wait() in giop_recv_buffer_get() as well. This might be an oversight or deliberate. That first warning "...g_cond_wait() in ORBit2 has the potential to block forever..." would appear to be coming true in this case.
The final piece in this puzzle seems to be in the Changelog entry for the actual changes. It claims that giop_recv_buffer_get() had changed to use g_cond_timed_wait() so either a commit got lost or the Changelog isn't in sync. 2006-12-03 Jules Colding <colding@omesc.com> * src/orb/GIOP/giop-recv-buffer.c (giop_recv_buffer_get): Replaced a g_cond_wait() with a g_cond_timed_wait(). The original g_cond_wait() could potentially block forever if a remote server was physically offline. However there aren't any occurrences of g_cond_timed_wait() in the source that grep can find (aside from Changelog and NEWS).
I changed the call to g_cond_timed_wait() and added some printed messages to get an idea of what is going on: static const char *link_status[] = {"LINK_CONNECTING", "LINK_CONNECTED", "LINK_DISCONNECTED", "LINK_TIMEOUT"}; GIOPRecvBuffer * giop_recv_buffer_get (GIOPMessageQueueEntry *ent, gboolean *timeout) { GIOPThread *tdata = NULL; GTimeVal tv; *timeout = FALSE; tdata = giop_thread_self (); thread_switch: if (giop_thread_io ()) { ent_lock (ent); for (; !check_got (ent); ) { g_print("ent->cnx->parent.status = %s\n", link_status[ent->cnx->parent.status]); if (!giop_thread_queue_empty_T (tdata)) { ent_unlock (ent); giop_thread_queue_process (tdata); ent_lock (ent); } else { g_get_current_time(&tv); glong now = tv.tv_sec; tv.tv_sec += 10; // supposed default for GIOPTimeoutLimit is 30 (Changelog 2006-12-05) g_print("%ld: Calling g_cond_timed_wait(,,%ld)\n", now, tv.tv_sec); g_cond_timed_wait (tdata->incoming, tdata->lock, &tv); } } When closing Eclipse this shows: eclipse -ver 3.4 ORBIT_SOCKETDIR=/tmp/orbit-tj ATK_BRIDGE_REDIRECT_LOG=1 GTK_RC_FILES=/etc/gtk/gtkrc:/home/tj/.gtkrc-1.2-gnome2 ORBIT2_DEBUG=all GTK_MODULES=canberra-gtk-module:gail:atk-bridge AT_SPI_DEBUG=1 GTK_DEBUG=all GTK_MODULES=canberra-gtk-module:gail:atk-bridge JAVA_HOME=/usr/lib/jvm/java-6-openjdk JAVACMD=/usr/lib/jvm/java-6-openjdk/bin/java INSTALL=/usr/lib/eclipse-3.4 CMDLINEARGS=-Dlinux.experimental=true VMARGS=-Xms192m -Xmx768m -XX:PermSize=128M -XX:MaxPermSize=256M CONFIGURATION= ent->cnx->parent.status = LINK_CONNECTED 1239586532: Calling g_cond_timed_wait(,,1239586542) ent->cnx->parent.status = LINK_CONNECTED 1239586542: Calling g_cond_timed_wait(,,1239586552) ent->cnx->parent.status = LINK_CONNECTED 1239586552: Calling g_cond_timed_wait(,,1239586562) ent->cnx->parent.status = LINK_CONNECTED 1239586562: Calling g_cond_timed_wait(,,1239586572) ent->cnx->parent.status = LINK_CONNECTED 1239586572: Calling g_cond_timed_wait(,,1239586582) ent->cnx->parent.status = LINK_CONNECTED 1239586582: Calling g_cond_timed_wait(,,1239586592) ent->cnx->parent.status = LINK_CONNECTED 1239586592: Calling g_cond_timed_wait(,,1239586602) ent->cnx->parent.status = LINK_CONNECTED 1239586602: Calling g_cond_timed_wait(,,1239586612) So even using the timed wait the outer loop !check_got(ent) condition remains true. I had hoped to get some output from using --enable-debug and ORBIT2_DEBUG=all but so far it doesn't seem to be 'seeing' the environment variable.
So the obvious question now is, is the g_cond_wait() a distraction and the real problem the !got_check(ent) in the outer loop. I'm struggling to understand what is supposed to be on the other end of the connection. During a debug session I dug down into the GIOPMessageQueueEntry structure: Breakpoint 1, giop_recv_buffer_get (ent=0x7f067354ca70, timeout=0x7f067354cac4) at giop-recv-buffer.c:723 723 g_cond_timed_wait (tdata->incoming, tdata->lock, &tv); (gdb) print *ent $10 = {buffer = 0x0, cnx = 0x7f066c12f800, msg_type = 1, request_id = 1934936680, src_thread = 0x1f6c440, async_cb = 0} (gdb) print *ent->cnx $9 = {parent = {parent = {g_type_instance = {g_class = 0x7f066c14b560}, ref_count = 3, qdata = 0x0}, proto = 0x7f0667602ec0, status = LINK_CONNECTED, options = LINK_CONNECTION_NONBLOCKING, was_initiated = 1, is_auth = 1, inhibit_reconnect = 0, remote_host_info = 0x7f066c14b950 "localhost", remote_serv_info = 0x7f066c14b860 "/tmp/orbit-tj/linc-4755-0-12537cd2a403a", priv = 0x7f066c14b890, idle_broken_callbacks = 0x0, timeout_mutex = 0x0, timeout_msec = 0, timeout_source_id = 0, timeout_status = LINK_TIMEOUT_UNKNOWN, tdata = 0x0}, incoming_msg = 0x0, incoming_frags = 0x0, giop_version = GIOP_1_2, orb_data = 0x7f066c1458e0} (gdb) print *ent->cnx->parent->priv $8 = {tag = 0x7f066c14b970, fd = 20, max_buffer_bytes = 0, write_queue_bytes = 0, write_queue = 0x0, was_disconnected = 0} (gdb) print *ent->src_thread $11 = {lock = 0x2312810, incoming = 0x2171c20, wake_context = 0x0, keys = 0x0, async_ents = 0x0, request_queue = 0x0, invoke_policies = 0x0, request_handler = 0x7f06673cd505 <ORBit_POAObject_invoke_incoming_request>} (gdb) print ent->src_thread->request_handler $17 = (void (*)(gpointer, gpointer, gpointer)) 0x7f06673cd505 <ORBit_POAObject_invoke_incoming_request> I'm not sure I understand this correctly, but should "src_thread" be part of the eclipse process? If so, it may be the thread has been shutdown as I theorised earlier. I ran another debug session (so it has different values) but attached gdb before closing the Workspace dialog and listed the threads. After closing the dialog the breakpoint in giop_recv_buffer_get() was hit and I listed threads again then examined ent->src_thread and tried to match it up to the thread lists. If I am understanding the thread address correctly it does look as if the one that should contain the address of <ORBit_POAObject_invoke_incoming_request> has indeed 'gone': (gdb) print *ent->src_thread $27 = {lock = 0x2256800, incoming = 0x22eeb60, wake_context = 0x0, keys = 0x0, async_ents = 0x0, request_queue = 0x0, invoke_policies = 0x0, request_handler = 0x7f048b1b1505 <ORBit_POAObject_invoke_incoming_request>} Threads whilst Workspace dialog is active: (gdb) info threads 15 Thread 0x7f04dd8bb950 (LWP 32715) 0x00007f04dcbf1496 in *__GI___poll (fds=0x28b7090, nfds=6, timeout=50) at ../sysdeps/unix/sysv/linux/poll.c:87 14 Thread 0x7f04977ee950 (LWP 32716) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 13 Thread 0x7f04976ed950 (LWP 32717) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 12 Thread 0x7f049739d950 (LWP 32718) pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:217 11 Thread 0x7f049729c950 (LWP 32719) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 10 Thread 0x7f049719b950 (LWP 32720) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 9 Thread 0x7f049705b950 (LWP 32721) sem_wait () at ../nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S:85 8 Thread 0x7f0496f5a950 (LWP 32722) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 7 Thread 0x7f0496e59950 (LWP 32723) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 6 Thread 0x7f0496d58950 (LWP 32724) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 5 Thread 0x7f0496c57950 (LWP 32725) pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:217 4 Thread 0x7f048a1c1950 (LWP 32726) pthread_cond_timedwait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S:217 3 Thread 0x7f048a0c0950 (LWP 32727) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 2 Thread 0x7f0489fbf950 (LWP 32728) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 1 Thread 0x7f04dd8bc6f0 (LWP 32714) 0x00007f04dd297c95 in pthread_join (threadid=139658873518416, thread_return=0x7fffe58e0460) at pthread_join.c:89 Threads after closing and hitting the breakpoint: (gdb) info threads 28 Thread 0x7f0489ebe950 (LWP 484) 0x00007f04dcbf1496 in *__GI___poll (fds=0x234b150, nfds=5, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:87 15 Thread 0x7f04dd8bb950 (LWP 32715) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 14 Thread 0x7f04977ee950 (LWP 32716) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 13 Thread 0x7f04976ed950 (LWP 32717) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 * 12 Thread 0x7f049739d950 (LWP 32718) giop_recv_buffer_get (ent=0x7f049739ccf0, timeout=0x7f049739cd44) at giop-recv-buffer.c:723 11 Thread 0x7f049729c950 (LWP 32719) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 10 Thread 0x7f049719b950 (LWP 32720) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 9 Thread 0x7f049705b950 (LWP 32721) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 8 Thread 0x7f0496f5a950 (LWP 32722) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 7 Thread 0x7f0496e59950 (LWP 32723) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 6 Thread 0x7f0496d58950 (LWP 32724) pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:261 1 Thread 0x7f04dd8bc6f0 (LWP 32714) 0x00007f04dd297c95 in pthread_join (threadid=139658873518416, thread_return=0x7fffe58e0460) at pthread_join.c:89 Notice that request_handler = 0x7f048b1b1505 would appear to be 'in' thread 4 Thread 0x7f048a1c1950 (LWP 32726) which has already closed. If there is a better way than this fuzzy address-range matching to determine the gdb thread info to the internal libORBit2 representation it would be easier to determine if this is a valid conclusion.
[Resetting QA Contact to newly introduced "at-spi-maint@gnome.bugs". Reason: So far it was impossible to watch changes in at-spi bug reports without following all the specific persons (Li Yuan, Bill Haneman, Jeff Wai, ...) and also their activity outside of at-spi reports. IMPORTANT: Anyone interested in following all bug activity (including all maintainers) must watch the "at-spi-maint@gnome.bugs" dummy user by adding it to the 'Users to watch' list under Preferences->Email preferences. This is also the default procedure nowadays in GNOME when setting up new products.]
[Mass-resetting default assignee, see bug 705890. Please reclaim this bug report by setting the assignee to yourself if you still plan to work on this. Thanks!]
I'm going to go ahead and close this because it concerns a very old version. Feel free to open a new bug if the problem persists.