Responder calling Finish method causing ABORT SIGNAL inside c++ lambda function
palfonsoilluscio opened this issue · 2 comments
Describe the bug
We are implementing sort of a async/event-driven communication feature using a RPC method which a client can call in order to set some custom
event related property on the server. Every time this event property changes, the pre register listeners (other clients) will receive a callback with a certain value. The listeners will be executing a specific code in their respective lambda functions once all above happens, now inside that lambda function, we are executing the responder_.Finish method (ServerAsyncResponseWriter) which will terminate the corresponding unary call for that listener. The problem is when the Finish
method is executed inside the lambda function, it causes a SIGABRT exception when the size of the message is being calculated in the serialization logic.
Our server is in C++ and we are using Swift 5.5 grcp-swift
package 1.19.1 and Protobuf 1.24.0. This happens in both build modes debug and release).
To reproduce
Steps to reproduce the bug you've found:
- Try to call Finish method inside lambda function in c++ for a GRPCAsyncUnary call.
Expected behaviour
The call to Finish should be successful and should not cause a SIGABRT exception.
Additional information
Please have the code snippet which contains the class implementing the lambda function:
class SubscribeToAssetsEvents : public RequestBase {
public:
SubscribeToAssetsEvents( AsyncAssetStreamerManager& owner ) : RequestBase( owner ), ownerClass( owner ) {
owner_.grpc().service_.Requesthola(
&context_, &request_, &responder_, cq(), cq(), handle_.tag( Handle::Operation::CONNECT, [this, &owner]( bool ok, Handle::Operation /* op */ ) {
LOG_DEBUG << "\n" + me( *this ) << "\n\n*****************************************************************\n"
<< "- Processing a new connect from " << context_.peer()
<< "\n*****************************************************************\n"
<< endl;
cout << "\n" + me( *this ) << "\n\n*****************************************************************\n"
<< "- Processing a new connect from " << context_.peer()
<< "\n*****************************************************************\n"
<< endl;
if ( !ok ) [[unlikely]] {
LOG_DEBUG << "The CONNECT request-operation failed. Assuming we are shutting down" << endl;
cout << "The CONNECT request-operation failed. Assuming we are shutting down" << endl;
return;
}
// Creates a new instance so the service can handle requests from a new client
owner_.createNew<SubscribeToAssetsEvents>( owner );
// Starts the process
registerSubscriptions();
} ) );
}
private:
// Objects and variables
AsyncAssetStreamerManager& ownerClass;
::grpc::ServerContext context_;
::Illuscio::SubscriptionRequest request_;
::Illuscio::SubscriptionResponse reply_;
::grpc::ServerAsyncResponseWriter<decltype( reply_ )> responder_ { &context_ };
vector<Illuscio::ASSET_EVTS> subscription_request_events;
Handle handle_ { *this };
// Methods
void registerSubscriptions() {
// Assigns the requests' events elements to a local vector
vector<string> subscription_request_events( request_.events().begin(), request_.events().end() );
reply_.set_event_( "GET" );
reply_.set_url_( "assetURL" );
if ( !subscription_request_events.empty() ) {
ownerClass.watcher.AddPropertyChangedListener( [this](AssetEventInfo value) {
responder_.Finish(reply_, grpc::Status::OK, handle_.tag( Handle::Operation::FINISH, [this]( bool ok, Handle::Operation /* op */ ) {
if ( !ok ) [[unlikely]] {
LOG_DEBUG << "The FINISH aqui es request-operation failed." << endl;
cout << "The FINISH aqui es request-operation failed." << endl;
return;
}
request_.Clear();
}));
});
LOG_DEBUG << "Events' subscriptions were successful." << endl;
cout << "Events' subscriptions were successful." << endl;
} else {
LOG_DEBUG << "Events' subscription registration failed, since there are no events to subscribe to." << endl;
cout << "Events' subscription registration failed, since there are no events to subscribe to." << endl;
}
}
};
We have tried changing the capture list using value and references without success, also putting the same logic outside the lambda function works fine. Hopefully we are missing something...
I’m afraid we can’t support the C++ implementation of grpc. Can I please suggest filing the bug upstream?
Makes total sense, thank you. We will...