Boost Python 包中的 Beast Socket 会杀死内核

问题描述 投票:0回答:1

由于某种原因,当使用 Boost Python 将以下内容公开给 python 时,唯一的指针构造函数(obj 构造函数)失败。这以前对我有用,不知道为什么它停止了。

#pragma once
#include <memory>
#include <boost/asio/ssl.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/beast.hpp>

//Socket
class Contextable
{
public:
    Contextable() : m_ssl(boost::asio::ssl::context::sslv23_client) {}

protected:
    boost::asio::io_context    m_ctx;
    boost::asio::ssl::context  m_ssl;
};

class SocketExample : protected Contextable
{
    using SocketImp = boost::beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>;
public:
    SocketExample()
    {
    }

    void constructSocket()
    {
        m_ws = std::make_unique<SocketImp>(m_ctx, m_ssl); //kills jupyter kernel
        std::cout << "DONE. OPEN FLAG: " << m_ws->is_open() << std::endl;
    }

private:
    std::unique_ptr<SocketImp> m_ws;
};

//ExampleModule
#include <boost/python.hpp>

BOOST_PYTHON_MODULE(ExampleModule)
{
    boost::python::class_<SocketExample, std::shared_ptr<SocketExample>, boost::noncopyable>("SocketExample")
        .def(boost::python::init<>())
        .def("constructSocket", &SocketExample::constructSocket)
        ;
}
##Jupyter Notebook
import ExampleModule as m
socket = m.SocketExample()
socket.constructSocket() ##kills kernel

知道我做错了什么吗?当使用 C++ 运行时,如下所示不会失败。

SocketExample sk;
sk.constructSocket(); //works fine when run inside main.cpp
c++ boost boost-python boost-beast-websocket
1个回答
0
投票

您很可能引入了 Jupyter 环境中缺少的间接依赖项。

我已经编译了你的源代码(稍作修改)

#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/beast.hpp>
#include <iostream>
#include <memory>

// Socket
class Contextable {
  public:
    Contextable() : m_ssl(boost::asio::ssl::context::sslv23_client) {}

  protected:
    boost::asio::io_context   m_ctx;
    boost::asio::ssl::context m_ssl;
};

class SocketExample : protected Contextable {
    using SocketImp = boost::beast::websocket::stream<boost::asio::ssl::stream<boost::asio::ip::tcp::socket>>;

  public:
    SocketExample() { std::cout << "SocketExample constructor" << std::endl; }
    ~SocketExample() { std::cout << "SocketExample destructor" << std::endl; }

    void constructSocket() {
        m_ws = std::make_unique<SocketImp>(m_ctx, m_ssl);
        std::cout << "DONE. OPEN FLAG: " << m_ws->is_open() << std::endl;
    }

  private:
    std::unique_ptr<SocketImp> m_ws;
};

// ExampleModule
#include <boost/python.hpp>

BOOST_PYTHON_MODULE(ExampleModule) {
    boost::python::class_<SocketExample, std::shared_ptr<SocketExample>, boost::noncopyable>("SocketExample")
        .def(boost::python::init<>())
        .def("constructSocket", &SocketExample::constructSocket);
}

使用 python 进行简单的 CLI 测试:

enter image description here

启动 Jupyter 笔记本1:

enter image description here

天堂里的麻烦

作为为什么事情会崩溃的一个例子,让我通过添加来在 C++ 模块上启用 ASAN/UBSAN

-fsanitize=undefined,address

到编译器标志。现在,Python CLI 测试实际上将显示出了什么问题:

enter image description here

我们可以告诉 python 先加载 ASAN²:

LD_PRELOAD=/nix/store/jfilhsiqdgm4nks2z6labx3iq9qd077a-gcc-13.3.0-lib/lib/libasan.so.8 python ./test.py

然后它就起作用了,给出了一些预期的内存泄漏报告:

enter image description here

但是,如果您尝试将其加载到 Jupyter 笔记本中,它将不知道如何加载 ASAN 依赖项并失败:

¹ 免责声明 我从未使用过 Jupyter,所以我全新安装了它,然后就开始使用它了... ² 我使用

ldd ExampleModule.so

得到了这条路径
© www.soinside.com 2019 - 2024. All rights reserved.