Программа OS X работает на компьютере разработчика, ужасно падая на других - PullRequest
8 голосов
/ 14 августа 2010

У меня есть Mac OS X 10.6, которую я использую в качестве своей машины для разработки. Программа, которую я написал, прекрасно работает на компьютере разработчика. Однако, когда я попытался запустить его на тестовой машине с 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 ++ в комплект моего приложения?

Ответы [ 3 ]

9 голосов
/ 13 сентября 2011

Решением этой проблемы является добавление следующего кода в один из ваших исходных файлов:

// 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 ++ есть несколько шаблонов, которые объявлены как внешние шаблоны, ихотя их экземпляры предоставляются libstdc ++ на 10.6+, они не предоставляются libstdc ++ на 10.5.В результате, когда вы используете эти шаблоны, вы успешно соединяетесь с 10.6 SDK для функций, не предоставляемых ОС 10.5, и поэтому dyld обрывается при запуске.Предоставляя экземпляры самостоятельно, вы гарантируете, что ваш код будет загружен на Snow Leopard.

В качестве альтернативы вы можете

#define _GLIBCXX_EXTERN_TEMPLATE 0 

в вашем файле префикса, но это приведет к вздутию кода шаблона.

2 голосов
/ 14 августа 2010

Есть несколько моментов, о которых я могу подумать:

  1. Вы скомпилировали его как "релизную сборку"?Сборка отладки может не работать на машинах, отличных от той, на которой она компилируется.

  2. Какой SDK вы использовали?Какую минимальную версию ОС вы указали в настройках сборки?Если вы хотите запустить его на 10.5, вам нужно использовать 10.5 SDK и / или установить целевую ОС на 10.5.См. этот документ Apple о сборке для нескольких версий ОС.

  3. Было ли на целевой машине DYLD_LIBRARY_PATH установлено что-то непустое?Если не сделать это осторожно, это может сбить с толку dyld.

Один из способов различать различные возможности - это запускать ваше приложение на компьютере разработчика, но с отдельной учетной записью без прав администраторааккаунт разработчика;тогда вы можете проверить, работает ли он в 10.6 боксе.

0 голосов
/ 13 сентября 2011

Я столкнулся с той же проблемой (сборка с GCC 4.2 делает мой код неспособным выполнить на OS X 10.5 из-за ошибок dyld в libstdc ++. 6.dylib).

Решение, предложенное Беном Артином, работает. Кроме того, вы можете установить определение _GLIBCXX_EXTERN_TEMPLATE в ноль перед добавлением каких-либо заголовков (если вы используете предварительно скомпилированные заголовки, убедитесь, что они правильно скомпилированы с определенным набором).

...