Подтвердить что ты не робот

Все селекторы, не распознанные при вызове методов Objective-C с использованием LLVM ExecutionEngine

Я работаю на OSX, используя Clang для компиляции кода Obj-C, который использует классы OSX Cocoa, и я пытаюсь запустить результат с помощью компилятора LLVM JIT. Я использую последнюю версию LLVM/Clang.

Нет проблем с компиляцией или связыванием моего кода, и я могу с радостью сделать системные вызовы C и С++ без особых проблем. Но все мои призывы Obj-C терпят неудачу, и я изо всех сил пытаюсь понять почему! Функция objc_msgSend() выглядит правильно вызванной, но среда выполнения отказывается распознавать даже самые простые селектора.

Мне удалось воспроизвести проблему, используя только Clang и LLI, и вот как это сделать:

Создайте простой файл test.mm:

#include <Cocoa/Cocoa.h>
#include <cstdio>
#include <iostream>

extern "C" int main (int, char**)
{
    std::cout << "==== step 1" << std::endl;

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    [pool release];

    std::cout << "==== step 2" << std::endl;

    return 0;
}

.. скомпилируйте его для биткода с clang:

clang -emit-llvm test.mm -c -o test.bc

Затем запустите его с помощью lli:

lli -load=/System/Library/Frameworks/Foundation.framework/Versions/Current/Foundation test.bc

Результат lli выглядит так:

==== step 1
objc[45353]: Object 0x101a362a0 of class __NSCFString autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug
2012-04-29 20:07:35.384 lli[45353:707] -[NSAutoreleasePool init]: unrecognized selector sent to instance 0x101a35170
2012-04-29 20:07:35.386 lli[45353:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSAutoreleasePool init]: unrecognized selector sent to instance 0x101a35170'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff89c76fc6 __exceptionPreprocess + 198
    1   libobjc.A.dylib                     0x00007fff8c9e6d5e objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff89d032ae -[NSObject doesNotRecognizeSelector:] + 190
    3   CoreFoundation                      0x00007fff89c63e73 ___forwarding___ + 371
    4   CoreFoundation                      0x00007fff89c63c88 _CF_forwarding_prep_0 + 232
    5   ???                                 0x0000000101929111 0x0 + 4321349905
    6   lli                                 0x000000010148f36b _ZN4llvm15ExecutionEngine17runFunctionAsMainEPNS_8FunctionERKSt6vectorISsSaISsEEPKPKc + 1259
    7   lli                                 0x0000000101016657 main + 3095
    8   lli                                 0x0000000101015a34 start + 52
    9   ???                                 0x0000000000000003 0x0 + 3
)
terminate called throwing an exception0  lli               0x00000001015c5b02 _ZL15PrintStackTracePv + 34
1  lli               0x00000001015c5fd9 _ZL13SignalHandleri + 633
2  libsystem_c.dylib 0x00007fff8f8bccfa _sigtramp + 26
3  libsystem_c.dylib 0x0000000000000001 _sigtramp + 18446603338107859745
4  libsystem_c.dylib 0x00007fff8f85ba7a abort + 143
5  libc++abi.dylib   0x00007fff8518a7bc abort_message + 214
6  libc++abi.dylib   0x00007fff85187fcf default_terminate() + 28
7  libobjc.A.dylib   0x00007fff8c9e71b9 _objc_terminate + 94
8  libc++abi.dylib   0x00007fff85188001 safe_handler_caller(void (*)()) + 11
9  libc++abi.dylib   0x00007fff8518805c __cxa_bad_typeid + 0
10 libc++abi.dylib   0x00007fff85189152 __gxx_exception_cleanup(_Unwind_Reason_Code, _Unwind_Exception*) + 0
11 libobjc.A.dylib   0x00007fff8c9e6e7a _objc_exception_destructor + 0
12 CoreFoundation    0x00007fff89d032ae -[NSObject doesNotRecognizeSelector:] + 190
13 CoreFoundation    0x00007fff89c63e73 ___forwarding___ + 371
14 CoreFoundation    0x00007fff89c63c88 _CF_forwarding_prep_0 + 232
15 CoreFoundation    0x0000000101929111 _CF_forwarding_prep_0 + 18446603342526043505
16 lli               0x000000010148f36b llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::vector<std::string, std::allocator<std::string> > const&, char const* const*) + 1259
17 lli               0x0000000101016657 main + 3095
18 lli               0x0000000101015a34 start + 52
19 lli               0x0000000000000003 start + 18446744069397718531
Stack dump:
0.  Program arguments: Release/bin/lli -load=/System/Library/Frameworks/Foundation.framework/Versions/Current/Foundation /Users/jules/Desktop/test.bc 
Abort trap: 6

Как вы можете видеть в журнале, в нем говорится, что -[NSAutoreleasePool init] является непризнанным селектором. То же самое происходит для любого другого селектора, например. -[NSString init] или другие вещи, которые явно должны работать.

Любая помощь или подсказки были бы высоко оценены! Я немного потерял, является ли это ошибкой, или что-то, что я делаю неправильно, или, может быть, просто функция, которая еще не закончена. Я не могу найти никаких ссылок на эту проблему в любом месте документации LLVM или межсетевых экранов.

Я пробовал различные варианты clang, такие как устаревшая Obj-C хрупкая ABI, но не повезло. Я не эксперт ни в LLVM, ни во время выполнения Obj-C, и это меня озадачило.

- EDIT -

Просто немного больше информации, в надежде, что он может позвонить в колокол с кем-то..

Когда я попытался заменить обычное вызов сообщения obj-C явным вызовом objc_msgSend, я нашел это:

SEL s = sel_getUid ("init");
objc_msgSend (myObject, s);   // Succeeds!

SEL s = @selector (init);
objc_msgSend (myObject, s);   // Fails!

.. поэтому кажется, что когда clang автоматически генерирует значение SEL, он создает значение, которое не может использоваться во время выполнения. Может ли кто-нибудь даже предложить, где в кодовой базе LLVM/Clang я должен попытаться понять, что может происходить?

4b9b3361

Ответ 1

Objective-C использует специально названные глобальные значения для ссылки на селекторы, а компоновщик и среда выполнения ObjC имеют специальное знание этих глобальных переменных, что делает все нормально работать. lli не знает о Objective-C; поэтому среда выполнения ObjC никогда не запускает свою специальную обработку для рассматриваемых глобальных переменных.

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