关闭嵌入式PySide / PyQt4 python代码

时间:2018-03-28 14:17:15

标签: c++ memory-leaks qt4 pyside address-sanitizer

我正在使用嵌入式python解释器加载一些PySide(或PyQt4)脚本的C ++ Qt4应用程序。我注意到Address Sanitizer在退出c ++退出时报告了内存泄漏。

为了解决这个问题,我编写了一个嵌入在C ++中的简单PySide代码,试图了解内存泄漏的来源。

我在尝试各种各样的事情时花了很长时间,但无济于事。我怀疑它与某些引用计数错误有关,当Python解释器关闭时会造成一些麻烦,但我不确定。

有人可以帮我理解我做错了吗?

这是我的简单代码:

#include <iostream>
#include "Python.h"

class EmbedPySide
{

public:

  EmbedPySide()
  {
    char name[] = "test";
    Py_SetProgramName(name);
    Py_Initialize();

    std::string code =
        "from PySide import QtGui\n"
        ""
        "class EmbededPySide(QtGui.QApplication):\n"
        ""
        "    def __init__(self):\n"
        "        super(EmbededPySide, self).__init__([])\n"
        "        self.button = QtGui.QPushButton('Shutdown')\n"
        "        self.button.clicked.connect(self.cleanUp)\n"
        "        self.win = QtGui.QMainWindow()\n"
        "        self.win.setCentralWidget(self.button)\n"
        "        self.win.move(600, 300)\n"
        "        self.win.show()\n"
        ""
        "    def cleanUp(self):\n"
        "        del self.button\n"
        "        del self.win\n"
        "        self.quit()\n"
        ""
        "if __name__=='__main__':\n"
        "    app = EmbededPySide()\n"
        "    app.exec_()";

    PyRun_SimpleString(code.c_str());
  }

  ~EmbedPySide()
  {
    Py_Finalize();
    std::cout << "Destructor called" << std::endl;
  }

};

int main()
{
  EmbedPySide embedded;

  std::cout << "Exiting" << std::endl;
}

我编译它:

g++ main.cpp -O1 -g -fsanitize=address -fno-omit-frame-pointer \
-I/usr/include/python2.7 -lpython2.7

为清楚起见,这是我在代码字符串中编写的python代码:

from PySide import QtGui

class EmbededPySide(QtGui.QApplication):

    def __init__(self):
        super(EmbededPySide, self).__init__([])
        self.button = QtGui.QPushButton('Shutdown')
        self.button.clicked.connect(self.cleanUp)
        self.win = QtGui.QMainWindow()
        self.win.setCentralWidget(self.button)
        self.win.move(600, 300)
        self.win.show()

    def cleanUp(self):
        del self.button
        del self.win
        self.quit()

if __name__=='__main__':
    app = EmbededPySide()
    app.exec_()

在运行中,这是我得到的输出:

  

退出

     

析构函数叫

     

=============================================== ==================   == 5063 ==错误:LeakSanitizer:检测到内存泄漏

     

直接泄漏1277个对象中的3377664个字节,这些对象分配自:       __interceptor_calloc中的#0 0x7f161d4fb79a(/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9879a)       #1 0x7f161d0349ab(/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x1619ab)

     

从以下分配的1个对象直接泄漏786432个字节:       __interceptor_calloc中的#0 0x7f161d4fb79a(/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9879a)       #1 0x7f161d0349ab(/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0x1619ab)       #2 0x4f622d95dcb87ff()

     

从以下分配的27个对象中直接泄漏24680个字节:       malloc中的#0 0x7f161d4fb602(/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)       _PyObject_GC_Malloc中的#1 0x7f161cfacd48(/usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0+0xd9d48)

     

[...]

谢谢!

0 个答案:

没有答案