After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 631804 - Evolution aborts with pthread error in imapx_server_dispose()
Evolution aborts with pthread error in imapx_server_dispose()
Status: RESOLVED FIXED
Product: evolution-data-server
Classification: Platform
Component: Mailer
3.0.x (obsolete)
Other Linux
: Normal normal
: ---
Assigned To: evolution-mail-maintainers
Evolution QA team
Depends on:
Blocks:
 
 
Reported: 2010-10-10 08:56 UTC by David Woodhouse
Modified: 2013-09-14 16:53 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Don't join parser thread (1.59 KB, patch)
2010-10-23 10:31 UTC, David Woodhouse
reviewed Details | Review
patch (863 bytes, patch)
2010-10-25 12:38 UTC, David Woodhouse
committed Details | Review

Description David Woodhouse 2010-10-10 08:56:53 UTC
GThread-ERROR **: file gthread-posix.c: line 385 (g_thread_join_posix_impl): err
or 'Resource deadlock avoided' during 'pthread_join (*(pthread_t*)thread, &ignor
e)'
aborting...


Was running under Valgrind, didn't get to see a backtrace or anything. Will see if it happens again...
Comment 1 David Woodhouse 2010-10-16 09:57:14 UTC
Program received signal SIGABRT, Aborted.

Thread 140735634454288 (LWP 26471)

  • #0 raise
    at ../nptl/sysdeps/unix/sysv/linux/raise.c line 64
  • #1 abort
    at abort.c line 92
  • #2 g_logv
  • #3 g_log
    at gmessages.c line 577
  • #4 g_thread_join_posix_impl
    at gthread-posix.c line 385
  • #5 g_thread_join
    at gthread.c line 2042
  • #6 imapx_server_dispose
    at camel-imapx-server.c line 4941
  • #7 g_object_unref
    at gobject.c line 2658
  • #8 g_value_unset
    at gvalue.c line 275
  • #9 g_signal_emit_valist
    at gsignal.c line 3013
  • #10 g_signal_emit
    at gsignal.c line 3040
  • #11 imapx_parser_thread
    at camel-imapx-server.c line 4887
  • #12 g_thread_create_proxy
    at gthread.c line 1897
  • #13 start_thread
    at pthread_create.c line 301
  • #14 clone
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S line 115

Thread 31 (Thread 0x7fff917fb710 (LWP 26471))

  • #0 raise
    at ../nptl/sysdeps/unix/sysv/linux/raise.c line 64
  • #1 abort
    at abort.c line 92
  • #2 g_logv
  • #3 g_log
    at gmessages.c line 577
  • #4 g_thread_join_posix_impl
    at gthread-posix.c line 385
  • #5 g_thread_join
    at gthread.c line 2042
  • #6 imapx_server_dispose
    at camel-imapx-server.c line 4941
  • #7 g_object_unref
    at gobject.c line 2658
  • #8 g_value_unset
    at gvalue.c line 275
  • #9 g_signal_emit_valist
    at gsignal.c line 3013
  • #10 g_signal_emit
    at gsignal.c line 3040
  • #11 imapx_parser_thread
    at camel-imapx-server.c line 4887
  • #12 g_thread_create_proxy
    at gthread.c line 1897
  • #13 start_thread
    at pthread_create.c line 301
  • #14 clone
    at ../sysdeps/unix/sysv/linux/x86_64/clone.S line 115

Thread 1 (Thread 0x7ffff5208980 (LWP 26425))

  • #0 g_type_check_instance_cast
    from /home/dwmw2/git/evolution/widgets/misc/.libs/libemiscwidgets.so.0
  • #1 e_activity_proxy_init
    at e-activity-proxy.c line 279
  • #2 g_type_create_instance
    at gtype.c line 1887
  • #3 g_object_constructor
    at gobject.c line 1597
  • #4 g_object_newv
    at gobject.c line 1462
  • #5 g_object_new_valist
    at gobject.c line 1578
  • #6 g_object_new
    at gobject.c line 1296
  • #7 shell_taskbar_activity_add
    at e-shell-taskbar.c line 101
  • #8 g_closure_invoke
    at gclosure.c line 766
  • #9 signal_emit_unlocked_R
    at gsignal.c line 3252
  • #10 g_signal_emit_valist
    at gsignal.c line 2983
  • #11 g_signal_emit
    at gsignal.c line 3040
  • #12 e_shell_backend_add_activity
    at e-shell-backend.c line 421
  • #13 mail_msg_submit
    at mail-mt.c line 74
  • #14 g_main_dispatch
    at gmain.c line 2149
  • #15 g_main_context_dispatch
    at gmain.c line 2702
  • #16 g_main_context_iterate
    at gmain.c line 2780
  • #17 g_main_loop_run
    at gmain.c line 2988
  • #18 IA__gtk_main
    at gtkmain.c line 1237
  • #19 main
    at main.c line 689

