Tk Source Code

View Ticket
Bounty program for improvements to Tcl and certain Tcl packages.
Ticket UUID: f9fa926666d8e06972b5f0583b07a3c98eaac0a0
Title: hangs or crashes when displaying astral chars
Type: Bug Version:
Submitter: ronaldoussoren Created on: 2020-11-08 13:23:36
Subsystem: (unused) Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2021-01-24 21:51:00
Resolution: Duplicate Closed By: jan.nijtmans
    Closed on: 2021-01-24 21:51:00
A number of Python users report that Tk scripts crash or hang when displaying astral unicode characters, such as emoji.

This happens on a number of platforms, including Linux and macOS. On Linux this appears to be related to the font used, the crash only happens when a coloured emoji font is present. 

I don't have detailed information on Tk versions at the moment. On macOS I can reproduce with Tk 8.6.8, which is the version of Tk included with the regular installers for macOS.

The Python issue about this:
User Comments: jan.nijtmans added on 2021-01-24 21:51:00:

Dup of [3767882e06]

marc_culler (claiming to be Marc Culler) added on 2020-11-10 20:43:46:
This is now fixed for macOS and the fix has been merged into core-8-6-branch
and main.

marc_culler (claiming to be Marc Culler) added on 2020-11-09 16:17:49:
@nab: The merge will handle the later commit to core-8-6-branch There will be
a merge to mac_styles eventually.  I don't think this will affect you unless
you have a label with an emoji.

nab added on 2020-11-09 15:35:47:
Hi Marc,
it seems that you didn't start this branch from the latest core8-6 branch...

also does this impact also mac_styles branch?

best regards,

marc_culler (claiming to be Marc Culler) added on 2020-11-09 14:52:14:
When I said "CGColorContext" I meant "CGColorRef".

marc_culler (claiming to be Marc Culler) added on 2020-11-09 13:40:17:
I was able to reproduce this with the current core-8-6-branch on macOS.

The crash occurred when creating a 16x16 bitmap of color "gray50" on line
1396 of tkButton.c.  This bitmap is needed for the button's stippleGC, except
it really isn't needed since the Mac port does not support stippling.  Also,
the butPtr->gray field, which is set to be a pointer to the 16x16 bitmap, is
only used when there is no disabled foreground color.  But in this case there
is a disabled foreground color.  So there were two separate reasons why there
was no need to be constructing this bitmap in the first place.  Nonetheless,
there should not be a crash when it is constructed.

Digging deeper into the cause of the crash, it appeared to be related to a
color caching scheme used only by macOS.  There is platform specific code
in xgc.c which initializes this cache and it is implemented in tkMacOSColor.c.
In my opinion this cache was an optimization which was probably costing more
CPU cycles than it saved.  The idea was to avoid creating a CGColorContext
for the foreground and background color of a GC (X graphics context) by
extending the GC struct to include pointers to two cached CGColorContexts.
The only function which used the cache was TkMacOSXCreateCGColor, which is
called in exactly one place, in tkFont.c.

The bugfix branch bug-f9fa926666-mac appears to fix this.  It removes the
platform specific code from xgc.c, removes the caching scheme from
tkMacOSXColor.c and adds a guard against a None tkwin in TkGetDoublePixels.
The guard prevents a crash which seemed to appear only after the cache was
removed.  This has nothing to do with colors, but was most likely an
initialization race condition that had been masked by the color caching.
(The crash could also be prevented by adding a print statement.)

fvogel added on 2020-11-08 14:13:46:

Duplicate of [b4d47f5419], as it seems.

ronaldoussoren added on 2020-11-08 13:26:17:
One way to reproduce the problem:

$ wish
% label .l -text 😄
% X Error of failed request:  BadLength (poly request too large or internal Xlib length error)
  Major opcode of failed request:  139 (RENDER)
  Minor opcode of failed request:  20 (RenderAddGlyphs)
  Serial number of failed request:  599
  Current serial number in output stream:  599