Summary: | Crash (SEGV) at gtkcmctree.c:4514 after deleting an unread message | ||||||
---|---|---|---|---|---|---|---|
Product: | Claws Mail (GTK 2) | Reporter: | Aleksander Mazur <deweloper> | ||||
Component: | Folders/IMAP | Assignee: | users | ||||
Status: | RESOLVED FIXED | ||||||
Severity: | critical | CC: | andreas.bierfert, arthur.huillet, mschwendt | ||||
Priority: | P3 | ||||||
Version: | 3.11.1 | ||||||
Hardware: | PC | ||||||
OS: | Linux | ||||||
Attachments: |
|
Description
Aleksander Mazur
2015-01-29 19:10:04 UTC
cf. http://lists.claws-mail.org/pipermail/users/2014-February/008366.html Other than that, stacktraces without any additional details on reproducibility sometimes are not helpful. Even if a crash is _not_ reproducible always, do mention that. Steps to reproduce: 1. Enable fancy plugin and configure claws-mail to prefer HTML content 2. Open an unread HTML message on an IMAP account 3. Delete the message before it gets marked as read Reproducibility ~50% (In reply to comment #2) > Steps to reproduce: > 1. Enable fancy plugin and configure claws-mail to prefer HTML content > 2. Open an unread HTML message on an IMAP account > 3. Delete the message before it gets marked as read > > Reproducibility ~50% claws-mail crashes with exactly the same callstack on plaintext messages as well, but a bit less frequently. It happened again, this time on a 32-bit system. (gdb) bt #0 summary_set_row_marks (summaryview=summaryview@entry=0x8630d18, row=row@entry=0x893a890) at summaryview.c:3833 #1 0x081bc685 in msginfo_mark_as_read (summaryview=0x8630d18, msginfo=<optimized out>, row=0x893a890) at summaryview.c:3534 #2 0x081bc755 in msginfo_mark_as_read_timeout (data=data@entry=0x85a0870) at summaryview.c:3551 #3 0x49f52262 in g_timeout_dispatch (source=source@entry=0x8cda3a0, callback=0x81bc700 <msginfo_mark_as_read_timeout>, user_data=0x85a0870) at gmain.c:4451 #4 0x49f51556 in g_main_dispatch (context=0x84a1638) at gmain.c:3066 #5 g_main_context_dispatch (context=context@entry=0x84a1638) at gmain.c:3642 #6 0x49f51920 in g_main_context_iterate (context=0x84a1638, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713 #7 0x49f51dc3 in g_main_loop_run (loop=loop@entry=0x8411980) at gmain.c:3907 #8 0x41740720 in IA__gtk_main () at gtkmain.c:1257 #9 0x08082e44 in main (argc=1, argv=0xbffff1e4) at main.c:1559 Let's have a look at this: (gdb) print msginfo $1 = (MsgInfo *) 0x1 (gdb) print row $2 = (GtkCMCTreeNode *) 0x893a890 (gdb) print summaryview->selected $16 = (GtkCMCTreeNode *) 0x87bac90 Frame #2 passes summaryview->selected as row, but as you can see above, row != summaryview->selected in frame #1. It seems that this is possible because msginfo_mark_as_read_timeout() (called from a Glib timeout) is completely unsynchronized with msginfo_mark_as_read_timeout() (called from a Gtk signal handler for GDK_KEY_Delete). So summary_delete() might call summary_select_node() which calls summary_cancel_mark_read_timeout() but this may fail to cancel the timeout if another thread has already started execution of timeout handler. Timeout handler calls summary_set_row_marks() (as seen on backtrace above) with old value of "selected", which is stored on stack. Then GDK_KEY_Delete handler replaces summaryview->selected with new value and destroys old selected row. Then context switches to timeout handler which tries to use the old (already destroyed) row. I'm not familiar with Glib/Gtk - if that scenario is impossible please explain how it was supposed to be synchronized (I mean, handling Delete key vs. "mark as read" timeout). According to https://www.gnu.org/software/guile-gnome/docs/gdk/html/Threads.html : "Callbacks from GTK+ signals are made within the GTK+ lock. However callbacks from GLib (timeouts, IO callbacks, and idle functions) are made outside of the GTK+ lock. So, within a signal handler you do not need to call gdk-threads-enter, but within the other types of callbacks, you do. " In summaryview.c msginfo_mark_as_read_timeout() - a timeout callback - doesn't seem to call gdk-threads-enter (whatever it is). summaryview.c also doesn't seem to synchronize cancelling the "mark as read" timeout properly, as described under https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-source-remove . Isn't it also necessary to use g_source_is_destroyed as explained in https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-source-is-destroyed ? It seems that the real problem is simpler. Everything happens in a single thread. Look what callstack I catched just before SIGSEGV: #0 summary_clear_list (summaryview=summaryview@entry=0x8630d08) at summaryview.c:1617 #1 0x081c1d30 in summary_show (summaryview=summaryview@entry=0x8630d08, item=0x8729180) at summaryview.c:1311 #2 0x081c166f in summary_execute (summaryview=summaryview@entry=0x8630d08) at summaryview.c:4989 #3 0x081c4ed0 in summary_move_selected_to (summaryview=summaryview@entry=0x8630d08, to_folder=to_folder@entry=0x87294f0) at summaryview.c:4580 #4 0x081c5064 in summary_delete_trash (summaryview=summaryview@entry=0x8630d08) at summaryview.c:4460 #5 0x081c534e in summary_key_pressed (widget=widget@entry=0x84e6458, event=0x914e9f8, summaryview=summaryview@entry=0x8630d08) at summaryview.c:6803 #6 0x417439ae in _gtk_marshal_BOOLEAN__BOXED (closure=0x86dbcd0, return_value=0xbfffddfc, n_param_values=2, param_values=0xbfffde70, invocation_hint=0xbfffde18, marshal_data=0x0) at gtkmarshalers.c:86 #7 0x4a0597de in g_closure_invoke (closure=0x86dbcd0, return_value=return_value@entry=0xbfffddfc, n_param_values=2, param_values=param_values@entry=0xbfffde70, invocation_hint=invocation_hint@entry=0xbfffde18) at gclosure.c:777 #8 0x4a06c56e in signal_emit_unlocked_R (node=node@entry=0x84d49f8, detail=0, instance=0x84e6458, emission_return=emission_return@entry=0xbfffdefc, instance_and_params=0xbfffde70) at gsignal.c:3586 #9 0x4a0740ab in g_signal_emit_valist (instance=instance@entry=0x84e6458, signal_id=signal_id@entry=52, detail=detail@entry=0, var_args=0xbfffdfc0 "\330\337\377\277ЉJ\b\260DN\b\b", var_args@entry=0xbfffdfbc "\370\351\024\t\330\337\377\277ЉJ\b\260DN\b\b") at gsignal.c:3340 #10 0x4a074654 in g_signal_emit (instance=instance@entry=0x84e6458, signal_id=52, detail=detail@entry=0) at gsignal.c:3386 #11 0x41895783 in gtk_widget_event_internal (widget=widget@entry=0x84e6458, event=event@entry=0x914e9f8) at gtkwidget.c:5017 #12 0x41895a56 in IA__gtk_widget_event (widget=widget@entry=0x84e6458, event=event@entry=0x914e9f8) at gtkwidget.c:4814 #13 0x418adf30 in IA__gtk_window_propagate_key_event (window=window@entry=0x84a0228, event=event@entry=0x914e9f8) at gtkwindow.c:5199 #14 0x418b1054 in gtk_window_key_press_event (widget=widget@entry=0x84a0228, event=0x914e9f8) at gtkwindow.c:5229 #15 0x417439ae in _gtk_marshal_BOOLEAN__BOXED (closure=0x84d49e0, return_value=0xbfffe18c, n_param_values=2, param_values=0xbfffe200, invocation_hint=0xbfffe1a8, marshal_data=0x418b1000 <gtk_window_key_press_event>) at gtkmarshalers.c:86 #16 0x4a058275 in g_type_class_meta_marshal (closure=0x84d49e0, return_value=0xbfffe18c, n_param_values=2, param_values=0xbfffe200, invocation_hint=0xbfffe1a8, marshal_data=0xcc) at gclosure.c:970 #17 0x4a0597de in g_closure_invoke (closure=closure@entry=0x84d49e0, return_value=return_value@entry=0xbfffe18c, n_param_values=2, param_values=param_values@entry=0xbfffe200, invocation_hint=invocation_hint@entry=0xbfffe1a8) at gclosure.c:777 #18 0x4a06c1ca in signal_emit_unlocked_R (node=node@entry=0x84d49f8, detail=0, instance=0x84a0228, emission_return=emission_return@entry=0xbfffe28c, instance_and_params=0xbfffe200) at gsignal.c:3624 #19 0x4a0740ab in g_signal_emit_valist (instance=instance@entry=0x84a0228, signal_id=signal_id@entry=52, detail=detail@entry=0, var_args=0xbfffe350 "h\343\377\277ЉJ\b\340\032N\b\b", var_args@entry=0xbfffe34c "\370\351\024\th\343\377\277ЉJ\b\340\032N\b\b") at gsignal.c:3340 #20 0x4a074654 in g_signal_emit (instance=instance@entry=0x84a0228, signal_id=52, detail=detail@entry=0) at gsignal.c:3386 #21 0x41895783 in gtk_widget_event_internal (widget=widget@entry=0x84a0228, event=event@entry=0x914e9f8) at gtkwidget.c:5017 #22 0x41895a56 in IA__gtk_widget_event (widget=widget@entry=0x84a0228, event=event@entry=0x914e9f8) at gtkwidget.c:4814 #23 0x4174174c in IA__gtk_propagate_event (widget=widget@entry=0x84a0228, event=event@entry=0x914e9f8) at gtkmain.c:2464 #24 0x41741ab0 in IA__gtk_main_do_event (event=0x914e9f8) at gtkmain.c:1685 #25 0x41b15619 in gdk_event_dispatch (source=source@entry=0x84a15f0, callback=0x0, user_data=0x0) at gdkevents-x11.c:2403 #26 0x49f51556 in g_main_dispatch (context=0x84a1638) at gmain.c:3066 #27 g_main_context_dispatch (context=context@entry=0x84a1638) at gmain.c:3642 #28 0x49f51920 in g_main_context_iterate (context=context@entry=0x84a1638, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713 #29 0x49f519e9 in g_main_context_iteration (context=0x84a1638, context@entry=0x0, may_block=may_block@entry=1) at gmain.c:3774 #30 0x417409a2 in IA__gtk_main_iteration () at gtkmain.c:1345 #31 0x08231965 in threaded_run (folder=0x86ff260, param=param@entry=0xbfffe5cc, result=result@entry=0xbfffe5b8, func=func@entry=0x8231a70 <connect_ssl_run>) at imap-thread.c:445 #32 0x0823475d in imap_threaded_connect_ssl (folder=folder@entry=0x86ff260, server=0x8711948 "poczta.interia.pl", port=port@entry=993) at imap-thread.c:577 #33 0x080e6dd3 in imap_session_new (account=0x86f4850, folder=0x86ff260) at imap.c:1154 #34 imap_session_get (folder=folder@entry=0x86ff260) at imap.c:1040 #35 0x080edfc0 in imap_change_flags (folder=0x86ff260, item=0x8729180, msginfo=0x8c25e98, newflags=81920) at imap.c:4899 #36 0x080ce6c0 in folder_item_change_msg_flags (item=0x8729180, msginfo=msginfo@entry=0x8c25e98, newflags=newflags@entry=81920) at folder.c:3882 #37 0x081a011a in procmsg_msginfo_unset_flags (msginfo=msginfo@entry=0x8c25e98, perm_flags=perm_flags@entry=3, tmp_flags=tmp_flags@entry=0) at procmsg.c:2068 #38 0x081b72ff in summary_msginfo_unset_flags (msginfo=0x8c25e98, flags=3, tmp_flags=0) at summaryview.c:3448 #39 0x081bc67c in msginfo_mark_as_read (summaryview=0x8630d08, msginfo=<optimized out>, row=0x8703530) at summaryview.c:3533 #40 0x081bc755 in msginfo_mark_as_read_timeout (data=data@entry=0x9174b98) at summaryview.c:3551 #41 0x49f52262 in g_timeout_dispatch (source=source@entry=0x8f1d940, callback=0x81bc700 <msginfo_mark_as_read_timeout>, user_data=0x9174b98) at gmain.c:4451 #42 0x49f51556 in g_main_dispatch (context=0x84a1638) at gmain.c:3066 #43 g_main_context_dispatch (context=context@entry=0x84a1638) at gmain.c:3642 #44 0x49f51920 in g_main_context_iterate (context=0x84a1638, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at gmain.c:3713 #45 0x49f51dc3 in g_main_loop_run (loop=loop@entry=0x8411980) at gmain.c:3907 #46 0x41740720 in IA__gtk_main () at gtkmain.c:1257 #47 0x08082e44 in main (argc=1, argv=0xbffff1e4) at main.c:1559 Frame #39 - msginfo_mark_as_read() - calls summary_msginfo_unset_flags(msginfo, MSG_NEW | MSG_UNREAD, 0) what passes control to IMAP session and then GTK main loop. GTK chooses to handle DELETE key press at this moment. This rebuilds list of messages in summaryview and turns old summaryview->selected (stored in frame #39 as "row") into garbage. Control passes back to frame #39 and msginfo_mark_as_read() at summaryview.c:3534 tries to use the just destroyed message held in "row", what causes a segmentation fault already known from backtraces in previous comments. Created attachment 1475 [details]
Workaround
Interesting. Dunno how often I've tried unsuccessfully to reproduce any of those gtkcmctree crashes. Is this with delayed "Mark messages as read" or with immediate mark as read? (In reply to comment #7) > > Is this with delayed "Mark messages as read" or with immediate mark as read? Delayed "Mark messages as read", in my case 1 second. It seems it is crucial to hit/click DELETE at the same time when the "Mark messages as read" timeout fires. I guess this issue is more likely to happen when connection to IMAP server is slow. I can readily reproduce this crash, by deleting unread messages (on an IMAP server, with 1 second delayed marked-as-read). Backtrace: #0 0x00000000005fa8c4 in gtk_cmctree_node_get_row_data (ctree=ctree@entry=0xa875d0, node=node@entry=0x1567520) at gtkcmctree.c:4514 #1 0x0000000000551cc3 in summary_set_row_marks (summaryview=0xc97880, row=0x1567520) at summaryview.c:3838 #2 0x0000000000557687 in msginfo_mark_as_read (summaryview=0xc97880, msginfo=<optimized out>, row=0x1567520) at summaryview.c:3542 #3 0x000000000055774b in msginfo_mark_as_read_timeout (data=0x12f0c80) at summaryview.c:3559 #4 0x00007ffff528f6e3 in ?? () from /usr/lib/libglib-2.0.so.0 #5 0x00007ffff528ec7a in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0 #6 0x00007ffff528f020 in ?? () from /usr/lib/libglib-2.0.so.0 #7 0x00007ffff528f342 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0 #8 0x00007ffff748c467 in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0 #9 0x000000000044836d in main (argc=1, argv=0x7fffffffe218) at main.c:1559 Now testing the patch from commment #6. Changes related to this bug have been committed. Please check latest Git and update the bug accordingly. You can also get the patch from: http://git.claws-mail.org/ ++ ChangeLog 2015-10-23 12:21:02.073484944 +0200 http://git.claws-mail.org/?p=claws.git;a=commitdiff;h=86631fd083a2d8d18997f86d312ecc970c885e29 Merge: 0adc584 3a611ed Author: Colin Leroy <colin@colino.net> Date: Fri Oct 23 12:21:01 2015 +0200 Merge branch 'master' of file:///home/git/claws http://git.claws-mail.org/?p=claws.git;a=commitdiff;h=3a611edf84b769aa067d8de3c6a7447d482f1c1c Author: Paul <paul@claws-mail.org> Date: Fri Oct 23 11:20:22 2015 +0100 fix bug 3375, 'Crash (SEGV) at gtkcmctree.c:4514 after deleting an unread message' Patch by Arthur Huillet. |