我的应用程序在新Apple笔记本电脑上构建时崩溃,然后在更旧的Apple笔记本电脑上启动。
当使用llvm 6.1和C ++ 11时,应用程序使用Xcode 6.4在OSX 10.9和10.10上构建。 SDK为10.10,目标OSX为10.7。优化已关闭。
当C运行时加载我的应用程序二进制文件并初始化模块时,崩溃非常早。
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 com.MyCompany.MyApplication 0x000000010cd10e7a _GLOBAL__I_a + 10
1 dyld 0x00007fff61fd3ceb ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 265
2 dyld 0x00007fff61fd3e78 ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 40
3 dyld 0x00007fff61fd0871 ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int,
这是在我的任何应用程序代码之前。在构建计算机(i7 CPU)上不会发生崩溃。崩溃发生在i5和Core 2 Duo机器上。我怀疑扩展(CPU特定)指令正在加载崩溃。
当我使用相同的Xcode,相同的llvm等在Core 2 Duo机器上构建应用程序时,没有崩溃。
我也在使用自制软件:libmtp,libusb,libusb-compat,cryptopp,curl(带有c-ares,openssl,nghttp2),boost。我已经在必要时指定了C ++ 11,并指定了--build-bottle。我静态链接到这些库。
我试图在所有库,最终二进制文件等上使用otool -tV来查找SSE指令。
我尝试将Xcode LLVM构建设置“启用其他矢量扩展”设置为“平台”和“SSE3”无效。这可能是因为自制软件没有将-wiversal标志从curl传递给openssl的建筑物而且它是cryptlib。
我从旧机器上取了静态库libcurl.a(CURL),libssl.a(OpenSSL),libcrypto.a(OpenSSL),libz.a(zlib)并将它们添加到我的存储库中。使用Xcode将它们链接到我的应用程序可以解决问题。
我是否可以使用其他工具来缩小违规指令? 崩溃还有其他解释吗?
附录: 除了在旧机器上构建库之外,我还创建了一个概念验证,即最小的即时崩溃程序,它报告了一个稍微不同的崩溃位置,但演示了这个问题:
在i7(带有新Intel CPU的新Apple电脑)上,使用自制软件安装: brew install curl --with-c-ares --with-openssl
然后将此源复制到文件sse.cpp:
#define CURL_STATICLIB
#include <curl/curl.h>
int main(int argc, const char * argv[]) {
curl_global_init(CURL_GLOBAL_ALL);
return 0;
}
编译:
clang++ sse.cpp -c -arch x86_64 -I/usr/local/opt/curl/include
clang++ -o a.out sse.o /usr/local/opt/openssl/lib/libssl.a /usr/local/opt/openssl/lib/libcrypto.a /usr/local/opt/zlib/lib/libz.a /usr/local/opt/curl/lib/libcurl.a /usr/local/opt/c-ares/lib/libcares.a -stdlib=libc++ -framework LDAP
现在转移到使用较旧Intel CPU的较旧Apple计算机,并将其崩溃:
./a.out
崩溃报告(压缩):
Process: a.out [569]
...
Code Type: X86-64 (Native)
Parent Process: bash [448]
Responsible: Terminal [339]
...
OS Version: Mac OS X 10.10.5 (14F27)
...
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 a.out 0x000000010dbdce3f ENGINE_new + 36
1 a.out 0x000000010dbe05e3 ENGINE_load_dynamic + 11
2 a.out 0x000000010dbdf04a ENGINE_load_builtin_engines + 24
3 a.out 0x000000010dc76b36 Curl_ossl_init + 14
4 a.out 0x000000010dc5c2a5 curl_global_init + 114
5 a.out 0x000000010db51d95 main + 37
6 libdyld.dylib 0x00007fff88b735c9 start + 1
答案 0 :(得分:0)
禁用编译器优化时代码是否有效?如果没有,尝试旧版Xcode怎么样?它可能只是一个编译器错误,但我希望不会!如果您可以找到要检查的有效编译器或一组编译器选项,则可以使用LLVM的bugpoint工具来隔离哪个文件被错误编译。
答案 1 :(得分:0)
解决方案似乎涉及使用:
export HOMEBREW_BUILD_BOTTLE=1
export HOMEBREW_BOTTLE_ARCH=core2
构建自制程序库时。使用Intel XED我能够检查发出的机器代码以获取不受支持的说明:
xed_cmd="/usr/local/bin/xed"
ar -x libcurl.a
parts=(*.o)
for j in "${parts[@]}"; do
chipcheck=$(${xed_cmd} -i ${j} -chip-check ${chipToCheck})
chiperrors=$(echo "${chipcheck}" | grep "# Total Chip Check Errors")
if [[ "$chiperrors" != "# Total Chip Check Errors: 0" ]] ; then
echo ERROR ${libname} ${j} $chiperrors
fi
done