From 443b92e16a0648dceb1d01efa3b26dd6494d2397 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Mon, 7 Aug 2017 10:15:46 +0300 Subject: [PATCH] Ticket #3846: fix crash on slow startup... ...because of access to free'd viewer in the idle hooks execution. Signed-off-by: Andrew Borodin --- src/viewer/actions_cmd.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/viewer/actions_cmd.c b/src/viewer/actions_cmd.c index 37fddd244..5322bf572 100644 --- a/src/viewer/actions_cmd.c +++ b/src/viewer/actions_cmd.c @@ -692,6 +692,27 @@ mcview_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void * { delete_hook (&select_file_hook, mcview_hook); + /* + * In some cases when mc startup is very slow and one panel is in quick vew mode, + * @view is registered in two hook lists at the same time: + * mcview_callback (MSG_INIT) -> add_hook (&select_file_hook) + * mcview_hook () -> add_hook (&idle_hook). + * If initialization of file manager is not completed yet, but user switches + * panel mode from qick view to another one (by pressing C-x q), the following + * occurs: + * view hook is deleted from select_file_hook list via following call chain: + * set_display_type (view_listing) -> widget_replace () -> + * send_message (MSG_DESTROY) -> mcview_callback (MSG_DESTROY) -> + * delete_hook (&select_file_hook); + * @view object is free'd: + * set_display_type (view_listing) -> g_free (old_widget); + * but @view still is in idle_hook list and tried to be executed: + * frontend_dlg_run () -> execute_hooks (idle_hook). + * Thus here we have access to free'd @view object. To prevent this, remove view hook + * from idle_hook list. + */ + delete_hook (&idle_hook, mcview_hook); + if (mc_global.midnight_shutdown) mcview_ok_to_quit (view); }