Sporadical AU plugin issue with juce::OSXTypeface::getGlyphPositions

Hello everybody.

I have an issue that is difficult for me to track down since it only happens sporadically and only in the AU version of my plugin on OSX. I would really appreciate any hint that points me in the right direction to fix it.

From what I see in the crashlog it seems that it caused by a component that I have subclassed from juce::ComboBox. During paint a lot of AppKit stuff is done but in the end something goes wrong in juce::GlyphArrangement::addCurtailedLineOfText and finally juce::OSXTypeface::getGlyphPositions.

The only two suspicions that I have at the moment are:

  • Maybe the String in the ComboBox item is not a valid UTF8 String. But from what I see this would have been rejected in the String class before and I do not see combobox strings that would cause a problem here.
  • Maybe it is a multithreading issue with loading the Font? But why would this only happen on OSX? And I am creating the Typeface with createSystemTypefaceFor in the constructor of my LookAndFeel instance.

Any ideas? And here the crashlog - sorry for the long post.

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000126ecc004
Exception Note: EXC_CORPSE_NOTIFY

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [6845]

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libFontParser.dylib                    0x00007fff43d6cb08 TSFNTFont::GetTableOffset(unsigned int, unsigned long&) const + 58
1   libFontParser.dylib                    0x00007fff43d6ca8b TSFNTFont::GetTable(unsigned int, unsigned long&) const + 43
2   libFontParser.dylib                    0x00007fff43dac2e8 TTrueTypeMemoryFont::GetTable(unsigned int, unsigned long&) const + 114
3   libFontParser.dylib                    0x00007fff43d6fcd3 TsfntTable::TsfntTable(TSFNTFont const&, unsigned int) + 51
4   libFontParser.dylib                    0x00007fff43d71949 TcmapUnicodeTable::TcmapUnicodeTable(TSFNTFont const&) + 31
5   libFontParser.dylib                    0x00007fff43d9ea78 TSFNTFont::GetGlyphsForCharacterRange(unsigned short*, CFRange) const + 42
6   libFontParser.dylib                    0x00007fff43dc44aa FPFontGetGlyphsForCharacterRange + 154
7   com.apple.CoreText                 0x00007fff475b760c TBaseFont::GetGlyphsForCharacterRange(CFRange, unsigned short*) const + 74
8   com.apple.CoreText                 0x00007fff47599aae TASCIIDataCache::TASCIIDataCache(TFont const*) + 74
9   com.apple.CoreText                 0x00007fff47599a2e TFont::InitASCIIDataCache() const + 34
10  com.apple.CoreText               0x00007fff475ccdfe TASCIIEncoder::Encode() + 82
11  com.apple.CoreText               0x00007fff475cc7e3 TGlyphEncoder::EncodeChars(CFRange, TAttributes const&, TGlyphEncoder::Fallbacks) + 1189
12  com.apple.CoreText               0x00007fff475cbe82 TTypesetterAttrString::Initialize(__CFAttributedString const*) + 238
13  com.apple.CoreText               0x00007fff475cbb64 TTypesetterAttrString::TTypesetterAttrString(__CFAttributedString const*, __CFDictionary const*) + 176
14  com.apple.CoreText               0x00007fff475cb9ae CTLineCreateWithAttributedString + 60
15  com.vastdynamics.VAST2                     0x00000001209bdb5e juce::OSXTypeface::getGlyphPositions(juce::String const&, juce::Array<int, juce::DummyCriticalSection, 0>&, juce::Array<float, juce::DummyCriticalSection, 0>&) + 238
16  com.vastdynamics.VAST2                     0x00000001209c1d95 juce::Font::getGlyphPositions(juce::String const&, juce::Array<int, juce::DummyCriticalSection, 0>&, juce::Array<float, juce::DummyCriticalSection, 0>&) const + 117
17  com.vastdynamics.VAST2                     0x00000001209c1578 juce::GlyphArrangement::addCurtailedLineOfText(juce::Font const&, juce::String const&, float, float, float, bool) + 88
18  com.vastdynamics.VAST2                     0x0000000120a6324d juce::TextEditor::TextHolderComponent::paint(juce::Graphics&) + 1005
19  com.vastdynamics.VAST2                     0x0000000120a7bf39 juce::Component::paintComponentAndChildren(juce::Graphics&) + 137
20  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
21  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
22  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
23  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
24  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
25  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
26  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
27  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
28  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
29  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
30  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
31  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
32  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
33  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
34  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
35  com.vastdynamics.VAST2                     0x0000000120a7c2ea juce::Component::paintComponentAndChildren(juce::Graphics&) + 1082
36  com.vastdynamics.VAST2                     0x0000000120aa4a3f juce::ComponentPeer::handlePaint(juce::LowLevelGraphicsContext&) + 719
37  com.vastdynamics.VAST2                     0x0000000120a9e3c6 juce::JuceNSViewClass::drawRect(objc_object*, objc_selector*, CGRect) + 502
38  com.apple.AppKit                    0x00007fff42f38c29 _NSViewDrawRect + 66
39  com.apple.AppKit                    0x00007fff42f23a22 -[NSView _drawRect:clip:] + 1745
40  com.apple.logic10                   0x000000010a5f7f34 0x109bdc000 + 10600244
41  com.apple.AppKit                    0x00007fff42f218e6 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 4808
42  com.apple.AppKit                    0x00007fff42f21226 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3080
43  com.apple.AppKit                    0x00007fff42f21226 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3080
44  com.apple.AppKit                    0x00007fff42f21226 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3080
45  com.apple.AppKit                    0x00007fff42f21226 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3080
46  com.apple.AppKit                    0x00007fff42f21226 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3080
47  com.apple.AppKit                    0x00007fff42f21226 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3080
48  com.apple.AppKit                    0x00007fff42f21226 -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3080
49  com.apple.AppKit                    0x00007fff42f1df2a -[NSView _oldDisplayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 1887
50  com.apple.AppKit                    0x00007fff42f1d569 -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 253
51  com.apple.AppKit                    0x00007fff42f1a152 -[NSView displayIfNeeded] + 1300
52  com.apple.AppKit                    0x00007fff42f16ee8 -[NSWindow displayIfNeeded] + 283
53  com.apple.AppKit                    0x00007fff42f16d27 __NSWindowGetDisplayCycleObserverForDisplay_block_invoke + 722
54  com.apple.AppKit                    0x00007fff42f11e2a NSDisplayCycleObserverInvoke + 170
55  com.apple.AppKit                    0x00007fff42f1199f NSDisplayCycleFlush + 1073
56  com.apple.QuartzCore          0x00007fff5087225b CA::Transaction::run_commit_handlers(CATransactionPhase) + 49
57  com.apple.QuartzCore          0x00007fff50871c22 CA::Transaction::commit() + 186
58  com.apple.AppKit                    0x00007fff42f11305 __65+[CATransaction(NSCATransaction) NS_setFlushesWithDisplayRefresh]_block_invoke + 274
59  com.apple.CoreFoundation                  0x00007fff4591a8ed __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
60  com.apple.CoreFoundation                  0x00007fff4591a822 __CFRunLoopDoObservers + 452
61  com.apple.CoreFoundation                  0x00007fff458bc345 __CFRunLoopRun + 1166
62  com.apple.CoreFoundation                  0x00007fff458bbc64 CFRunLoopRunSpecific + 463
63  com.apple.HIToolbox             0x00007fff44b52ab5 RunCurrentEventLoopInMode + 293
64  com.apple.HIToolbox             0x00007fff44b526f4 ReceiveNextEventCommon + 371
65  com.apple.HIToolbox             0x00007fff44b52568 _BlockUntilNextEventMatchingListInModeWithFilter + 64
66  com.apple.AppKit                    0x00007fff42e0d363 _DPSNextEvent + 997
67  com.apple.AppKit                    0x00007fff42e0c102 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1362
68  com.apple.logic10                   0x000000010b261a7d 0x109bdc000 + 23616125
69  com.vastdynamics.VAST2                     0x00000001209ba94c juce::MessageManager::runDispatchLoopUntil(int) + 252
70  com.vastdynamics.VAST2                     0x0000000120a722bd juce::Component::runModalLoop() + 477
71  com.vastdynamics.VAST2                     0x00000001207c5e0d VASTComboPreset::showPopup() + 4525
72  com.vastdynamics.VAST2                     0x00000001209b797c juce::MessageQueue::deliverNextMessage() + 236
73  com.vastdynamics.VAST2                     0x00000001209b784a juce::MessageQueue::runLoopSourceCallback(void*) + 26
74  com.apple.CoreFoundation                  0x00007fff458d9395 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
75  com.apple.CoreFoundation                  0x00007fff458d933b __CFRunLoopDoSource0 + 108
76  com.apple.CoreFoundation                  0x00007fff458bcdd1 __CFRunLoopDoSources0 + 195
77  com.apple.CoreFoundation                  0x00007fff458bc37a __CFRunLoopRun + 1219
78  com.apple.CoreFoundation                  0x00007fff458bbc64 CFRunLoopRunSpecific + 463
79  com.apple.HIToolbox             0x00007fff44b52ab5 RunCurrentEventLoopInMode + 293
80  com.apple.HIToolbox             0x00007fff44b526f4 ReceiveNextEventCommon + 371
81  com.apple.HIToolbox             0x00007fff44b52568 _BlockUntilNextEventMatchingListInModeWithFilter + 64
82  com.apple.AppKit                    0x00007fff42e0d363 _DPSNextEvent + 997
83  com.apple.AppKit                    0x00007fff42e0c102 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1362
84  com.apple.logic10                   0x000000010b261a7d 0x109bdc000 + 23616125
85  com.apple.AppKit                    0x00007fff42e06165 -[NSApplication run] + 699
86  com.apple.AppKit                    0x00007fff42df58a3 NSApplicationMain + 780
87  com.apple.logic10                   0x000000010a5f825d 0x109bdc000 + 10601053
88  libdyld.dylib                               0x00007fff72b0ded9 start + 1

Any ideas? Similar experiences? I am lost there …

Just got the same issue (in a vst, with the latest tip of the develop branch). Any idea what might be the cause?

|#0|0x00007fff3b2ce83a in TSFNTFont::GetTableOffset(unsigned int, unsigned long&) const ()|
|---|---|
|#1|0x00007fff3b2ce777 in TSFNTFont::GetTable(unsigned int, unsigned long&) const ()|
|#2|0x00007fff3b30d913 in TTrueTypeMemoryFont::GetTable(unsigned int, unsigned long&) const ()|
|#3|0x00007fff3b2d1a53 in TsfntTable::TsfntTable(TSFNTFont const&, unsigned int) ()|
|#4|0x00007fff3b2d36bb in TcmapUnicodeTable::TcmapUnicodeTable(TSFNTFont const&) ()|
|#5|0x00007fff3b2ffff8 in TSFNTFont::GetGlyphsForCharacterRange(unsigned short*, CFRange) const ()|
|#6|0x00007fff3b3254be in FPFontGetGlyphsForCharacterRange ()|
|#7|0x00007fff3ea07798 in TBaseFont::GetGlyphsForCharacterRange(CFRange, unsigned short*) const ()|
|#8|0x00007fff3e9ecb4e in TASCIIDataCache::TASCIIDataCache(TFont const*) ()|
|#9|0x00007fff3e9ecacc in TFont::InitASCIIDataCache() const ()|
|#10|0x00007fff3ea1c5ac in TASCIIEncoder::Encode() ()|
|#11|0x00007fff3ea1bf8e in TGlyphEncoder::EncodeChars(CFRange, TAttributes const&, TGlyphEncoder::Fallbacks) ()|
|#12|0x00007fff3ea1b626 in TTypesetterAttrString::Initialize(__CFAttributedString const*) ()|
|#13|0x00007fff3ea1b379 in TTypesetterAttrString::TTypesetterAttrString(__CFAttributedString const*, __CFDictionary const*) ()|
|#14|0x00007fff3ea1b1ca in CTLineCreateWithAttributedString ()|
|#15|0x000000012351dcc2 in juce::OSXTypeface::getGlyphPositions(juce::String const&, juce::Array<int, juce::DummyCriticalSection, 0>&, juce::Array<float, juce::DummyCriticalSection, 0>&) at PluginName/JUCE/modules/juce_graphics/native/juce_mac_Fonts.mm:657|
|#16|0x00000001234b6332 in juce::Font::getGlyphPositions(juce::String const&, juce::Array<int, juce::DummyCriticalSection, 0>&, juce::Array<float, juce::DummyCriticalSection, 0>&) const at PluginName/JUCE/modules/juce_graphics/fonts/juce_Font.cpp:651|
|#17|0x00000001234596ef in juce::GlyphArrangement::addCurtailedLineOfText(juce::Font const&, juce::String const&, float, float, float, bool) at PluginName/JUCE/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp:152|
|#18|0x0000000123458b33 in juce::GlyphArrangement::addLineOfText(juce::Font const&, juce::String const&, float, float) at PluginName/JUCE/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp:141|
|#19|0x000000012345a178 in juce::GlyphArrangement::addFittedText(juce::Font const&, juce::String const&, float, float, float, float, juce::Justification, int, float) at PluginName/JUCE/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp:324|
|#20|0x0000000123459fac in juce::Graphics::drawFittedText(juce::String const&, juce::Rectangle<int>, juce::Justification, int, float) const at PluginName/JUCE/modules/juce_graphics/contexts/juce_GraphicsContext.cpp:326|
|#21|0x000000012345a44e in juce::Graphics::drawFittedText(juce::String const&, int, int, int, int, juce::Justification, int, float) const at PluginName/JUCE/modules/juce_graphics/contexts/juce_GraphicsContext.cpp:342|
1 Like

Have seen the same recently using the latest Master branch and AU plugins. Happens so sporadically that I haven’t managed to find the root cause… but good to know I’m not the only one! I am using a custom font stored as binary data, in case that matters.

1 Like

I am also having the same issue with a custom subclass of juce::ComboBox and a custom font stored as binary data. Was this sorted yet?

Are you using a recent version of JUCE? I fixed a couple of issues to do with text rendering on macOS in the last few months:

If you’re not using the latest version of JUCE, please try updating and see if the issue persists. If it does, please provide a stack trace at the point of the crash. If you’re able to test with Address Sanitizer and provide its output at the point of the crash, that will help us to track down the issue more quickly. Providing a small sample program that demonstrates the problem would also be very helpful.

Thanks, I’m a couple of months behind these changes. Will update and share the results if needed.