2012-04-29 7 views
12

Sono in esecuzione su OSX, utilizzando Clang per compilare un codice Obj-C che utilizza le classi OSX Cocoa e sto cercando di eseguire il risultato con Compilatore JL LLVM. Sto usando l'ultima versione sanguinante di LLVM/Clang.Tutti i selettori non riconosciuti durante il richiamo dei metodi Objective-C utilizzando il LLVM ExecutionEngine

Non ci sono problemi nella compilazione o nel collegamento del mio codice, e posso tranquillamente effettuare chiamate di sistema C e C++ senza alcun problema. Ma tutte le mie invocazioni Obj-C stanno fallendo miseramente, e sono fuori dalla mia profondità cercando di capire perché! Sembra che la funzione objc_msgSend() venga richiamata correttamente, ma il runtime rifiuta di riconoscere anche i selettori più semplici.

sono riuscito a riprodurre il problema utilizzando solo Clang e LLI, e questo è come farlo:

Creare un semplice file di 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; 
} 

..compile a codice binario che con clang:

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

Poi eseguirlo con lli:

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

L'uscita del lli simile a questo:

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

Come si può vedere nel registro, si dice che -[NSAutoreleasePool init] è un selettore non riconosciuto. Lo stesso accade per qualsiasi altro selettore, ad es. -[NSString init] o altre cose che dovrebbero funzionare chiaramente.

Qualsiasi aiuto o indizio sarebbe molto apprezzato! Sono un po 'perso sul fatto che si tratti di un bug, o qualcosa che sto sbagliando, o forse solo una funzionalità che non è ancora stata completata. Non riesco a trovare alcun riferimento a questo problema in nessuna parte dei documenti o interwebs LLVM.

Ho provato diverse opzioni di clang come l'ABI legacy Obj-C fragile, ma non ho avuto fortuna. Non sono esperto di LLVM o del runtime Obj-C, e questo mi ha messo in difficoltà.

--EDIT--

Solo un po 'più di informazioni, nella speranza che potrebbe suonare un campanello con qualcuno ..

Quando ho provato a sostituire il normale obj-C messaggio di invocazione con un esplicito chiamare per objc_msgSend, ho trovato questo:

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

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

..quindi sembra che quando clang genera automaticamente il valore SEL, è la produzione di un valore che non è utilizzabile dal runtime. Qualcuno può suggerire anche dove nella base di codice LLVM/Clang dovrei cercare di capire cosa potrebbe succedere?

+0

Hai fatto progressi su questo da allora? –

+0

Per chiunque sia interessato c'è una discussione su questo su dev di LLVM: [È possibile eseguire codice Objective-C tramite JV LLVM?] (Http://lists.llvm.org/pipermail/llvm-dev/2016-November/ 106995.html). –

risposta

2

Objective-C utilizza globals appositamente denominati per fare riferimento ai selettori, e il linker e il runtime ObjC hanno una conoscenza speciale di questi globals che fa funzionare tutto normalmente. non ha conoscenza dell'Obiettivo-C; pertanto, il runtime ObjC non esegue mai la sua gestione speciale per i globals in questione.

In cima alla mia testa, non ho idea di cosa esattamente devi fare per farlo funzionare, però.

+0

Sì, ho il sospetto che sia qualcosa del genere. Il registro di debug mostra correttamente il nome del selettore, quindi la struttura deve essere inizializzata in una certa misura, ma forse c'è un qualche tipo di struttura di classe che non è impostata correttamente. – jules72