Проблемы с динамическими библиотеками в Python и libstdc ++ - PullRequest
3 голосов
/ 27 сентября 2011

Краткое содержание: модуль Python связан с другой версией libstdc++.dylib, чем исполняемый файл Python.В результате происходит вызов iostream из-за сбоя модуля.

Backstory

Я создаю модуль Python, используя SWIG на более старом компьютере (работает 10.5.8).По разным причинам я использую GCC 4.5 (установленный через MacPorts), чтобы сделать это, используя Python 2.7 (установленный через MacPorts, скомпилированный с использованием системного GCC 4.0.1 по умолчанию).

Observed Behavior

Короче говоря: вызов str( myObject ) в Python заставляет код C ++ по очереди вызывать std::operator<< <std::char_traits<char> >.Это приводит к следующей ошибке:

Python(487) malloc: *** error for object 0x69548c: Non-aligned pointer being freed
*** set a breakpoint in malloc_error_break to debug

Установка точки останова и вызов backtrace в случае сбоя дает:

#0  0x9734de68 in malloc_error_break ()
#1  0x97348ad0 in szone_error ()
#2  0x97e6fdfc in std::string::_Rep::_M_destroy ()
#3  0x97e71388 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string ()
#4  0x97e6b748 in std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow ()
#5  0x97e6e7a0 in std::basic_streambuf<char, std::char_traits<char> >::xsputn ()
#6  0x00641638 in std::__ostream_insert<char, std::char_traits<char> > ()
#7  0x006418d0 in std::operator<< <std::char_traits<char> > ()
#8  0x01083058 in meshLib::operator<< <tranSupport::Dimension<(unsigned short)1> > (os=@0xbfffc628, c=@0x5a3c50) at /Users/sethrj/_code/pytrt/meshlib/oned/Cell.cpp:21
#9  0x01008b14 in meshLib_Cell_Sl_tranSupport_Dimension_Sl_1u_Sg__Sg____str__ (self=0x5a3c50) at /Users/sethrj/_code/_build/pytrt-gcc45DEBUG/meshlib/swig/mesh_onedPYTHON_wrap.cxx:4439
#10 0x0101d150 in _wrap_Cell_T___str__ (args=0x17eb470) at /Users/sethrj/_code/_build/pytrt-gcc45DEBUG/meshlib/swig/mesh_onedPYTHON_wrap.cxx:8341
#11 0x002f2350 in PyEval_EvalFrameEx ()
#12 0x002f4bb4 in PyEval_EvalCodeEx ()
[snip]

Предполагаемая проблема

Я считаю, что проблемабудь то, что мой код ссылается на новую версию libstdc ++:

/opt/local/lib/gcc45/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.14.0)

, тогда как двоичный файл Python имеет очень косвенную зависимость от системы libstdc++, которая загружается первой (вывод из info shared в gdb):

  1 dyld                  - 0x8fe00000        dyld Y Y /usr/lib/dyld at 0x8fe00000 (offset 0x0) with prefix "__dyld_"
  2 Python                - 0x1000            exec Y Y /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python (offset 0x0)
                                          (objfile is) /opt/local/bin/python
  3 Python                F 0x219000          dyld Y Y /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Python at 0x219000 (offset 0x219000)
  4 libSystem.B.dylib     - 0x9723d000        dyld Y Y /usr/lib/libSystem.B.dylib at 0x9723d000 (offset -0x68dc3000)
                                 (commpage objfile is) /usr/lib/libSystem.B.dylib[LC_SEGMENT.__DATA.__commpage]
  5 CoreFoundation        F 0x970b3000        dyld Y Y /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation at 0x970b3000 (offset -0x68f4d000)
  6 libgcc_s.1.dylib      - 0x923e6000        dyld Y Y /usr/lib/libgcc_s.1.dylib at 0x923e6000 (offset -0x6dc1a000)
  7 libmathCommon.A.dylib - 0x94af5000        dyld Y Y /usr/lib/system/libmathCommon.A.dylib at 0x94af5000 (offset -0x6b50b000)
  8 libicucore.A.dylib    - 0x97cf4000        dyld Y Y /usr/lib/libicucore.A.dylib at 0x97cf4000 (offset -0x6830c000)
  9 libobjc.A.dylib       - 0x926f0000        dyld Y Y /usr/lib/libobjc.A.dylib at 0x926f0000 (offset -0x6d910000)
                                 (commpage objfile is) /usr/lib/libobjc.A.dylib[LC_SEGMENT.__DATA.__commpage]
 10 libauto.dylib         - 0x95eac000        dyld Y Y /usr/lib/libauto.dylib at 0x95eac000 (offset -0x6a154000)
 11 libstdc++.6.0.4.dylib - 0x97e3d000        dyld Y Y /usr/lib/libstdc++.6.0.4.dylib at 0x97e3d000 (offset -0x681c3000)
 12 _mesh_oned.so         - 0x1000000         dyld Y Y /Users/sethrj/_code/_build/pytrt-gcc45DEBUG/meshlib/swig/_mesh_oned.so at 0x1000000 (offset 0x1000000)
 13 libhdf5.7.dylib       - 0x122c000         dyld Y Y /opt/local/lib/libhdf5.7.dylib at 0x122c000 (offset 0x122c000)
 14 libz.1.2.5.dylib      - 0x133000          dyld Y Y /opt/local/lib/libz.1.2.5.dylib at 0x133000 (offset 0x133000)
 15 libstdc++.6.dylib     - 0x600000          dyld Y Y /opt/local/lib/gcc45/libstdc++.6.dylib at 0x600000 (offset 0x600000)
[snip]

Обратите внимание, что ошибка malloc возникает в адресе памяти системы libstdc++, а не в том, с которым связана общая библиотека.

Попытки разрешения

Я пытался заставить MacPorts собирать Python, используя GCC 4.5, а не компилятор Apple, но фаза установки не удалась, потому что ему нужно было создать «Framework» для Mac, чего, по-видимому, ванильный GCC не делает.

Даже с флагом компилятора -static-libstdc++ __ostream_insert вызывает std::basic_streambuf из загруженной системой общей библиотеки.

Я попытался изменить DYLD_LIBRARY_PATH, добавив /opt/local/lib/gcc45/, но безрезультатно.

Что я могу сделать, чтобы заставить это работать?Я нахожусь в тупике.

Дополнительная информация

Эта проблема, кажется, характерна для Mac OS X .Обратите внимание, как во всех выходных данных отладки адрес переходит между вызовами на std::__ostream_insert и std::basic_streambuf::xsputn: он покидает новый код GCC 4.5 и переходит к старому коду общей библиотеки в /usr/bin.Теперь, чтобы найти обходной путь ...

Ответы [ 2 ]

2 голосов
/ 05 октября 2011

Решил это.Я обнаружил, что эта проблема не является чем-то необычным при смешивании версий GCC на Mac.Прочитав это решение для mpich и проверив исходный код mpich , я обнаружил, что решение заключается в добавлении следующего флага в gcc в системах Mac:

-flat_namespace

Я так счастлив.Я бы хотел, чтобы мне не потребовалось недели, чтобы понять.:)

0 голосов
/ 01 октября 2011

Запустить Python в GDB, установить точку останова на malloc_error_break.Это покажет вам, что освобождается, что не выделено.Я сомневаюсь, что это ошибка между ABI между версиями libstdc ++.

...