2012-04-29 3 views
12

OSX에서 실행 중이며 Clang을 사용하여 OSX Cocoa 클래스를 사용하는 Obj-C 코드를 컴파일하고 있습니다. LLVM JIT 컴파일러. LLVM/Clang의 최첨단 버전을 사용하고 있습니다.LLVM ExecutionEngine을 사용하여 Objective-C 메소드를 호출 할 때 모든 셀렉터가 인식되지 않습니다.

내 코드를 컴파일하거나 연결하는 데 문제가 없으며 아무런 문제없이 C 및 C++ 시스템 호출을 즐겁게 할 수 있습니다. 하지만 모든 Obj-C 호출은 비참하게 실패하고 있으며, 나는 왜 그런지 알아 내려고 노력하고 있습니다! objc_msgSend() 함수가 올바르게 호출 된 것처럼 보이지만 런타임에서 가장 단순한 선택기를 인식하지 못합니다.

난 그냥 연타와 LLI를 사용하여 문제를 재현하는 데 성공했으며,이 같은 방법으로 할 수 있습니다 :

간단한 파일 test.mm 만들기 : 그것은 ..compile

#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 -emit-llvm test.mm -c -o test.bc 

을 그리고 아프 그것을 실행

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 문서 나 인터 웹에서 찾을 수 없다.

나는 Obj-C 깨지기 쉬운 ABI 같은 다른 clang 옵션을 시도했지만 운이 없었습니다. 나는 LLVM 또는 Obj-C 런타임에 대한 전문가가 아니며,이 하나가 저를 곤란하게합니다.

--EDIT--

그냥 조금 누군가와 벨 수 있다는 희망에 대한 추가 정보를 원하시면 ..

내가 명시 적으로 정상 OBJ-C 메시지 호출을 교체 시도 이 연타 때 SEL 값을 자동 - 생성하는 것 ..so는 런타임에 의해 사용 가능한 아니다 값을 생성하는 것,

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

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

: objc_msgSend에 전화,이를 발견했다. 아무도 LLVM/Clang 코드베이스에서 어디서 무슨 일이 벌어 질지 이해하려고 노력해야한다고 제안 할 수 있습니까?

+0

그 이후로 진전을 보았습니까? –

+0

관심있는 사람들에게 LLVM dev에 관한 토론이 있습니다 : [LLVM JIT를 통해 Objective-C 코드를 실행할 수 있습니까?] (http://lists.llvm.org/pipermail/llvm-dev/2016-November/ 106995.html). –

답변

2

Objective-C는 특별히 이름이 지정된 전역을 사용하여 선택기를 나타내며 링커와 ObjC 런타임은 이러한 전역에 대한 특별한 지식을 가지고있어 모든 것이 정상적으로 작동합니다. lli는 Objective-C에 대한 지식이 없습니다. 따라서 ObjC 런타임은 문제의 전역에 대한 특수 처리를 실행하지 않습니다.

내 머리 꼭대기에서 나는 제대로 작동하도록하려면 무엇이 필요한지 잘 모릅니다.

+0

네, 그럴 것 같아요. 디버그 로그에는 선택기의 이름이 올바르게 표시되므로 구조가 어느 정도 초기화되어야하지만 올바르게 설정되지 않은 클래스 구조가있을 수 있습니다. – jules72