GNOME Bugzilla – Bug 737842
SIGSEGV when GVfsChannel is blocked
Last modified: 2014-10-09 09:20:45 UTC
Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7de12a5 in g_vfs_job_emit_finished (job=0x0) at gvfsjob.c:322 322 g_assert (!job->finished); g_vfs_channel_send_reply is executed if channel got new request and backend->priv->block_requests = TRUE. Consequently send_reply_cb is executed and crashed if channel->priv->current_job = NULL. It is pretty similar to the bug 675181 and attachement 240642.
+ Trace 234170
See downstream bug for additional debug info: https://bugzilla.redhat.com/show_bug.cgi?id=1149760
Created attachment 288044 [details] [review] gvfschannel: do not crash when channel is blocked Backend could crash, when channel is blocked and got new request unless current job is set. Therefor send_reply_cb is called without current job and cause following error: Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7de12a5 in g_vfs_job_emit_finished (job=0x0) at gvfsjob.c:322 322 g_assert (!job->finished); To fix the problem be sure error job is set.
Created attachment 288045 [details] [review] gvfschannel: do not call close job if channel is blocked This is necessary to avoid SIGPIPE on send_replay.
Created attachment 288046 [details] [review] gvfschannel: don't abort when finalizing Remove g_assert (channel->priv->backend_handle == NULL), because it could happen when backend is force unmounted.
Ross notices that SIGPIPE is ignored in deamon_init: #ifdef SIGPIPE /* Ignore SIGPIPE to avoid killing daemons on cancelled transfer * * See https://bugzilla.gnome.org/show_bug.cgi?id=649041 * */ signal (SIGPIPE, SIG_IGN); #endif So we have to figure out why it isn't ignored properly: Program received signal SIGPIPE, Broken pipe.
+ Trace 234198
Thread 140737144416000 (LWP 22436)
The SIGPIPE is caused due to gdb rewrites signal handlers, however the patch is still useful. We don't want new jobs to be run if channel is blocked when force unmounting.
Review of attachment 288044 [details] [review]: ::: daemon/gvfschannel.c @@ +329,3 @@ + job = NULL; + error = g_error_new_literal (G_IO_ERROR, G_IO_ERROR_CLOSED, + _("Channel blocked")); This seems to leak req->data.
Review of attachment 288045 [details] [review]: As we ignore sigpipe outside gdb i don't think this is a good idea. It complicates the code for no real reason imho.
Review of attachment 288046 [details] [review]: looks ok
Review of attachment 288045 [details] [review]: Actually, you're right, we should probably not start a new close job in the backend while unmounting...
Review of attachment 288045 [details] [review]: Change the commit message though.
Comment on attachment 288046 [details] [review] gvfschannel: don't abort when finalizing commit 535a192f3fbba97eb2f2f1fdc2c8909a26a89fdb
Comment on attachment 288045 [details] [review] gvfschannel: do not call close job if channel is blocked commit ace3084150b2d4ac8c6719061365c2bc9baf5edb with changed commit message
Comment on attachment 288044 [details] [review] gvfschannel: do not crash when channel is blocked commit 3abf2f64900c8dfb033af748c0aadc0cf61523c5 with additional g_free
Thanks for the reviews!