2012-04-29 23 views
12

Tôi đang chạy trên OSX, sử dụng Clang để biên dịch một số mã Obj-C sử dụng các lớp Cocoa OSX và tôi đang cố gắng chạy kết quả với Trình biên dịch LLVM JIT. Tôi đang sử dụng phiên bản mới nhất của LLVM/Clang.Tất cả các bộ chọn không được nhận ra khi gọi các phương thức Objective-C bằng cách sử dụng LLVM ExecutionEngine

Không có vấn đề gì khi biên dịch hoặc liên kết mã của tôi và tôi có thể thực hiện cuộc gọi hệ thống C và C++ một cách vui vẻ mà không gặp bất kỳ sự cố nào. Nhưng tất cả những lời cầu khẩn của Obj-C của tôi đều thất bại, và tôi đã hết sức cố gắng giải thích tại sao! Hàm objc_msgSend() dường như được gọi chính xác, nhưng thời gian chạy là từ chối nhận ra ngay cả những bộ chọn đơn giản nhất.

tôi đã quản lý để tạo lại vấn đề sử dụng chỉ Clang và LLI, và đây là cách để làm điều đó:

Tạo một test.mm tập tin đơn giản:

#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 nó để bitcode với kêu vang:

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

Sau đó chạy nó với lli:

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

Kết quả của lli trông như thế này:

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

Như bạn thấy trong nhật ký, nó nói rằng -[NSAutoreleasePool init] là một selector không được công nhận. Điều tương tự cũng xảy ra với bất kỳ công cụ chọn nào khác, ví dụ: -[NSString init] hoặc những thứ khác rõ ràng nên hoạt động.

Bất kỳ trợ giúp hoặc đầu mối nào sẽ được đánh giá cao! Tôi hơi lạc lõng về việc liệu đây có phải là một lỗi, hay một cái gì đó tôi đang làm sai, hoặc có thể chỉ là một tính năng chưa được hoàn thành. Tôi không thể tìm thấy bất kỳ tham chiếu đến vấn đề này bất cứ nơi nào trong các tài liệu LLVM hoặc interwebs.

Tôi đã thử các tùy chọn clang khác nhau như ABI dễ vỡ Obj-C cũ, nhưng không có may mắn. Tôi không có chuyên gia về LLVM hoặc thời gian chạy Obj-C, và điều này đã khiến tôi bối rối.

--EDIT--

Chỉ cần một chút biết thêm, với hy vọng rằng nó có thể rung chuông với một ai đó ..

Khi tôi cố gắng thay thế thông điệp gọi obj-C bình thường với một rõ ràng gọi tới objc_msgGửi, tôi tìm thấy điều này:

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

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

.. có vẻ như khi tự động tạo giá trị SEL, nó tạo ra giá trị không thể sử dụng được bởi thời gian chạy. Bất cứ ai thậm chí có thể đề nghị nơi trong codebase LLVM/Clang tôi nên xem xét để cố gắng hiểu những gì có thể xảy ra?

+0

Bạn có thực hiện bất kỳ tiến triển nào về điều này kể từ đó không? –

+0

Đối với bất kỳ ai quan tâm có một cuộc thảo luận về điều này trên LLVM dev: [Có thể thực thi mã Objective-C qua LLVM JIT không?] (Http://lists.llvm.org/pipermail/llvm-dev/2016-November/ 106995.html). –

Trả lời

2

Mục tiêu-C sử dụng các hình cầu được đặt tên đặc biệt để tham chiếu đến bộ chọn và trình liên kết và thời gian chạy ObjC có kiến ​​thức đặc biệt về các hình cầu này làm cho mọi thứ hoạt động bình thường. lli không có kiến ​​thức về Objective-C; do đó, thời gian chạy ObjC không bao giờ chạy xử lý đặc biệt của nó cho các hình cầu được đề cập.

Tắt đầu của tôi, tôi không có ý tưởng chính xác những gì bạn cần làm để làm cho nó hoạt động, mặc dù.

+0

Vâng, tôi nghi ngờ đó là một cái gì đó như thế này. Nhật ký gỡ lỗi hiển thị tên của trình chọn chính xác, vì vậy cấu trúc phải được khởi tạo ở một mức độ nào đó, nhưng có lẽ có một số loại cấu trúc lớp trong đó không được thiết lập chính xác .. – jules72