Hello Antonio (and list),

while testing a plot functionality I encountered a crash when destroying a 
dialog.
It is a Gtk-related issue and happens due to a Gtk signal handler being called 
on
an invalid data.

I have prepared and tested a fix for the problem. The patch is attached to this
message and also published on github:
https://github.com/blueowl04/iup-github/commits/gtk-crash-fix

The commit message describes a test case and also contains a call stack
grabbed by valgrind.

Best regards,
blueowl
From a4f3e819472843f271538aa62c8a6c0da5d2799e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= <[email protected]>
Date: Tue, 3 Oct 2017 17:14:47 +0200
Subject: [PATCH] gtk: fix a possible crash when destroying a dialog
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

gtkDialogUnMapMethod() should disconnect GTK signal handlers connected in
gtkDialogMapMethod(). Forgetting to do that may result in calling a handler
for already destroyed data (ih).

Test case:
* run an application displaying a plot (e.g. an IUP example)
* right click the plot to open the context menu
* select "Data Set Properties..."
* click a button to open color dialog
* click Cancel to close the dialog
* click Cancel to close the Properties dialog
* ---> application crashes

Trace from valgrind:
==18414== Invalid read of size 8
==18414==    at 0x62B42A2: iTableFindItem (iup_table.c:639)
==18414==    by 0x62B3A52: iupTableGetTyped (iup_table.c:377)
==18414==    by 0x62B3964: iupTableGetFunc (iup_table.c:357)
==18414==    by 0x625DDFA: IupGetCallback (iup_callback.c:45)
==18414==    by 0x62669C0: IupDestroy (in /home/jirka/code/github/iup-github/lib/Linux412_64/libiup.so)
==18414==    by 0x62F5E1B: gtkDialogChildDestroyEvent (iupgtk_dialog.c:56)
==18414==    by 0x7D8AEAC: g_closure_invoke (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x7D9D4AD: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x7DA5C84: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x7DA669E: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x6B6276D: ??? (in /usr/lib/libgtk-3.so.0.2200.21)
==18414==    by 0x6B7679A: ??? (in /usr/lib/libgtk-3.so.0.2200.21)
==18414==  Address 0x11f966f0 is 16 bytes inside a block of size 32 free'd
==18414==    at 0x4C2E14B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18414==    by 0x62B330E: iupTableDestroy (iup_table.c:194)
==18414==    by 0x626668F: iHandleDestroy (in /home/jirka/code/github/iup-github/lib/Linux412_64/libiup.so)
==18414==    by 0x62935D4: iParamColorButton_CB (iup_getparam.c:437)
==18414==    by 0x62D6EFB: gtkButtonClicked (iupgtk_button.c:346)
==18414==    by 0x7D8B0E5: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x7DA5F6E: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x7DA669E: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x68F90ED: ??? (in /usr/lib/libgtk-3.so.0.2200.21)
==18414==    by 0x68F9145: ??? (in /usr/lib/libgtk-3.so.0.2200.21)
==18414==    by 0x7D8B0E5: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x7DA5F6E: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==  Block was alloc'd at
==18414==    at 0x4C2CE5F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18414==    by 0x62B30A5: iupTableCreateSized (iup_table.c:123)
==18414==    by 0x62B307A: iupTableCreate (iup_table.c:117)
==18414==    by 0x6266735: iupObjectCreate (in /home/jirka/code/github/iup-github/lib/Linux412_64/libiup.so)
==18414==    by 0x627DB67: IupColorDlg (iup_colordlg.c:25)
==18414==    by 0x6293404: iParamColorButton_CB (iup_getparam.c:412)
==18414==    by 0x62D6EFB: gtkButtonClicked (iupgtk_button.c:346)
==18414==    by 0x7D8B0E5: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x7DA5F6E: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x7DA669E: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x68F90ED: ??? (in /usr/lib/libgtk-3.so.0.2200.21)
==18414==    by 0x68F9145: ??? (in /usr/lib/libgtk-3.so.0.2200.21)
==18414==
==18414== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==18414==  Access not within mapped region at address 0x108
==18414==    at 0x62B42BE: iTableFindItem (iup_table.c:641)
==18414==    by 0x62B3A52: iupTableGetTyped (iup_table.c:377)
==18414==    by 0x62B3964: iupTableGetFunc (iup_table.c:357)
==18414==    by 0x625DDFA: IupGetCallback (iup_callback.c:45)
==18414==    by 0x62669C0: IupDestroy (in /home/jirka/code/github/iup-github/lib/Linux412_64/libiup.so)
==18414==    by 0x62F5E1B: gtkDialogChildDestroyEvent (iupgtk_dialog.c:56)
==18414==    by 0x7D8AEAC: g_closure_invoke (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x7D9D4AD: ??? (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x7DA5C84: g_signal_emit_valist (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x7DA669E: g_signal_emit (in /usr/lib/libgobject-2.0.so.0.5200.3)
==18414==    by 0x6B6276D: ??? (in /usr/lib/libgtk-3.so.0.2200.21)
==18414==    by 0x6B7679A: ??? (in /usr/lib/libgtk-3.so.0.2200.21)

Signed-off-by: Jiří KlimeÅ¡ <[email protected]>
---
 src/gtk/iupgtk_dialog.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/gtk/iupgtk_dialog.c b/src/gtk/iupgtk_dialog.c
index 0de03a48..6195540e 100644
--- a/src/gtk/iupgtk_dialog.c
+++ b/src/gtk/iupgtk_dialog.c
@@ -995,6 +995,7 @@ static int gtkDialogMapMethod(Ihandle* ih)
 static void gtkDialogUnMapMethod(Ihandle* ih)
 {
   GtkWidget* inner_parent;
+  InativeHandle* parent;
 #if GTK_CHECK_VERSION(2, 10, 0) && !GTK_CHECK_VERSION(3, 14, 0)
   GtkStatusIcon* status_icon;
 #endif
@@ -1014,6 +1015,12 @@ static void gtkDialogUnMapMethod(Ihandle* ih)
   }
 #endif
 
+  /* disconnect signal handlers */
+  g_signal_handlers_disconnect_by_data(G_OBJECT(ih->handle), ih);
+  parent = iupDialogGetNativeParent(ih);
+  if (parent)
+    g_signal_handlers_disconnect_by_func(G_OBJECT(parent), gtkDialogChildDestroyEvent, ih);
+
   inner_parent = gtk_bin_get_child((GtkBin*)ih->handle);
   gtk_widget_unrealize(inner_parent);
   gtk_widget_destroy(inner_parent);  
-- 
2.14.2

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Iup-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/iup-users

Reply via email to