Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beast Socket from Boost Python Package Kills Kernel #2922

Closed
MasterBe opened this issue Aug 30, 2024 · 4 comments
Closed

Beast Socket from Boost Python Package Kills Kernel #2922

MasterBe opened this issue Aug 30, 2024 · 4 comments

Comments

@MasterBe
Copy link

For some reason when exposing the below to python using Boost Python, the unique pointer constructor (the obj constructor) fails. This used to work for me before, not sure why it stopped.

#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

Any idea what I am doing wrong? When running this using c++ as follows does not fail.

SocketExample sk;
sk.constructSocket(); //works fine when run inside main.cpp
@ashtum
Copy link
Collaborator

ashtum commented Aug 30, 2024

What version of Boost are you using? Are there any errors or messages that might help?

@MasterBe
Copy link
Author

MasterBe commented Aug 30, 2024

Hi I am using boost version 1_84 (#define BOOST_VERSION 108400). I am running on release mode no errors/messages, I tried to try-catch and cout to screen but the error is not catchable just kills kernel. I tried constructing the socket step by step and I can without error execute the following code from python:

	std::cout << "START" << std::endl;
	using NextLayer = boost::asio::ssl::stream<boost::asio::ip::tcp::socket>;
	using ws_stream = boost::beast::websocket::stream<NextLayer>;
	boost::asio::io_context m_ctx{};
	boost::asio::ssl::context m_ssl(boost::asio::ssl::context::sslv23_client);
	boost::empty_value<NextLayer>(boost::empty_init_t{}, m_ctx, m_ssl);
	//auto m_stream = std::make_unique<ws_stream::impl_type>(m_ctx, m_ssl);
	//std::cout << "OPEN: 139 < " << m_stream->rd_buf.max_size() << std::endl;
	std::cout << "END" << std::endl;

I made impl_type public for the sake of debugging. Still this: auto m_stream = std::make_unique<ws_stream::impl_type>(m_ctx, m_ssl); fails

The boost code is:

    template<class... Args>
    impl_type(Args&&... args)
        : boost::empty_value<NextLayer>(
            boost::empty_init_t{},
            std::forward<Args>(args)...)
        , detail::service::impl_type(
            this->get_context(
                this->boost::empty_value<NextLayer>::get().get_executor()))
        , timer(this->boost::empty_value<NextLayer>::get().get_executor())
    {
        timeout_opt.handshake_timeout = none();
        timeout_opt.idle_timeout = none();
        timeout_opt.keep_alive_pings = false;
    }

So looks like it's the second part failing. (something to do with context maybe)

@MasterBe
Copy link
Author

MasterBe commented Aug 30, 2024

I can track it down to here:

	std::cout << "START" << std::endl;
	struct impex : public boost::beast::websocket::detail::service::impl_type
	{
		impex(boost::asio::execution_context& ctx) : boost::beast::websocket::detail::service::impl_type(ctx) {};
		virtual
			void
			shutdown() {}
	};

	boost::asio::execution_context ctx;
	impex v(ctx); //kills kernel
	std::cout << "END" << std::endl;

Looking at: include\boost\asio\execution_context.hpp. Not sure who is initializing: boost::asio::detail::service_registry* service_registry_;?

@sehe
Copy link
Collaborator

sehe commented Aug 30, 2024

For info, I answered the same question on StackOverflow https://stackoverflow.com/a/78933665/85371 where I was able to demonstrate it working from a Jupyter Notebook in principle. I also imagined a technical reason why things would stop working, although @MasterBe 's problem ostensibly has a different exact root cause.

Given the extra info in this ticket, I'd still look at compiler flags and shared libraries (ldconf/SxS/manifests depending on platforms)

@ashtum ashtum closed this as completed Oct 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants