I have a very weird problem with core text, which sometimes randomly and sometimes reproducibly crashes my application. I use it to lay out and render a couple of pages. I do this asynchronously in the background to not block the user interface.
While this works fine in general, it sometimes crashes. All these crashes happen on the very same line:
framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)myText);
In fact, they also also seem to come from a similar point in the framework. I know you don't like it, but here's the head of a crash log:
Thread 8 Crashed:
0 ??? 0x0764f446 typeinfo for FT::data_stream + 6
1 libCGFreetype.A.dylib 0x076048b8 FT::font::copy_table(unsigned int) const + 94
2 libCGFreetype.A.dylib 0x0760b085 (anonymous namespace)::copy_table(void*, unsigned int) + 53
3 CoreText 0x00f9592e TBaseFont::CopyTable(unsigned int) const + 334
4 CoreText 0x00f670f6 TAATMorphTable::TAATMorphTable(TLine&, long, unsigned int) + 110
5 CoreText 0x00f6744c TAATMorphTableMorx::TAATMorphTableMorx(TLine&, long, TGlyphList<TDeletedGlyphIndex>&) + 54
6 CoreText 0x00f53eb5 TShapingEngine::ShapeGlyphs(TLine&, TCharStream const&, CFRange&, TGlyphList<TDeletedGlyphIndex>*) + 215
7 CoreText 0x00f579ce TTypesetter::FinishEncoding(TLine&, signed char, TGlyphList<TDeletedGlyphIndex>*) const + 260
8 CoreText 0x00f6664b TTypesetterAttrString::Initialize(__CFAttributedString const*) + 543
9 CoreText 0x00f6683e TTypesetterAttrString::TTypesetterAttrString(__CFAttributedString const*) + 158
10 CoreText 0x00f6102e TFramesetterAttrString::TFramesetterAttrString(__CFAttributedString const*) + 86
11 CoreText 0x00f6099e CTFramesetterCreateWithAttributedString + 78
...
All crashes I can remember have been in the FT::font::copy_table
function. Interestingly, the more complicated the font-requirements, the more frequent the crashes. Chinese text nearly always crash -- those fonts seem to be quite complicated.
Workaround: The workaround I found is to sequentialize the calls to CTFramesetterCreateWithAttributedString
in either the main queue or a separate one. The problem is that this single call makes up 79% of the total layout and rendering running time. So I would love to have it in multiple threads.
Question: Any Pros around that could help? To me this sounds like a race condition somewhere deep down. I didn't find anything stating that CoreText may not be used threaded. And I will file a bug tomorrow. However, I might also just have missed something. Any advice?
Thanks, Max
myText
to the function? E.g. ifmyText
is being changed while the framesetter is being created? – PernellCTFramesetterCreateWithAttributedString()
from multiple threads and see if it crashes. – Cytogenesis