2010-08-14 62 views
8

我有一個OS X 10.6 Mac我用作我的開發機器。我寫的程序在開發機器上完美工作。但是,當我試圖在OS X 10.5上運行它(不確定是否相關)測試機器時,它在啓動時崩潰。OS X程序在開發機器上運行,其他人可怕地崩潰

這是我得到的錯誤:

Process:   MyApp[25908] 
Path:   /Applications/MyApp.app/Contents/MacOS/MyApp 
Identifier:  MyApp 
Version:   ??? (???) 
Code Type:  X86 (Native) 
Parent Process: launchd [109] 

Interval Since Last Report:   17392106 sec 
Crashes Since Last Report:   735 
Per-App Interval Since Last Report: 0 sec 
Per-App Crashes Since Last Report: 8 

Date/Time:  2010-08-14 07:50:09.768 -0700 
OS Version:  Mac OS X 10.5.8 (9L31a) 
Report Version: 6 
Anonymous UUID: 1BF30470-ACF2-46C7-B6D5-4514380965C8 

Exception Type: EXC_BREAKPOINT (SIGTRAP) 
Exception Codes: 0x0000000000000002, 0x0000000000000000 
Crashed Thread: 0 

Dyld Error Message: 
    Symbol not found: __ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i 
    Referenced from: /Applications/MyApp.app/Contents/MacOS/MyApp 
    Expected in: /usr/lib/libstdc++.6.dylib 

因此,它看起來像它的崩潰,因爲它加載動態函數庫libstdC++的不兼容的版本6。這種事情是普通的嗎?在Google上搜索並不能真正揭示許多其他有此問題的程序。我應該在編譯時做些什麼來防止這種情況發生?我是否需要以某種方式在我的應用程序包中包含libstdC++?

回答

9

這個問題的解決方案是將下面的代碼添加到您的源文件之一:

// Workarounds for symbols that are missing from Leopard stdlibc++.dylib. 
_GLIBCXX_BEGIN_NAMESPACE(std) 
// From ostream_insert.h 
template ostream& __ostream_insert(ostream&, const char*, streamsize); 

#ifdef _GLIBCXX_USE_WCHAR_T 
    template wostream& __ostream_insert(wostream&, const wchar_t*, streamsize); 
#endif 

// From ostream.tcc 
template ostream& ostream::_M_insert(long); 
template ostream& ostream::_M_insert(unsigned long); 
template ostream& ostream::_M_insert(bool); 
#ifdef _GLIBCXX_USE_LONG_LONG 
    template ostream& ostream::_M_insert(long long); 
    template ostream& ostream::_M_insert(unsigned long long); 
#endif 
template ostream& ostream::_M_insert(double); 
template ostream& ostream::_M_insert(long double); 
template ostream& ostream::_M_insert(const void*); 

#ifdef _GLIBCXX_USE_WCHAR_T 
    template wostream& wostream::_M_insert(long); 
    template wostream& wostream::_M_insert(unsigned long); 
    template wostream& wostream::_M_insert(bool); 
    #ifdef _GLIBCXX_USE_LONG_LONG 
     template wostream& wostream::_M_insert(long long); 
     template wostream& wostream::_M_insert(unsigned long long); 
    #endif 
    template wostream& wostream::_M_insert(double); 
    template wostream& wostream::_M_insert(long double); 
    template wostream& wostream::_M_insert(const void*); 
#endif 

// From istream.tcc 
template istream& istream::_M_extract(unsigned short&); 
template istream& istream::_M_extract(unsigned int&); 
template istream& istream::_M_extract(long&); 
template istream& istream::_M_extract(unsigned long&); 
template istream& istream::_M_extract(bool&); 
#ifdef _GLIBCXX_USE_LONG_LONG 
    template istream& istream::_M_extract(long long&); 
    template istream& istream::_M_extract(unsigned long long&); 
#endif 
template istream& istream::_M_extract(float&); 
template istream& istream::_M_extract(double&); 
template istream& istream::_M_extract(long double&); 
template istream& istream::_M_extract(void*&); 

#ifdef _GLIBCXX_USE_WCHAR_T 
    template wistream& wistream::_M_extract(unsigned short&); 
    template wistream& wistream::_M_extract(unsigned int&); 
    template wistream& wistream::_M_extract(long&); 
    template wistream& wistream::_M_extract(unsigned long&); 
    template wistream& wistream::_M_extract(bool&); 
    #ifdef _GLIBCXX_USE_LONG_LONG 
     template wistream& wistream::_M_extract(long long&); 
     template wistream& wistream::_M_extract(unsigned long long&); 
    #endif 
    template wistream& wistream::_M_extract(float&); 
    template wistream& wistream::_M_extract(double&); 
    template wistream& wistream::_M_extract(long double&); 
    template wistream& wistream::_M_extract(void*&); 
#endif 

_GLIBCXX_END_NAMESPACE 

根本的問題是,有被聲明爲的libstdc的extern模板++頭,雖然幾個模板它們的實例由10.6+上的libstdC++提供,它們不是由10.5上的libstdC++提供的。因此,當您使用這些模板時,您可以成功鏈接到10.5操作系統所不具備的功能的10.6 SDK,因此在啓動時會彈出對話框。通過自己提供實例,確保您的代碼將在Snow Leopard上加載。

或者,您可以

#define _GLIBCXX_EXTERN_TEMPLATE 0 

在前綴文件,但這樣做將導致模板代碼膨脹。

+0

請注意,您需要包含''才能使上述代碼正常工作。 – 2014-08-26 16:53:54

2

有我能想到的幾點:

  1. 你編譯它作爲一個「發佈版本」?調試版本可能無法在編譯它的機器上運行。

  2. 你使用了哪個SDK?您在構建設置中指定了哪個最低操作系統版本?如果你想在10.5上運行它,你需要使用10.5 SDK和/或將目標OS設置爲10.5。有關構建多個OS版本的信息,請參閱this Apple document

  3. 目標機器有DYLD_LIBRARY_PATH設置爲非空嗎?如果不仔細,可能會混淆dyld

一來區分各種可能性的方法是在開發機上運行你的應用程序,但與來自dev的帳戶沒有管理員權限的單獨帳戶;那麼你可以測試它是否在10.6盒子裏運行。

+0

重點說明1:如果調試版本適用於兼容體系結構(例如,,你沒有試圖在PowerPC機器上運行Intel代碼)並且不使用ZeroLink(我認爲它甚至不在最新的Xcode上提供),那麼調試版本應該可以工作。 – JWWalker 2010-08-14 23:02:07

+0

謝謝,你說得對。糾正。 – Yuji 2010-08-15 01:05:17

0

我遇到了同樣的問題(使用GCC 4.2編譯時,由於libstdC++。6.dylib中的dyld錯誤,我的代碼無法在OS X 10.5上執行)。

Ben Artin提出的解決方案有效。或者,您可以在添加任何標頭之前將定義_GLIBCXX_EXTERN_TEMPLATE設置爲零(如果您正在使用預編譯標頭,請確保它們已使用define集正確編譯)。