Python 和 libstdc 的动态库问题++

发布于 2024-12-06 18:32:34 字数 5236 浏览 0 评论 0 原文

执行摘要:Python 模块链接到与 Python 可执行文件不同的 libstdc++.dylib 版本。结果是模块中对 iostream 的调用崩溃。

背景故事

我正在一台旧计算机(运行 10.5.8)上使用 SWIG 创建一个 Python 模块。由于各种原因,我使用 GCC 4.5(通过 MacPorts 安装)来执行此操作,并使用 Python 2.7(通过 MacPorts 安装,使用系统默认的 GCC 4.0.1 编译)。

观察到的行为

长话短说:在 Python 中调用 str( myObject ) 会导致 C++ 代码依次调用 std::operator<< ; >。这会生成以下错误:

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++,它首先加载(gdb中info共享的输出):

  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 使用 GCC 4.5 而不是 Apple 编译器构建 Python,但安装阶段失败,因为它需要创建 Mac“框架”,而普通 GCC 显然不这样做。

即使使用 -static-libstdc++ 编译器标志,__ostream_insert 也会从系统加载的共享库调用 std::basic_streambuf

我尝试通过添加 /opt/local/lib/gcc45/ 来修改 DYLD_LIBRARY_PATH 但无济于事。

我该怎么做才能让它发挥作用?我已经无计可施了。

更多信息

此问题似乎是 Mac 操作系统的常见问题x。请注意,在所有调试输出中,地址如何在对 std::__ostream_insertstd::basic_streambuf::xsputn 的调用之间跳转:它离开了新的 GCC 4.5代码并跳转到 /usr/bin 中较旧的共享库代码。现在,要找到解决方法...

Executive summary: a Python module is linked against a different version of libstdc++.dylib than the Python executable. The result is that calls to iostream from the module crash.

Backstory

I'm creating a Python module using SWIG on an older computer (running 10.5.8). For various reasons, I am using GCC 4.5 (installed via MacPorts) to do this, using Python 2.7 (installed via MacPorts, compiled using the system-default GCC 4.0.1).

Observed Behavior

To make a long story short: calling str( myObject ) in Python causes the C++ code in turn to call std::operator<< <std::char_traits<char> >. This generates the following error:

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

Setting a breakpoint and calling backtrace when it fails gives:

#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]

Suspected issue

I believe the issue to be that my code links against a new version of libstdc++:

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

whereas the Python binary has a very indirect dependence on the system libstdc++, which loads first (output from info shared in 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]

Note that the malloc error occurs in the memory address for the system libstdc++, not the one the shared library is linked against.

Attempted resolutions

I tried to force MacPorts to build Python using GCC 4.5 rather than the Apple compiler, but the install phase fails because it needs to create a Mac "Framework", which vanilla GCC apparently doesn't do.

Even with the -static-libstdc++ compiler flag, __ostream_insert calls the std::basic_streambuf from the system-loaded shared library.

I tried modifying DYLD_LIBRARY_PATH by prepending /opt/local/lib/gcc45/ but without avail.

What can I do to get this to work? I'm at my wit's end.

More information

This problem seems to be common to mac os x. Notice how in all of the debug outputs show, the address jumps between the calls to std::__ostream_insert and std::basic_streambuf::xsputn: it's leaving the new GCC 4.5 code and jumping into the older shared library code in /usr/bin. Now, to find a workaround...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

祁梦 2024-12-13 18:32:34

解决了。我发现在 Mac 上混合 GCC 版本时这个问题并不少见。阅读此 mpich 解决方案并检查mpich源代码,我发现解决方案是在mac系统上的gcc中添加以下标志:

-flat_namespace

我太高兴了。我希望这没有花费我一周的时间来弄清楚。 :)

Solved it. I discovered that this problem is not too uncommon when mixing GCC versions on the mac. After reading this solution for mpich and checking the mpich source code, I found that the solution is to add the following flag to gcc on mac systems:

-flat_namespace

I am so happy. I wish this hadn't taken me a week to figure out. :)

如此安好 2024-12-13 18:32:34

在 GDB 中运行 Python,在 malloc_error_break 上设置断点。这将向您显示正在释放但未分配的内容。我怀疑这是 libstdc++ 版本之间的 ABI 之间的错误。

Run Python in GDB, set a breakpoint on malloc_error_break. That will show you what's being freed that's not allocated. I doubt that this is an error between ABIs between the versions of libstdc++.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文