Comment 2 Akhil Laddha 2010-10-19 09:10:09 UTC
I got similar crash in 2.91.2. I moved to mail view from calendar view, then clicked on Inbox, clicked on 'x' to quit evolution and it crashed.

  • #0 g_logv
  • #1 g_log
  • #2 g_thread_join_posix_impl
    at gthread-posix.c line 385
  • #3 g_thread_join
    at gthread.c line 2042
  • #4 imapx_server_dispose
    at camel-imapx-server.c line 4947
  • #5 g_object_unref
    at gobject.c line 2660
  • #6 g_value_object_free_value
    at gobject.c line 2946
  • #7 g_value_unset
    at gvalue.c line 275
  • #8 g_signal_emit_valist
    at gsignal.c line 3013
  • #9 g_signal_emit
    at gsignal.c line 3040
  • #10 imapx_parser_thread
    at camel-imapx-server.c line 4893
  • #11 g_thread_create_proxy
    at gthread.c line 1897
  • #12 start_thread
    from /lib/libpthread.so.0
  • #13 clone
    from /lib/libc.so.6

Comment 3 Milan Crha 2010-10-21 11:23:58 UTC
I saw this only once, and I understand this as the thread has the last reference to the CamelImapxServer object, and during the "shutdown" signal emission is this reference removed, and object about to dispose, and because the dispose is now waiting on the thread to finish (my change, and correct), then the pthread detects that the thread wants to wait on itself, which is obviously impossible, then it aborts.

Possibilities:
a) invoke "shutdown" signal on the main thread, in some timeout routine - it may  mean that there should be one more synchronization mechanism for indication that the thread properly gone, otherwise we would be able to finalize the CamelImapxServer object before the timeout will be reached
b) do the unref of the 'conn' in camel-imapx-conn-managet.c:free_connection on timeout, which will ensure the object's reference will be removed only from the main thread.

The b) seems like easier way, but does it make any sense?
Comment 4 David Woodhouse 2010-10-23 10:31:51 UTC
Created attachment 173067 [details] [review]
Don't join parser thread

Or we could just stop joining that thread altogether.

When I go offline I get a different deadlock now, with idle:

Thread 44 (Thread 0x7fffa37a8710 (LWP 25504))

  • #0 pthread_join
    from /lib64/libpthread.so.0
  • #1 g_thread_join_posix_impl
    at gthread-posix.c line 385
  • #2 g_thread_join
    at gthread.c line 2042
  • #3 imapx_exit_idle
    at camel-imapx-server.c line 2389
  • #4 imapx_server_dispose
    at camel-imapx-server.c line 4954
  • #5 g_object_unref
    at gobject.c line 2658
  • #6 free_connection
    at camel-imapx-conn-manager.c line 59
  • #7 g_slist_foreach
    at gslist.c line 856
  • #8 imapx_prune_connections
    at camel-imapx-conn-manager.c line 72
  • #9 imapx_disconnect_sync
    at camel-imapx-store.c line 252
  • #10 camel_service_disconnect_sync
    at camel-service.c line 496
  • #11 camel_offline_store_set_online_sync
    at camel-offline-store.c line 157
  • #12 mail_store_go_offline_thread
    at e-mail-store-utils.c line 59
  • #13 run_in_thread
    at gsimpleasyncresult.c line 783
  • #14 io_job_thread
    at gioscheduler.c line 181
  • #15 g_thread_pool_thread_proxy
    at gthreadpool.c line 319
  • #16 g_thread_create_proxy
    at gthread.c line 1897
  • #17 start_thread
    from /lib64/libpthread.so.0
  • #18 clone
    from /lib64/libc.so.6

