簡體   English   中英

Python在加載C ++編寫的擴展模塊時接收SIGSEGV

[英]Python receives SIGSEGV while loading C++ written extension module

正確的代碼示例:

#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)個故意錯誤:

  • 變量some​​Constant聲明但從未定義;

  • 函數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上顯示。

題:

  1. 它是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

所以libapt-pkg.so的函數調用libstdc++.so的函數libstdc++.so它調用模塊中的函數。

你的功能永遠不會被調用。 但是,你的代碼使用了std::string並為std::string實例化了一些函數,這些函數被包含在你的*.so ,覆蓋了完全不同的*.so所使用的函數,並且由於某種原因而崩潰我並不完全確定為什么。

我的直覺告訴我你使用gcc來創建*.so而不是g++ 您不會在鏈接時收到錯誤,因為鏈接共享對象不起作用。 加載時不會出現錯誤,因為libstdc++ 恰好已經加載了。

你使用gccg++進行鏈接嗎? 嘗試使用g++

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM