单声道/Xamarin.iOS SIGTRAP gc.safepoint_poll 崩溃

Mono / Xamarin.iOS SIGTRAP gc.safepoint_poll crash

我在生产中有一个 Xamarin.iOS 应用程序,它使用大量带有音色的 MIDI。我正在使用 appcenter.ms 来捕获崩溃和记录事件。我无法重新创建和排除故障的用户偶尔会发生一次崩溃(而且很少发生)。根据崩溃报告,它发生在许多不同的设备和 iOS 版本中。这似乎是随机的。我还使用了带有面包屑的 Sentry.io,但是没有任何东西用我可以与这次崩溃相匹配的相同 date/time 标记记录在那里。垃圾收集器似乎参与其中,它似乎也与加载声音字体有关(即来自堆栈跟踪的 GlobalState::LoadInstrumentFromDLSCollection)。

有没有人对可能导致此问题的原因或如何追踪它有任何建议?垃圾收集器和底层低级 C++ 操作之间是否发生了一些不利的交互?有没有办法确保垃圾收集器不会在加载声音字体的过程中尝试 运行?

这是我加载 soundfonts 的代码,然后是来自 appcenter 的完整堆栈跟踪(顺便说一句,发生这种情况时 try/catch 实际上没有捕获任何异常,但我还是包含了它)。当然,我可能认为这段代码是罪魁祸首是错误的,但这是唯一加载声音字体的代码。

我用谷歌搜索了每个 iOS 相关的 c++ 调用(例如 SampleManager::InsertSample(unsigned long, Sample*)),但找不到其他人报告类似问题。

public bool LoadInstrument(string soundFontPath)
        {
           
            if (_currentInstrumentPath != soundFontPath)
                _currentInstrumentPath = soundFontPath;
            try
            {
                var soundFontUrl = CFUrl.FromFile(soundFontPath);
                if (_samplerUnit == null)
                    return false;
                if (!_samplerUnit.IsPlaying)
                    _samplerUnit.LoadInstrument(new SamplerInstrumentData(soundFontUrl, InstrumentType.SF2Preset)
                    {
                        BankLSB = SamplerInstrumentData.DefaultBankLSB,
                        BankMSB = SamplerInstrumentData.DefaultMelodicBankMSB,
                        PresetID = (byte)0
                    });
            }
            catch (Exception ex)
            {
                App.DiagnosticsLogger.WriteLog(ex);
                _eventAggregator.PublishOnUIThreadAsync(new TUE.Messages.ExceptionThrownMessage
                {
                    SourceClass = "MidiSequencePlayer",
                    Exception = ex,
                    DisplayMessage = "Failed to load the soundfont, Path: " + soundFontPath
                });
                var fileName = System.IO.Path.GetFileName(soundFontPath);
                var properties = new Dictionary<string, string>();
                properties.Add("ExceptionMessage", ex.Message);
                properties.Add("MethodName", "LoadInstrument");
                properties.Add("FileName", fileName);
                properties.Add("Path", soundFontPath);
                App.AnalyticsLogger.LogEvent("MSQ.LoadInstrument", "MIDI", properties, Sentry.Protocol.BreadcrumbLevel.Error);
                return false;
            }
            return true;
        }

堆栈跟踪:

libEmbeddedSystemAUs.dylib
    SampleManager::InsertSample(unsigned long, Sample*)
    libEmbeddedSystemAUs.dylib
    InstrumentManager::AddSample(DlsWave*, __CFURL const*, bool, unsigned int)
    
libEmbeddedSystemAUs.dylib
    GlobalState::LoadInstrumentFromDLSCollection(InstrumentState*, __CFURL const*, unsigned int, unsigned int, bool)
    
libEmbeddedSystemAUs.dylib
    Sampler::SetProperty(unsigned int, unsigned int, unsigned int, void const*, unsigned int)
libEmbeddedSystemAUs.dylib
    AUBase::DispatchSetProperty(unsigned int, unsigned int, unsigned int, void const*, unsigned int)

libEmbeddedSystemAUs.dylib
    AUMethodSetProperty(void*, unsigned int, unsigned int, unsigned int, void const*, unsigned int)
gc.safepoint_poll
     
gc.safepoint_poll
    
gc.safepoint_poll
    
gc.safepoint_poll
    
gc.safepoint_poll
gc.safepoint_poll
     
gc.safepoint_poll
    
gc.safepoint_poll
    
gc.safepoint_poll
    
gc.safepoint_poll
    
gc.safepoint_poll
    
gc.safepoint_poll
gc.safepoint_poll
     
gc.safepoint_poll
gc.safepoint_poll
     gc.safepoint_poll
plcrash::MS::async::dwarf_cfa_state_iterator<unsigned long long, long long>::next(unsigned int*,
plcrash::MS::async::plcrash_dwarf_cfa_reg_rule_t*, unsigned long long*)
TUE.iOS plcrash::MS::async::dwarf_cfa_state_iterator<unsigned long long, long long>::next(unsigned int*,
plcrash::MS::async::plcrash_dwarf_cfa_reg_rule_t*, unsigned long long*)
Foundation
    __NSThreadPerformPerform
C
CoreFoundation
    __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
CoreFoundation
    __CFRunLoopDoSource0
CoreFoundation
    __CFRunLoopDoSources0
 
CoreFoundation
    __CFRunLoopRun
 
CoreFoundation

CFRunLoopRunSpecific

GraphicsServices
    GSEventRunModal
 
UIKitCore
    -[UIApplication _run]
 
UIKitCore
    UIApplicationMain

TUE.iOS
    gc.safepoint_poll
 
TUE.iOS
    gc.safepoint_poll
 
TUE.iOS
    gc.safepoint_poll
 
TUE.iOS
    gc.safepoint_poll
 
TUE.iOS
    gc.safepoint_poll
 
TUE.iOS
    gc.safepoint_poll
 
TUE.iOS
    gc.safepoint_poll
 
TUE.iOS

xamarin_release_block_on_main_thread

TUE.iOS

plcrash::MS::async::dwarf_cfa_state_iterator<unsigned long long, long long>::next(unsigned int*,
plcrash::MS::async::plcrash_dwarf_cfa_reg_rule_t*, unsigned long long*)
libdyld.dylib

start

我将对 LoadInstrument 的调用包装在 MainThread.BeginInvokeOnMainThread 中。这似乎已经完全解决了这个问题,因为我再也没有收到关于此的另一份报告:

MainThread.BeginInvokeOnMainThread(() =>
                        _samplerUnit.LoadInstrument(new SamplerInstrumentData(soundFontUrl, InstrumentType.SF2Preset)
                        {
                            BankLSB = SamplerInstrumentData.DefaultBankLSB,
                            BankMSB = SamplerInstrumentData.DefaultMelodicBankMSB,
                            PresetID = (byte)0
                        }));