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 753992 - im-quartz discard_preedit segmentation fault
im-quartz discard_preedit segmentation fault
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Input Methods
3.16.x
Other Mac OS
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2015-08-23 15:31 UTC by Ethan Sherriff
Modified: 2016-08-07 17:03 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Crash Report (66.86 KB, text/plain)
2015-08-23 18:57 UTC, Ethan Sherriff
  Details
Output of crash run in lldb with debugging symbols. (2.92 KB, text/plain)
2015-08-25 18:34 UTC, Ethan Sherriff
  Details
Output of crash run in lldb with debugging symbols and backtrace! (8.80 KB, text/plain)
2015-08-25 19:32 UTC, Ethan Sherriff
  Details
Check that parent window is a GdkWindowQuartz. (2.31 KB, patch)
2015-09-19 19:34 UTC, John Ralls
committed Details | Review
Patch for gtk+ 2.24 (1.38 KB, patch)
2015-10-02 13:45 UTC, David Lechner
committed Details | Review
[PATCH 1/2] quartz: introduce gdk_quartz_window_is_quartz function (1.64 KB, patch)
2016-07-18 20:06 UTC, Kristian Rietveld
none Details | Review
[PATCH 2/2] imquartz: fix regression introduced by commit 4ba1fb (1.70 KB, patch)
2016-07-18 20:07 UTC, Kristian Rietveld
none Details | Review
Updated [PATCH 2/2] imquartz: fix regression introduced by commit 4ba1fb (2.14 KB, patch)
2016-08-07 14:59 UTC, Kristian Rietveld
accepted-commit_now Details | Review

