正确的代码示例:
#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(两个)故意错误:
已声明但从 undefined variable someConstant;
函数 some_function 已定义,但从未调用;
如果被dlopen/dlsym编译打开:
sf.so: undefined symbol: someConstant
根据需要。但是如果由 Python 解释器加载:
>>> from sf import *
Segmentation fault (core dumped)
最奇怪的是从核心文件中转储的 python 回溯:
#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 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++。
关于c++ - Python 在加载 C++ 编写的扩展模块时收到 SIGSEGV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13261843/
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or