【问题标题】:Boost.Python + OpenGL segmentation faultsBoost.Python + OpenGL 分段错误
【发布时间】:2009-11-17 20:05:13
【问题描述】:

我有一个用 Boost.Python 编写的(几乎)完美运行的 C++ 代码。它包装了一个基于共享指针的 3 或 4 个类的结构层次结构,没有什么非常复杂的(即 A 类有一个 B 类实例指针的 std::vector 等),称为 foo 的顶级包。

前段时间,我决定使用 PyOpenGL 将可视化添加到项目中。所以现在,每当我在拥有import foo 之前拥有import OpenGL 时,我就会在C++ 代码中遇到分段错误(例如,当我迭代一系列对象及其子对象时。)

我最好的假设是 OpenGL 以某种方式替代了内存分配函数或做一些类似的邪恶的事情。任何人都可以阐明情况吗?我会根据要求提供更多详细信息,但整个事情似乎相当混乱。

根据要求,隔离测试用例:

生成文件:

all:
    g++ -shared -o foo.so -fPIC \
        -I/usr/include/boost-1_37/ -I/usr/include/python2.5 \
        -lpython2.5 -lboost_python-1_37 \
        foo.cpp

Python 文件:

from OpenGL import *
import foo

b = foo.B()

for i in range(10):
    b.elements.append(foo.A())

for e in b.elements:
    print e

# Crash here if `from OpenGL import *` is present.

C++ 文件:

#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>

namespace bp = boost::python;

struct A {
    typedef boost::shared_ptr<A> ptr;
};

struct B {
    typedef boost::shared_ptr<B> ptr;
    std::vector<A::ptr> elements;
};


// Proxies B::elements without converting them 
// back and forth between lists.
struct ElementProxy {

    static ElementProxy 
    init(B::ptr b)
    {
        return ElementProxy(b);
    }

    ElementProxy(B::ptr b)
    : b_(b)
    {}

    size_t
    len() 
    {
        return (*b_).elements.size();
    }

    A::ptr
    getitem(size_t i) 
    {
        if (i >= len()) {
            PyErr_SetString(PyExc_IndexError, "Index out of bounds.");
            bp::throw_error_already_set();
        }
        return (*b_).elements[i];
    }

    void
    append(A::ptr e) 
    {
        (*b_).elements.push_back(e);
    }

    static boost::python::class_<ElementProxy> 
    wrap() 
    {
        return bp::class_<ElementProxy>("ElementProxy", bp::no_init)

            .def("__len__", &ElementProxy::len, 
                 (bp::arg("self")),
                 "Returns the number of contained elements"
                 )

            .def("__getitem__", &ElementProxy::getitem, 
                 (bp::arg("self"), bp::arg("i")), 
                 "Returns the element at given index"
                 )

            .def("append", &ElementProxy::append, 
                 (bp::arg("self"), bp::arg("element")), 
                 "Appends an element"
                 )
            ;
    }

private:

    B::ptr b_;
};



BOOST_PYTHON_MODULE(foo) {

    bp::class_<A, A::ptr, boost::noncopyable>("A") ;

    ElementProxy::wrap();

    bp::class_<B, B::ptr, boost::noncopyable>("B")
        .add_property("elements", &ElementProxy::init) ;
}

【问题讨论】:

  • 你能把它归结为一个最小的代码示例吗?能够查看它并可能对其进行测试,将有助于弄清楚它。
  • 将问题修改为包含一个。在这种特殊情况下,崩溃发生在循环之后,在实际框架中,它发生在第一次 for 迭代之后。感谢收看。
  • 可能没有直接帮助,但是.. 通常认为“从 SomeModule 导入 *”是个坏主意。也许尝试只导入你需要的东西?
  • 好建议,但仍然没有运气:((即from OpenGL import GL 仍然崩溃)

标签: python memory opengl boost segmentation-fault


【解决方案1】:

如果您的操作系统是 linux,您可能会遇到这个错误:https://bugs.launchpad.net/ubuntu/+source/mesa/+bug/259219

如果调用

export LD_PRELOAD=&lt;path-to-libstdc++&gt;

在启动程序之前修复它,就是这样。您需要替换为您机器上的实际路径。类似于 /usr/lib/gcc/i686-pc-linux-gnu/4.1.2/libstdc++.so.6 的东西。

该错误仅发生在某些图形驱动程序和发行版中,但非常普遍。特别是,它已在 Ubuntu 11.04 中得到修复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-15
    • 2018-09-14
    • 2012-11-02
    • 1970-01-01
    • 2020-08-08
    • 2021-08-18
    • 1970-01-01
    • 2020-07-19
    相关资源
    最近更新 更多