Comment 5 David Woodhouse 2010-10-23 11:50:44 UTC
Hm, cannot reproduce that deadlock now.
Comment 6 Milan Crha 2010-10-25 09:01:25 UTC
(In reply to comment #4)
> Or we could just stop joining that thread altogether.

Yes, that can do it too. Though I'm afraid it can have some side effects, like the server will be gone before the thread finishes, which means the thread will access freed memory. The thread cannot add a reference to the server, as otherwise the dispose will be never called, and the thread will never stop (maybe except of going online/offline, it needs more testing). So I think there should be some synchronizing mechanism to know whether the thread gone or not. Probably some EFlag.

> @@ -5182,6 +5177,8 @@ imapx_server_get_message (CamelIMAPXServer *is,

This chunk is for other bug, isn't it?
Comment 7 David Woodhouse 2010-10-25 11:30:24 UTC
(In reply to comment #6)
> (In reply to comment #4)
> > Or we could just stop joining that thread altogether.
> 
> Yes, that can do it too. Though I'm afraid it can have some side effects,

Hm, very true. I was thinking that it already *has* a reference, otherwise it couldn't be dropping it and thus ending up in imapx_server_dispose(). But that's only a temporary one when it sends the signal.

In that case I'm inclined to revert to the simple and dirty option:

--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -4944,7 +4944,8 @@ imapx_server_dispose (GObject *object)
        QUEUE_UNLOCK (server);
 
        if (server->parser_thread) {
-               g_thread_join (server->parser_thread);
+               if (server->parser_thread != g_thread_self())
+                       g_thread_join (server->parser_thread);
                server->parser_thread = NULL;
        }
 


> > @@ -5182,6 +5177,8 @@ imapx_server_get_message (CamelIMAPXServer *is,
> 
> This chunk is for other bug, isn't it?

Yeah, no idea why that was lying around uncommitted. Pushed now.
Comment 8 Milan Crha 2010-10-25 11:59:35 UTC
If, and only if, you want to use this change, then do the join on idle or timeout, because otherwise you'll end-up with a memory leak and it's pity to see all your memory leak bugs filled and then this :)

> > This chunk is for other bug, isn't it?
> 
> Yeah, no idea why that was lying around uncommitted. Pushed now.

Do not forget to close/update the bug, if not done already.
Comment 9 David Woodhouse 2010-10-25 12:38:27 UTC
Created attachment 173174 [details] [review]
patch

(In reply to comment #8)
> If, and only if, you want to use this change, then do the join on idle or
> timeout, because otherwise you'll end-up with a memory leak and it's pity to
> see all your memory leak bugs filled and then this :)

Oh yeah. My original attempt did get that far, but then I ripped it all out in favour of the 'don't join at all' version.

> Do not forget to close/update the bug, if not done already.

I don't think I got round to filing one for that, for some reason.
Comment 10 Milan Crha 2010-10-25 13:20:37 UTC
(In reply to comment #9)
> > Do not forget to close/update the bug, if not done already.
> 
> I don't think I got round to filing one for that, for some reason.

Sure you did, see bug #631754 (I know I was "reviewing" it recently).
Comment 11 David Woodhouse 2010-10-25 13:56:55 UTC
Oh, so I did. Thanks :)
Comment 12 Milan Crha 2010-10-27 06:50:34 UTC
OK, the patch looks good, from the functionality point of view. Just format new code in evo's way - add new lines where they should be, add spaces where they should be, and please commit to master and gnome-2-32. Thanks.
Comment 13 Milan Crha 2010-11-08 14:06:38 UTC
Created commit 0a2718c in eds master (2.91.3+)
Created commit 7231e71 in eds gnome-2-32 (2.32.1+)
Comment 14 Michael Meeks 2010-11-26 09:36:47 UTC
Ho hum - if the thread is created to be joined, and we fail to join it - then we leak address space; this exacerbates our "thread 2840" type problems, and eventually causes extremely odd bugs & crashes.

ie. every joinable thread we create, must be joined after it exits - or we'll get even worse at this ... - surely ?
Comment 15 Milan Crha 2010-11-29 11:05:07 UTC
(In reply to comment #14)
> ie. every joinable thread we create, must be joined after it exits - or we'll
> get even worse at this ... - surely ?

Yup, that's basically what the patch does. Or I didn't get your complaint/comment.