Description Ethan Sherriff 2015-08-23 15:31:41 UTC
The function discard_preedit (modules/input/imquartz.c:237) causes a segmentation fault when the user clicks on a GtkEntry. I think this is also mentioned here (https://wiki.gnome.org/Projects/GTK+/OSX) under “input methods” as: “Bridged to native input methods with imquartz, but it breaks all text entry on Leopard.”.
Comment 1 Ethan Sherriff 2015-08-23 18:57:30 UTC
Created attachment 309895 [details]
Crash Report
Comment 2 John Ralls 2015-08-23 21:57:35 UTC
Can you rebuild gtk+ with -g in CFLAGS and crash it again? It would help a lot to have the actual line number of the crash. Even better would be to crash it in lldb so that you can find out exactly what variable is a bad pointer.
Comment 3 Ethan Sherriff 2015-08-25 18:34:19 UTC
Created attachment 309977 [details]
Output of crash run in lldb with debugging symbols.
Comment 4 John Ralls 2015-08-25 19:23:46 UTC
Tantalizingly close. After the crash, use the bt command to get a stack trace and paste that in.
Comment 5 Ethan Sherriff 2015-08-25 19:32:43 UTC
Created attachment 309979 [details]
Output of crash run in lldb with debugging symbols and backtrace!
Comment 6 Ethan Sherriff 2015-08-25 19:34:36 UTC
I've got there eventually, sorry for being so slow with all the debugging information!
Comment 7 Matthias Clasen 2015-08-27 02:27:15 UTC
Not an OS X developer, but the code in imquartz.c looks questionable to me - in several places, it uses the GDK_IS_WINDOW macro on the object returned by gdk_quartz_window_get_nsview(), which is not a GObject, so things are expected to crash...
Comment 8 John Ralls 2015-09-19 19:34:51 UTC
Created attachment 311677 [details] [review]
Check that parent window is a GdkWindowQuartz.

(In reply to Matthias Clasen from comment #7)
> Not an OS X developer, but the code in imquartz.c looks questionable to me -
> in several places, it uses the GDK_IS_WINDOW macro on the object returned by
> gdk_quartz_window_get_nsview(), which is not a GObject, so things are
> expected to crash...

Indeed. The guy who implemented that was convinced that gdk_quartz_window_get_nsview() sometimes returns a GdkWindow*, but I don't see how that could be unless the GdkWindow is sometimes not a GdkWindowQuartz.

This patch instead checks if the parent window is really a GdkWindowQuartz; as long as that's true the returned NSView should be either a GdkQuartzNSView or nil.

OP, please test to see if that resolves your crash.
Comment 9 David Lechner 2015-10-02 13:45:24 UTC
Created attachment 312565 [details] [review]
Patch for gtk+ 2.24

I came across the same crash in in gtk+ 2.24 (and also in quartz_set_cursor_location). gtk2 doesn't have the GDK_IS_QUARTZ_WINDOW macro, so I just left that part out.

I have tested that the fix does indeed work in discard_preedit() and quartz_set_cursor_location().
Comment 10 Tom Schoonjans 2015-11-01 11:14:52 UTC
Is there a reason why this patch didn't make it into 3.18.2? It looks like it was committed in master several weeks before this version was released.

It's a pretty important one since it seems to break a lot of gtk apps running on El Capitan.
Comment 11 John Ralls 2015-11-02 01:41:20 UTC
That's because Matthias didn't backport it to the gtk-3-18 branch. I just did so, so it will be in Gtk-3.18.3.
Comment 12 Tom Schoonjans 2015-11-02 07:09:04 UTC
Thanks John!
Comment 13 Kristian Rietveld 2016-07-18 20:05:55 UTC
(In reply to David Lechner from comment #9)
> Created attachment 312565 [details] [review] [review]
> Patch for gtk+ 2.24
> 
> I came across the same crash in in gtk+ 2.24 (and also in
> quartz_set_cursor_location). gtk2 doesn't have the GDK_IS_QUARTZ_WINDOW
> macro, so I just left that part out.

These checks cannot just be left out. While upgrading GTK+ 2.x for GIMP, we found that this commit is causing crashes.

I will be attaching two patches that I would like to commit to gtk-2-24 to fix this issue. The fix is to re-introduce the checks in a different way.
Comment 14 Kristian Rietveld 2016-07-18 20:06:50 UTC
Created attachment 331745 [details] [review]
[PATCH 1/2] quartz: introduce gdk_quartz_window_is_quartz function
Comment 15 Kristian Rietveld 2016-07-18 20:07:17 UTC
Created attachment 331746 [details] [review]
[PATCH 2/2] imquartz: fix regression introduced by commit 4ba1fb
Comment 16 John Ralls 2016-07-18 23:47:35 UTC
Wouldn't it be cleaner and simpler to just put that check in gdk_quartz_window_get_nsview() and return NULL if it it fails? Is there a case somewhere where calling gdk_quartz_window_get_nsview on a GdkWindow* that isn't a GdkWindowImplQuartz* would somehow return a usable value?

 NSView *
 gdk_quartz_window_get_nsview (GdkWindow *window)
 {
-  if (GDK_WINDOW_DESTROYED (window))
+  if (!GDK_WINDOW_IS_QUARTZ (window) || GDK_WINDOW_DESTROYED (window))
     return NULL;
 
   return ((GdkWindowImplQuartz *)window->impl)->view;
 }

Then imquartz.c would need only add two checks for nsview == NULL.
Comment 17 Matthias Clasen 2016-07-25 12:58:44 UTC
Just make the macro public, instead of adding oddd function wrappers; look at what the x11 and wayland backends do. At least, thats my opinion.
Comment 18 Kristian Rietveld 2016-07-25 15:20:02 UTC
(In reply to Matthias Clasen from comment #17)
> Just make the macro public, instead of adding oddd function wrappers; look
> at what the x11 and wayland backends do. At least, thats my opinion.

The macro is already public in 3.x and there are no problems there. In 2.x, the macro involves GdkWindowImpl which is all kept private.

I chose for a function wrapper, because the win32 backend has that too, probably to work around the same problem:

gboolean      gdk_win32_window_is_win32 (GdkWindow *window);

gboolean
gdk_win32_window_is_win32 (GdkWindow *window)
{
  return GDK_WINDOW_IS_WIN32 (window);
}
Comment 19 Kristian Rietveld 2016-07-25 15:21:41 UTC
(In reply to John Ralls from comment #16)
> Wouldn't it be cleaner and simpler to just put that check in
> gdk_quartz_window_get_nsview() and return NULL if it it fails? Is there a
> case somewhere where calling gdk_quartz_window_get_nsview on a GdkWindow*
> that isn't a GdkWindowImplQuartz* would somehow return a usable value?

Simpler yes, cleaner I am not sure. I guess in theory the _get_nsview function needs a g_return_val_if_fail check for GDK_WINDOW_IS_QUARTZ(). If you want a silent check, which is what we want, we need the separate macro or function.
Comment 20 John Ralls 2016-07-25 16:10:48 UTC
(In reply to Kristian Rietveld from comment #19)
> (In reply to John Ralls from comment #16)
> > Wouldn't it be cleaner and simpler to just put that check in
> > gdk_quartz_window_get_nsview() and return NULL if it it fails? Is there a
> > case somewhere where calling gdk_quartz_window_get_nsview on a GdkWindow*
> > that isn't a GdkWindowImplQuartz* would somehow return a usable value?
> 
> Simpler yes, cleaner I am not sure. I guess in theory the _get_nsview
> function needs a g_return_val_if_fail check for GDK_WINDOW_IS_QUARTZ(). If
> you want a silent check, which is what we want, we need the separate macro
> or function.

What I proposed is silent, though I agree that it would be better to log the error. It's cleaner because returning NULL instead of some undefined pointer is surely correct for _get_nsview(), as that will force the inevitable crash to be closer to its source.
Comment 21 Kristian Rietveld 2016-08-07 14:59:27 UTC
Created attachment 332889 [details] [review]
Updated [PATCH 2/2] imquartz: fix regression introduced by commit 4ba1fb

As suggested in the latest comment, put an assertion in gdk_quartz_window_get_nsview() so we also avoid returning a garbled pointer.
Comment 22 John Ralls 2016-08-07 15:11:12 UTC
Comment on attachment 332889 [details] [review]
Updated [PATCH 2/2] imquartz: fix regression introduced by commit 4ba1fb

Looks good, thanks.
Comment 23 Kristian Rietveld 2016-08-07 17:03:12 UTC
Pushed to gtk-2-24. I leave it up to you whether you also want to have it pushed to master.


commit 899147d6d06d375d992ae28d250329b7b35a3ab4
Author: Kristian Rietveld <kris@loopnest.org>
Date:   Mon Jul 18 22:00:48 2016 +0200

    imquartz: fix regression introduced by commit 4ba1fb

    In the preceding fix, the checks involving GDK_IS_QUARTZ_WINDOW macros
    were left out. These checks are in fact crucial, because these functions
    are sometimes called with non-quartz functions as the original comments
    in the code do indicate. Therefore, reintroduce these checks. This
    fixes a crash in GIMP.

commit 6b8e20a05cde19500c0fb97576cc22c3ef1088dc
Author: Kristian Rietveld <kris@loopnest.org>
Date:   Mon Jul 18 21:59:28 2016 +0200

    quartz: introduce gdk_quartz_window_is_quartz function

    This function can be used to check whether a GdkWindow is a quartz
    window. It is equivalent to it's win32 counterpart. The function
    is necessary because the macro necessary for this check is private.