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

random ASSERT on boost::beast:websocket::impl::write.hpp with program termination #2943

Open
virgiliofornazin opened this issue Oct 23, 2024 · 7 comments

Comments

@virgiliofornazin
Copy link

Got an exception using boost::beast websocket with SSL, on this part of code
(file include/boost/beast/websocket/impl/write.hpp, line 549, on impl.wr_block.unlock(this), where wr_block.id_ == 0).

//--------------------------------------------------------------------------

upcall:
    impl.wr_block.unlock(this); << THIS UNLOCKED RAISE THE ASSERTION
    impl.op_close.maybe_invoke()
        || impl.op_idle_ping.maybe_invoke()
        || impl.op_rd.maybe_invoke()
        || impl.op_ping.maybe_invoke();
    this->complete(cont, ec, bytes_transferred_);
}

}

Using boost/1.86.0 from conan, built with clang++ using the following profile settings:

[settings]
arch=x86_64
build_type=Debug
compiler=clang
compiler.cppstd=23
compiler.version=18
compiler.libcxx=libstdc++11
os=Linux

[conf]
tools.build:compiler_executables = {"cpp": "/usr/bin/clang++", "c": "/usr/bin/clang"}
tools.build:cflags=["-fsanitize=address", "-g", "-O0"]
tools.build:cxxflags=["-fsanitize=address", "-g", "-O0"]
tools.build:exelinkflags=["-fsanitize=address", "-g", "-O0"]
tools.build:sharedlinkflags=["-fsanitize=address", "-g", "-O0"]
tools.info.package_id:confs=["tools.build:cflags", "tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags"]

[options]
b2/*:toolset=clang

Maybe the assertion being raised probably because of releasing a lock already released?

The call stack is attached as a file because cannot add it here since it´s bigcallstack.txt

@ashtum
Copy link
Collaborator

ashtum commented Oct 23, 2024

Is there a chance you're calling websocket::stream::async_write before the first operation has finished?

The algorithm, known as a composed asynchronous operation, is implemented in terms of calls to the next layer's async_write_some function. The program must ensure that no other calls to write, write_some, async_write, or async_write_some are performed until this operation completes.

@virgiliofornazin
Copy link
Author

virgiliofornazin commented Oct 23, 2024 via email

@ashtum
Copy link
Collaborator

ashtum commented Oct 23, 2024

well, an strand doesn't prevent you from calling async_write multiple times.

@virgiliofornazin
Copy link
Author

virgiliofornazin commented Oct 23, 2024 via email

@virgiliofornazin
Copy link
Author

I got the assert again, but what I detected: thread 1 create a ssl<tcp_stream> and perform a https request/reply (beast::async_write/beast::async_read), if I close the socket stream on another thread to abort the operation in case
of a logical timeout I decide to wait, the assert is raised.

I've managed to handle this connection status on my code, however, it seems to be a issue because the app couldn't
abort on this assertion.

Is there a way to 'close' the stream socket by another thread without raising this issue?

@ashtum
Copy link
Collaborator

ashtum commented Oct 25, 2024

If you want to close the stream from another thread, post the operation to the strand to prevent race conditions.

asio::post(ws.get_executor(), [&]{ ws.async_close(...); });

Assuming the websocket stream was constructed using an strand.

@virgiliofornazin
Copy link
Author

yes. it was. I'm trying to handle a 'request timed out' or 'communication timed out issue' when you issue a beast::async_read and cannot get a answer in a specific amount of time.

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

2 participants