Как предотвратить удаление функции C в приложении iOS при загрузке в TestFlight?IOS

Программируем под IOS
Ответить
Anonymous
 Как предотвратить удаление функции C в приложении iOS при загрузке в TestFlight?

Сообщение Anonymous »

  • У меня есть библиотека iOS, предоставляющая функцию C. Эта функция помечена видимостью по умолчанию и используется через теги атрибутов, чтобы компилятор/компоновщик не мог ее удалить

    Код: Выделить всё

    #ifdef __cplusplus
    #define DYLIB_EXPORT
    extern "C" __attribute__((visibility("default"))) __attribute__((used))
    #else
    #define DYLIB_EXPORT
    __attribute__((visibility("default"))) __attribute__((used))
    #endif
    
    DYLIB_EXPORT bool say_hello_world();
    

    Код: Выделить всё

    #import "helper_functions.h"
    #import 
    
    bool say_hello_world() {
    NSLog(@"Hello WORLD 🟢!");
    return true;
    }
    
  • Из динамической библиотеки sdk я хочу вызвать эту функцию. В этом примере это библиотека Rust

    Код: Выделить всё

    unsafe extern "C" {
    fn say_hello_world() -> bool;
    }
    
    #[unsafe(no_mangle)]
    extern "C" fn sdk_init() -> i32 {
    unsafe {
    say_hello_world();
    }
    return 0;
    }
    
  • Когда приложение скомпилировано и запущено из Xcode (в схемах отладки или выпуска), это работает, следующий фрагмент работает и печатает сообщение hello WORLD:

    Код: Выделить всё

     #import "Wrapper.h"
    #import "helper_functions.h"
    #import "sdk.h"
    
    @implementation Wrapper
    // This function is called on the main view controller mount
    + (int)initialize {
    NSBundle *frameworkBundle =
    [NSBundle bundleWithIdentifier:@"sdk"];
    if (![frameworkBundle isLoaded]) {
    BOOL success = [frameworkBundle load];
    if (!success) {
    return -1;
    }
    
    int status = sdk_init();
    return status;
    }
    
    return 0;
    }
    
    @end
    
  • Однако при архивировании и загрузке в TestFlight происходит дополнительный этап удаления, который избавляет от функцииsay_hello_world. Затем динамическая библиотека аварийно завершает работу с исключением нулевого указателя:

    Код: Выделить всё

    Thread 3 name:
    Thread 3 Crashed:
    0   ???                              0x0000000000000000 0x0 + 0
    1   sdk                              0x0000000105931ec0 0x105820000 + 1121984
    
Минимальный воспроизводимый пример
Помимо фрагментов, единственный способ воспроизвести пример — с помощью полностью компилируемого приложения iOS можно создать урезанный двоичный файл, который запускается на устройстве. Поэтому я максимально сократил код, чтобы воспроизвести проблему в этом репозитории:
https://github.com/ospfranco/dylib_crash
Затем заархивируйте приложение, а затем экспортируйте его с помощью параметра отладки. Перетащите мышью в окно поиска подключенного iPhone, чтобы установить его напрямую на устройство.
Дополнительные примечания
  • На форумах разработчиков Apple было некоторое обсуждение.
  • Библиотека Rust была скомпилирована с дополнительными флагами, чтобы предотвратить сбой компоновщика, когда функция отсутствует во время компиляции:

    Код: Выделить всё

    println!("cargo:rustc-link-arg=-Wl,-U,_say_hello_world");
    
  • Я точно знаю, что это проблема с удалением мертвого кода, потому что, если я отключу удаление мертвого кода в настройках проекта, код вообще не будет удален, что приведет к раздуванию двоичного файла, но сбой больше не произойдет. Однако это происходит только при создании распространяемого .ipa, а не при запуске непосредственно из Xcode


Подробнее здесь: https://stackoverflow.com/questions/798 ... -to-testfl
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»