2012-04-29 12 views
12

Estoy ejecutando en OSX, usando Clang para compilar algún código Obj-C que use las clases OSX Cocoa, y estoy tratando de ejecutar el resultado con el Compilador LLVM JIT. Estoy usando la última versión de última generación de LLVM/Clang.Todos los selectores no reconocidos al invocar métodos Objective-C utilizando LLVM ExecutionEngine

No hay problemas para compilar o vincular mi código, y puedo hacer llamadas al sistema C y C++ sin problemas. ¡Pero todas mis invocaciones de Obj-C están fallando miserablemente, y estoy fuera de mi profundidad tratando de descubrir por qué! Parece que la función objc_msgSend() se está llamando correctamente, pero el tiempo de ejecución se niega a reconocer incluso los selectores más simples.

he conseguido reproducir el problema utilizando sólo Clang y LLI, y esto es cómo hacerlo:

Crear un simple test.mm archivo:

#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; 
} 

..compile a código binario con el sonido metálico:

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

Entonces funcionar con lli:

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

La salida de lli se ve así:

==== 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 

Como se puede ver en el registro, se dice que es un selector de -[NSAutoreleasePool init] no reconocido. Lo mismo ocurre con cualquier otro selector, p. -[NSString init] u otras cosas que claramente deberían funcionar.

¡Cualquier ayuda o pista sería muy apreciada! Estoy un poco perdido en cuanto a si esto es un error, o algo que estoy haciendo mal, o tal vez solo una característica que aún no se ha terminado. No puedo encontrar ninguna referencia a este problema en ningún lugar de los documentos o interwebs de LLVM.

He intentado diferentes opciones de clang como el obj-C frágil ABI, pero no tuve suerte. No soy un experto en LLVM ni en el tiempo de ejecución de Obj-C, y este me tiene perplejo.

--EDIT--

Sólo un poco más de información, con la esperanza de que podría sonar una campana con alguien ..

Cuando probé la sustitución de la normal de obj-C mensaje de invocación con una explícita llamar a objc_msgSend, encontré esto:

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

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

.so parece que cuando clang genera automáticamente el valor de SEL, se está produciendo un valor que no es utilizable por el tiempo de ejecución. ¿Alguien puede sugerir dónde debo buscar en la base de código de LLVM/Clang para tratar de entender qué podría estar pasando?

+0

¿Ha hecho algún progreso en esto desde entonces? –

+0

Para cualquier persona interesada, hay una discusión sobre esto en el desarrollo de LLVM: [¿Es posible ejecutar el código Objective-C a través de LLVM JIT?] (Http://lists.llvm.org/pipermail/llvm-dev/2016-November/ 106995.html). –

Respuesta

2

Objective-C usa nombres globales para referirse a selectores, y el enlazador y el tiempo de ejecución ObjC tienen un conocimiento especial de estos valores globales que hace que todo funcione normalmente. lli no tiene conocimiento de Objective-C; por lo tanto, el tiempo de ejecución ObjC nunca ejecuta su manejo especial para los globales en cuestión.

Sin embargo, no tengo ni idea de qué es exactamente lo que tienes que hacer para que funcione.

+0

Sí, sospecho que es algo como esto. El registro de depuración muestra el nombre del selector correctamente, por lo que la estructura debe inicializarse hasta cierto punto, pero tal vez haya algún tipo de estructura de clase que no esté correctamente configurada. – jules72

Cuestiones relacionadas