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?
Hai fatto progressi su questo da allora? –
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). –