IOS EXC_BAD_INSTRUCTION при «int y = 0;»

#objective-c #exception

#objective-c #исключение

Вопрос:

У меня есть этот вызов в контексте класса UIViewController-наследника:

   (void) smthPressed: (id) caller
{
    // some code here
    // ...

    startTimers();
}
  

startTimers объявлены как:

 inline void startTimers()
{
    NSString * x = @""; // falls here with EXC_BAD_INSTRUCTION

    // some other codes here
}
  

Что, черт возьми, происходит?

Постскриптум:

 inline void startTimers()
{
    int x = 0;

    int y = 0; // EXC_BAD_INSTRUCTION here. Stack couldn't end there!

    // ...
  

P.P.S.:

В документации сказано: «Для большинства исключений, не связанных с доступом к памяти (например, EXC_BAD_INSTRUCTION …)», так что это НЕ ошибка доступа к памяти.

P.P.P.S.: arch является стандартным (armv6 armv7). Ничего не изменится, если я установлю оптимизированный (armv7).

Комментарии:

1. Вы пробовали инициализировать его с помощью nil, а не пустой строки?

2. Я когда-либо тестировал с «NSString * x = [NSString stringWithUTF8String: «»];» и это вообще не работает. Любой код в startTimers вызывает внезапную смерть.

3. Какой уровень оптимизации вы используете? Вам действительно нужно inline ? Почему вы используете функции, а не методы?

4. Я удалил встроенную, никакой разницы. Почему я должен использовать методы, а не функции? Это как если бы мои штаны спадали, когда я делаю шаг влево.

5. Самый быстрый, самый маленький. Я установил значение None — вообще ничего не изменилось.

Ответ №1:

Возможно, вы случайно повредили свой стек. Происходит ли это, когда вы размещаете startTimers() код в другом месте своей программы?

Попробуйте использовать NSZombieEnabled и статический анализатор для поиска других мест в вашем коде, в которых вы можете допускать ошибки управления памятью, которые могут привести к недопустимой записи в переменную стека (переполнение массивов в стеке, неверные указатели и т. Д.).

Вы также можете попробовать переключить компиляторы, если такая опция доступна для вас, в крайне редких случаях, когда вы столкнулись с ошибкой компилятора.

Ответ №2:

Я думаю, что здесь проблема с компилятором. Теперь, спустя 6 лет после того, как вы подняли проблему, если я попытаюсь скомпилировать ваш исходный код, он завершится неудачей. Это static зависит от ключевого слова. Следующий код компилируется и выполняется нормально:

 #import "ViewController.h"

@interface ViewController () 

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [ViewController smthPressed:self];
}

// Without the "static" keyword compile fails
static inline void fakeStartTimers() {
    int x = 0;
    int y = 0;
    printf("x and y are %d %d", x, y);
}

  (void)smthPressed:(id) caller
{
    fakeStartTimers();
}

@end
  

Это связано с компилятором

 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang --version
Apple LLVM version 9.1.0 (clang-902.0.39.1)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin