Commit 540b1887 authored by Kenton Varda's avatar Kenton Varda

Use UnwindDetector to protect against exceptions in all these RPC object desturctors.

parent 2d1c9a53
...@@ -735,6 +735,7 @@ private: ...@@ -735,6 +735,7 @@ private:
: RpcClient(connectionState), importId(importId) {} : RpcClient(connectionState), importId(importId) {}
~ImportClient() noexcept(false) { ~ImportClient() noexcept(false) {
unwindDetector.catchExceptionsIfUnwinding([&]() {
// Remove self from the import table, if the table is still pointing at us. (It's possible // Remove self from the import table, if the table is still pointing at us. (It's possible
// that another thread attempted to obtain this import just as the destructor started, in // that another thread attempted to obtain this import just as the destructor started, in
// which case that other thread will have constructed a new ImportClient and placed it in // which case that other thread will have constructed a new ImportClient and placed it in
...@@ -757,6 +758,7 @@ private: ...@@ -757,6 +758,7 @@ private:
builder.setReferenceCount(remoteRefcount); builder.setReferenceCount(remoteRefcount);
message->send(); message->send();
} }
});
} }
void addRemoteRef() { void addRemoteRef() {
...@@ -794,6 +796,8 @@ private: ...@@ -794,6 +796,8 @@ private:
uint remoteRefcount = 0; uint remoteRefcount = 0;
// Number of times we've received this import from the peer. // Number of times we've received this import from the peer.
kj::UnwindDetector unwindDetector;
}; };
class PipelineClient final: public RpcClient { class PipelineClient final: public RpcClient {
...@@ -1372,6 +1376,7 @@ private: ...@@ -1372,6 +1376,7 @@ private:
CapInjectorImpl(RpcConnectionState& connectionState) CapInjectorImpl(RpcConnectionState& connectionState)
: connectionState(connectionState) {} : connectionState(connectionState) {}
~CapInjectorImpl() noexcept(false) { ~CapInjectorImpl() noexcept(false) {
unwindDetector.catchExceptionsIfUnwinding([&]() {
kj::Vector<kj::Own<ResolutionChain>> thingsToRelease(exports.size()); kj::Vector<kj::Own<ResolutionChain>> thingsToRelease(exports.size());
if (connectionState.networkException == nullptr) { if (connectionState.networkException == nullptr) {
...@@ -1379,6 +1384,7 @@ private: ...@@ -1379,6 +1384,7 @@ private:
thingsToRelease.add(connectionState.releaseExport(exportId, 1)); thingsToRelease.add(connectionState.releaseExport(exportId, 1));
} }
} }
});
} }
bool hasCaps() { bool hasCaps() {
...@@ -1451,6 +1457,8 @@ private: ...@@ -1451,6 +1457,8 @@ private:
kj::Vector<ExportId> exports; kj::Vector<ExportId> exports;
// IDs of objects exported during finishDescriptors(). These will need to be released later. // IDs of objects exported during finishDescriptors(). These will need to be released later.
kj::UnwindDetector unwindDetector;
static const void* identity(const rpc::CapDescriptor::Reader& desc) { static const void* identity(const rpc::CapDescriptor::Reader& desc) {
// TODO(cleanup): Don't rely on internal APIs here. // TODO(cleanup): Don't rely on internal APIs here.
return _::PointerHelpers<rpc::CapDescriptor>::getInternalReader(desc).getLocation(); return _::PointerHelpers<rpc::CapDescriptor>::getInternalReader(desc).getLocation();
...@@ -1471,6 +1479,7 @@ private: ...@@ -1471,6 +1479,7 @@ private:
: connectionState(kj::addRef(connectionState)), id(id), fulfiller(kj::mv(fulfiller)) {} : connectionState(kj::addRef(connectionState)), id(id), fulfiller(kj::mv(fulfiller)) {}
~QuestionRef() { ~QuestionRef() {
unwindDetector.catchExceptionsIfUnwinding([&]() {
if (connectionState->networkException != nullptr) { if (connectionState->networkException != nullptr) {
return; return;
} }
...@@ -1505,6 +1514,7 @@ private: ...@@ -1505,6 +1514,7 @@ private:
} else { } else {
question.selfRef = nullptr; question.selfRef = nullptr;
} }
});
} }
inline QuestionId getId() const { return id; } inline QuestionId getId() const { return id; }
...@@ -1533,6 +1543,7 @@ private: ...@@ -1533,6 +1543,7 @@ private:
QuestionId id; QuestionId id;
kj::Own<kj::PromiseFulfiller<kj::Promise<kj::Own<RpcResponse>>>> fulfiller; kj::Own<kj::PromiseFulfiller<kj::Promise<kj::Own<RpcResponse>>>> fulfiller;
kj::Maybe<kj::Own<CapExtractorImpl>> resultCaps; kj::Maybe<kj::Own<CapExtractorImpl>> resultCaps;
kj::UnwindDetector unwindDetector;
}; };
class RpcRequest final: public RequestHook { class RpcRequest final: public RequestHook {
...@@ -2811,6 +2822,7 @@ public: ...@@ -2811,6 +2822,7 @@ public:
} }
~Impl() noexcept(false) { ~Impl() noexcept(false) {
unwindDetector.catchExceptionsIfUnwinding([&]() {
// std::unordered_map doesn't like it when elements' destructors throw, so carefully // std::unordered_map doesn't like it when elements' destructors throw, so carefully
// disassemble it. // disassemble it.
if (!connections.empty()) { if (!connections.empty()) {
...@@ -2823,6 +2835,7 @@ public: ...@@ -2823,6 +2835,7 @@ public:
deleteMe.add(kj::mv(entry.second)); deleteMe.add(kj::mv(entry.second));
} }
} }
});
} }
Capability::Client restore(_::StructReader hostId, ObjectPointer::Reader objectId) { Capability::Client restore(_::StructReader hostId, ObjectPointer::Reader objectId) {
...@@ -2850,6 +2863,8 @@ private: ...@@ -2850,6 +2863,8 @@ private:
ConnectionMap; ConnectionMap;
ConnectionMap connections; ConnectionMap connections;
kj::UnwindDetector unwindDetector;
RpcConnectionState& getConnectionState(kj::Own<VatNetworkBase::Connection>&& connection) { RpcConnectionState& getConnectionState(kj::Own<VatNetworkBase::Connection>&& connection) {
auto iter = connections.find(connection); auto iter = connections.find(connection);
if (iter == connections.end()) { if (iter == connections.end()) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment