server: deserialization exceptuion guards

This commit is contained in:
Matej Sekoranja
2013-09-23 11:05:52 +02:00
parent 9102e42aed
commit f2a10fd37a
3 changed files with 58 additions and 9 deletions

View File

@@ -934,8 +934,21 @@ namespace pvAccess {
_responseHandler->handleResponse(&_socketAddress,
thisPointer, _version, _command, _payloadSize,
_socketBuffer);
} catch (std::exception& ex) {
LOG(
logLevelDebug,
"Unexpected exception in responseHandler: %s",
ex.what()
);
} catch(...) {
//noop // TODO print?
LOG(
logLevelDebug,
"Unexpected exception in responseHandler!"
);
}
_socketBuffer->setLimit(_storedLimit);

View File

@@ -596,6 +596,21 @@ void ServerGetHandler::handleResponse(osiSockAddr* responseFrom,
destroy(); \
}
#define DESERIALIZE_EXCEPTION_GUARD(code) \
try { \
code; \
} \
catch (std::exception &e) { \
Status status(Status::STATUSTYPE_ERROR, e.what()); \
BaseChannelRequester::sendFailureMessage((int8)command, transport, ioid, qosCode, status); \
throw; \
} \
catch (...) { \
Status status(Status::STATUSTYPE_ERROR, "unknown exception caught"); \
BaseChannelRequester::sendFailureMessage((int8)command, transport, ioid, qosCode, status); \
throw; \
}
ServerChannelGetRequesterImpl::ServerChannelGetRequesterImpl(ServerContextImpl::shared_pointer const & context, ServerChannelImpl::shared_pointer const & channel, const pvAccessID ioid, Transport::shared_pointer const & transport) :
BaseChannelRequester(context, channel, ioid, transport), _channelGet(), _bitSet(), _pvStructure()
@@ -796,8 +811,12 @@ void ServerPutHandler::handleResponse(osiSockAddr* responseFrom,
{
ScopedLock lock(channelPut); // TODO not needed if put is processed by the same thread
BitSet::shared_pointer putBitSet = request->getBitSet();
putBitSet->deserialize(payloadBuffer, transport.get());
request->getPVStructure()->deserialize(payloadBuffer, transport.get(), putBitSet.get());
DESERIALIZE_EXCEPTION_GUARD(
putBitSet->deserialize(payloadBuffer, transport.get());
request->getPVStructure()->deserialize(payloadBuffer, transport.get(), putBitSet.get());
);
}
channelPut->put(lastRequest);
}
@@ -1014,7 +1033,10 @@ void ServerPutGetHandler::handleResponse(osiSockAddr* responseFrom,
ChannelPutGet::shared_pointer channelPutGet = request->getChannelPutGet();
{
ScopedLock lock(channelPutGet); // TODO not necessary if read is done in putGet
request->getPVPutStructure()->deserialize(payloadBuffer, transport.get());
DESERIALIZE_EXCEPTION_GUARD(
request->getPVPutStructure()->deserialize(payloadBuffer, transport.get());
);
}
channelPutGet->putGet(lastRequest);
}
@@ -1477,8 +1499,11 @@ void ServerArrayHandler::handleResponse(osiSockAddr* responseFrom,
PVArray::shared_pointer array = request->getPVArray();
{
ScopedLock lock(channelArray); // TODO not needed if read by the same thread
offset = SerializeHelper::readSize(payloadBuffer, transport.get());
array->deserialize(payloadBuffer, transport.get());
DESERIALIZE_EXCEPTION_GUARD(
offset = SerializeHelper::readSize(payloadBuffer, transport.get());
array->deserialize(payloadBuffer, transport.get());
);
}
channelArray->putArray(lastRequest, offset, array->getLength());
}
@@ -1968,7 +1993,12 @@ void ServerRPCHandler::handleResponse(osiSockAddr* responseFrom,
// deserialize put data
ChannelRPC::shared_pointer channelRPC = request->getChannelRPC();
// pvArgument
PVStructure::shared_pointer pvArgument(SerializationHelper::deserializeStructureFull(payloadBuffer, transport.get()));
PVStructure::shared_pointer pvArgument;
DESERIALIZE_EXCEPTION_GUARD(
pvArgument = SerializationHelper::deserializeStructureFull(payloadBuffer, transport.get());
);
channelRPC->request(pvArgument, lastRequest);
}
}

View File

@@ -988,6 +988,7 @@ void printValues(vector<string> const & names, vector<PVStructure::shared_pointe
#define DEFAULT_TIMEOUT 3.0
#define DEFAULT_REQUEST "field(value)"
#define DEFAULT_RPC_REQUEST ""
double timeOut = DEFAULT_TIMEOUT;
string request(DEFAULT_REQUEST);
@@ -1197,7 +1198,7 @@ public:
}
else
{
std::cerr << "[" << m_channelName << "] failed to create channel get: " << status << std::endl;
std::cerr << "[" << m_channelName << "] failed to create channel RPC: " << status << std::endl;
m_connectionEvent.signal();
}
}
@@ -1430,6 +1431,7 @@ int main (int argc, char *argv[])
bool cleanupAndReport = false;
bool serviceRequest = false;
bool pvRequestProvidedByUser = false;
bool onlyQuery = false;
string service;
//string urlEncodedRequest;
@@ -1454,6 +1456,7 @@ int main (int argc, char *argv[])
break;
case 'r': /* Set pvRequest value */
request = optarg;
pvRequestProvidedByUser = true;
// do not override terse mode
if (mode == ValueOnlyMode) mode = StructureMode;
break;
@@ -1843,7 +1846,10 @@ int main (int argc, char *argv[])
// simply empty
PVStructure::shared_pointer pvRequest =
getCreateRequest()->createRequest(request, requester);
getCreateRequest()->createRequest(
!pvRequestProvidedByUser ? DEFAULT_RPC_REQUEST : request,
requester
);
if(pvRequest.get()==NULL) {
fprintf(stderr, "failed to parse request string\n");
return 1;