正确的代码示例:
#include "Python.h"
#include <string>
extern const int someConstant;
void some_function()
{
const char *begin = NULL;
const char *end = NULL;
std::string s(begin, end);
const int v = someConstant;
}
static PyMethodDef _G_methods[] =
{
{NULL, NULL, 0, NULL} /* Sentinel */
};
PyMODINIT_FUNC initsf()
{
PyObject *module;
if (!(module = Py_InitModule("sf", _G_methods)))
{
return;
}
PyObject *pyerror = PyErr_NewException("fs.error", NULL, NULL);
Py_INCREF(pyerror);
PyModule_AddObject(module, "error", pyerror);
}
这是扩展模块草案。尽可能简单。它有一个空的方法表和从原始docpage复制的初始化函数。它包含2(2)个故意错误:
变量someConstant已声明但未定义;
函数some_function已定义,但从未调用;
如果由dlopen / dlsym编译和打开:
sf.so: undefined symbol: someConstant
根据要求。但如果由Python解释器加载:
>>> from sf import *
Segmentation fault (core dumped)
最奇怪的是从core-file转发的python的backtrace:
#0 0x00000bd6 in ?? ()
#1 0xb775c057 in char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) () from /usr/local/lib/python2.7/dist-packages/sf.so
#2 0xb6f9abb6 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#3 0xb6c3fe30 in pkgInitConfig(Configuration&) () from /usr/lib/i386-linux-gnu/libapt-pkg.so.4.12
#4 0xb6cf959e in ?? () from /usr/lib/python2.7/dist-packages/apt_pkg.so
#5 0x081949c1 in PyEval_EvalFrameEx ()
#6 0x0819af70 in PyEval_EvalCodeEx ()
#7 0x0819bb03 in PyImport_ExecCodeModuleEx ()
#8 0x0814bd40 in ?? ()
#9 0x080a38c2 in ?? ()
#10 0x0814c6d4 in ?? ()
#11 0x081031ae in ?? ()
...
看来,Python的加载器调用了std :: string构造函数: - )。
所以,堆栈已损坏。它在加载无效模块时或在处理错误后卸载时发生。如果示例代码几乎没有改变,它就不会发生。在Python 2.7.3 / Linux Ubuntu 10 / gcc 4.6.3上已经观察到这种行为,并且绝对没有在Python 2.7.1 / FreeBSD 8.1 / gcc 4.2.1上显示。
问题:
答案 0 :(得分:3)
让我们再看看那个堆栈跟踪
#0 0x00000bd6 in ?? () #1 0xb775c057 in char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) () from /usr/local/lib/python2.7/dist-packages/sf.so #2 0xb6f9abb6 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) () from /usr/lib/i386-linux-gnu/libstdc++.so.6 #3 0xb6c3fe30 in pkgInitConfig(Configuration&) () from /usr/lib/i386-linux-gnu/libapt-pkg.so.4.12 #4 0xb6cf959e in ?? () from /usr/lib/python2.7/dist-packages/apt_pkg.so
因此libapt-pkg.so
中的函数会调用libstdc++.so
中的函数来调用模块中的函数。
您的功能永远不会被调用。但是,您的代码使用std::string
并为std::string
实例化某些函数,这些函数会包含在*.so
中,覆盖完全不同的*.so
使用的函数,并会导致某些函数崩溃我不完全确定原因的原因。
我的直觉告诉我,您使用gcc
创建了*.so
而不是g++
。您不会在链接时收到错误,因为链接共享对象不起作用。加载时不会收到错误,因为libstdc++
巧合已经加载。
您使用gcc
或g++
进行关联吗?尝试使用g++
。