8

開発マシンとして使用している 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

動的ライブラリ libstdc++.6 の互換性のないバージョンをロードしているため、クラッシュしているようです。このようなことは普通ですか?Google で検索しても、この問題を抱えている他の多くのプログラムは実際には明らかになりません。これが起こらないようにするには、コンパイルで何をすべきですか? アプリケーション バンドル内に何らかの方法で libstdc++ を含める必要がありますか?

4

3 に答える 3

9

この問題の解決策は、次のコードをソース ファイルの 1 つに追加することです。

// 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 OS で提供されていない機能について 10.6 SDK に対して正常にリンクすることになり、起動時に dyld が異常終了します。インスタンス化を自分で提供することにより、コードが Snow Leopard に確実に読み込まれるようになります。

または、次のことができます。

#define _GLIBCXX_EXTERN_TEMPLATE 0 

をプレフィックス ファイルに追加しますが、これを行うとテンプレート コードが肥大化します。

于 2011-09-12T20:39:19.600 に答える
2

私が考えることができるいくつかのポイントがあります:

  1. 「リリースビルド」としてコンパイルしましたか?デバッグ ビルドは、コンパイルされたマシン以外のマシンでは実行されない場合があります。

  2. どの SDK を使用しましたか? ビルド設定で指定した最小 OS バージョンはどれですか? 10.5 で実行する場合は、10.5 SDK を使用するか、ターゲット OS を 10.5 に設定する必要があります。複数の OS バージョンのビルドに関するこの Apple ドキュメントを参照してください。

  3. ターゲット マシンがDYLD_LIBRARY_PATH空でない値に設定されていますか? 慎重に行わないと、混乱する可能性がありdyldます。

さまざまな可能性を区別する 1 つの方法は、アプリを開発マシンで実行することですが、開発アカウントとは管理者権限のない別のアカウントを使用します。その後、10.6 ボックスで動作するかどうかをテストできます。

于 2010-08-14T17:45:52.890 に答える
0

同じ問題に遭遇しました (GCC 4.2 でビルドすると、libstdc++.6.dylib の dyld エラーのため、OS X 10.5 でコードを実行できなくなります)。

Ben Artin によって提案されたソリューションが機能します。または、define _GLIBCXX_EXTERN_TEMPLATE をゼロに設定してから、ヘッダーを追加することもできます (プリコンパイル済みヘッダーを使用している場合は、正しく定義されたセットでコンパイルされていることを確認してください)。

于 2011-09-13T08:55:32.067 に答える