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?
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? –
Đố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). –