Сбой в [NSWindow orderFrontRegardless] после обновления до macOS Mojave - PullRequest
0 голосов
/ 18 февраля 2019

Получение этого странного сбоя после обновления до Мохаве.

Ничего особенного не делает, просто создает NSWindow и вызывает orderFrontRegardless

Раньше всегда работал нормально.

1   libsystem_platform.dylib            0x00007fff6610ab5d _sigtramp + 29
2   ???                                 0x0000000000000000 0x0 + 0
3   CoreFoundation                      0x00007fff39b00bb6 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
4   CoreFoundation                      0x00007fff39b00b30 ___CFXRegistrationPost_block_invoke + 63
5   CoreFoundation                      0x00007fff39b00a9a _CFXRegistrationPost + 404
6   CoreFoundation                      0x00007fff39b08f48 ___CFXNotificationPost_block_invoke + 87
7   CoreFoundation                      0x00007fff39a71994 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1642
8   CoreFoundation                      0x00007fff39a70d47 _CFXNotificationPost + 732
9   Foundation                          0x00007fff3bdab217 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
10  AppKit                              0x00007fff3720538b -[NSWindow _setFrameCommon:display:stashSize:] + 3090
11  AppKit                              0x00007fff37204766 -[NSWindow _setFrame:display:allowImplicitAnimation:stashSize:] + 192
12  AppKit                              0x00007fff3720469f -[NSWindow setFrame:display:] + 51
13  AppKit                              0x00007fff3727aca9 -[NSWindow _reallyDoOrderWindowAboveOrBelow:relativeTo:findKey:forCounter:force:isModal:] + 1336
14  AppKit                              0x00007fff372792a0 -[NSWindow _doOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 283
15  AppKit                              0x00007fff37a0dce9 -[NSWindow orderFrontRegardless] + 40

Код (это консольное приложение):

NSWindow *window =    [[NSWindow alloc] initWithContentRect:windowRect
styleMask:windowStyle
backing:NSBackingStoreBuffered
defer:NO];

// Since Snow Leopard, programs without application bundles and Info.plist
// files don't get a menubar and can't be brought to the front unless the
// presentation option is changed
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

 [NSApp activateIgnoringOtherApps:YES];
 [window makeKeyAndOrderFront:nil];

Ответы [ 3 ]

0 голосов
/ 30 марта 2019

Оказывается, у меня была серьезная ошибка памяти в совершенно другом месте, даже не упомянутом в обратном следе.

Я разыменовывал неинициализированный указатель.

Это второй раз, когда это происходит.

Не доверяйте следам Apple при отладке ошибок памяти.

Даже с libgmalloc.

0 голосов
/ 04 апреля 2019

Вы указали, что разыменовываете неинициализированный указатель.Но у меня недостаточно информации из отчета, который вы опубликовали, чтобы узнать, был ли это (возможно, по счастливой случайности) ноль, или просто мусорная память.Я предполагаю, что в какой-то момент вы потерпели крах с EXC_BAD_ACCESS (эквивалент сигнала SIGBUS или SIGSEGV, в зависимости).

критический бит информации здесь былу вас установлен обработчик сигнала.

Обработчики сигналов обычно (но не всегда) работают в аварийном потоке, используя тот же стек.Ядро внедряет обработчик, используя эту функцию _sigtramp.После доставки сигнала текущее состояние стека содержало информацию, необходимую для отслеживания плохого доступа к памяти.Но вместо этого был вызван ваш обработчик сигнала.Таким образом, он работал, изменяя стек, как это было.

Затем ваш обработчик сигналов завершился каким-то образом.Можно настроить обработчик сигнала, используя sigaction так, чтобы состояние процесса восстанавливалось до момента, предшествующего событию сбоя.Я не уверен, как был настроен ваш обработчик сигналов.Но, в конечном счете, я собираюсь предположить, что процессу было разрешено завершиться.

В этот момент Apple ReportCrash был бы запущен и собирал бы следы для всех потоков в любом состоянии вашего сигналаОбработчик оставил их .Это очень важно, потому что это не обязательно состояние сбоя.

Если сложить сложнее, backtrace_symbols_fd - это вовсе не безопасно для использования из обработчика сигнала.Асинхронная безопасность является сложной задачей, и запуск кода из обработчика сигналов очень труден для понимания .Есть очень мало вещей, которые вы можете сделать безопасно.Кроме того, я почти уверен, что backtrace_symbols_fd выделяет память.Итак, если ваш сбой был где-то в распределителе памяти, и это звучит так, как будто вы были, вы определенно рискуете зайти в тупик.Судя по обратному следу, похоже, что именно это и могло произойти.За подробностями обращайтесь к man sigaction.

Хуже того, раскрутка стека над фреймом обработчика сигнала особенно сложна из-за волшебства, которое ядро ​​выполняет для запуска вашего обработчика.Вот почему там находится кадр ???.

Резюме:

Без установленного обработчика сигналов ReportCrash от Apple мог бы создать правильную (и, вероятно, полезную) обратную трассировку для потока, вызывающего сбой.

Трассировка стека, которую вы включили, невелика, но трудно точно понять, почему.Похоже, что backtrace_symbols_fd не справился с работой по раскрутке, возможно, из-за того, что он не подходит для использования из обработчика сигнала, возможно, потому что он не поддерживается достаточно хорошим механизмом раскрутки стека для этой ситуации.Но без дополнительной информации мне трудно это знать.Я удивлен тем, что верхняя рамка была _sigtramp.Это не имеет большого смысла.Это заставляет меня думать, что, возможно, что-то пошло не так в самом обработчике сигнала. возможно аварийно завершить во второй раз в вашем обработчике.

Обратные следы Apple (генерируемые, например, ReportCrash, backtrace_symbols_fd или NSThread * callStackReturnAddresses), безусловно, можно доверять при условиивы осторожно используете их в безопасных условиях.

0 голосов
/ 22 февраля 2019

Как вы инициализируете приложение?Вы инициализировали NSApplication перед использованием AppKit?

Что-то вроде этих шагов должно быть необходимо в main.m:

@autoreleasepool {
    NSApplication* application = NSApplication.sharedApplication;

    AppDelegate* delegate = [[AppDelegate alloc] init];
    application.delegate = delegate;

    [application run];
}

Также ваш делегат может быть освобожден, так как NSApp содержит слабую ссылку на него.

...