OS X程序在开发机器上运行,在其他程序上崩溃

Nan*_*ket 8 macos libstdc++

我有一台OS X 10.6 Mac我用作我的开发机器.我编写的程序在开发机器上完美运行.但是,当我尝试在OS X 10.5上运行它(不确定是否相关)测试机器时,它会在启动时崩溃.

这是我得到的错误:

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
Run Code Online (Sandbox Code Playgroud)

所以看起来它正在崩溃,因为它正在加载动态库libstdc ++的不兼容版本.这类事物是普通的吗?在Google上搜索并没有真正揭示许多其他有这个问题的程序.我应该在编译中做些什么来防止这种情况发生?我是否需要以某种方式在我的应用程序包中包含libstdc ++?

Ben*_*tin 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
Run Code Online (Sandbox Code Playgroud)

根本问题是在libstdc ++头文件中有几个模板被声明为extern模板,虽然他们的实例化是由10.6+上的libstdc ++提供的,但它们不是由10.5上的libstdc ++提供的.因此,当您使用这些模板时,您最终会成功链接10.6 SDK以获取10.5 OS未提供的功能,因此dyld会在启动时崩溃.通过自己提供实例化,您可以确保在Snow Leopard上加载代码.

或者,你可以

#define _GLIBCXX_EXTERN_TEMPLATE 0 
Run Code Online (Sandbox Code Playgroud)

在你的前缀文件中,但这样做会导致模板代码膨胀.