Hi, I'm hitting a variety of exceptions on shutdown. Exactly what I hit seems to shift as I move things around to try to solve the problem, but here's the current one. This doesn't happen 100% of the time, so there must be a race involved:
> > avrenderer.exe!aardvark::CServerThread::Run::__l4::<lambda>(kj::Exception > && exception) Line 683 C++ > [External Code] > > avrenderer.exe!aardvark::CRecoverableExceptionHandler::onRecoverableException(kj::Exception > > && exception) Line 656 C++ > avrenderer.exe!kj::throwRecoverableException(kj::Exception && > exception, unsigned int ignoreCount) Line 878 C++ > avrenderer.exe!kj::_::Debug::Fault::~Fault() Line 332 C++ > > avrenderer.exe!kj::`anonymous-namespace'::AsyncStreamFd::read::__l2::<lambda>(unsigned > > __int64 result) Line 242 C++ > avrenderer.exe!kj::_::MaybeVoidCaller<unsigned __int64,unsigned > __int64>::apply<unsigned __int64 <lambda>(unsigned __int64) > >(kj::`anonymous-namespace'::AsyncStreamFd::read::__l2::unsigned __int64 > <lambda>(unsigned __int64) & func, unsigned __int64 && in) Line 135 C++ > avrenderer.exe!kj::_::TransformPromiseNode<unsigned __int64,unsigned > __int64,unsigned __int64 <lambda>(unsigned > __int64),kj::_::PropagateException>::getImpl(kj::_::ExceptionOrValue & > output) Line 401 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get::__l3::<lambda>() > Line 703 C++ > avrenderer.exe!kj::_::RunnableImpl<void <lambda>(void) >::run() Line 303 > C++ > avrenderer.exe!kj::_::runCatchingExceptions(kj::_::Runnable & runnable) > Line 1023 C++ > avrenderer.exe!kj::runCatchingExceptions<void <lambda>(void) > >(kj::_::TransformPromiseNodeBase::get::__l3::void <lambda>(void) && func) > Line 315 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get(kj::_::ExceptionOrValue > & output) Line 703 C++ > > avrenderer.exe!kj::_::TransformPromiseNodeBase::getDepResult(kj::_::ExceptionOrValue > > & output) Line 721 C++ > avrenderer.exe!kj::_::TransformPromiseNode<kj::_::Void,unsigned > __int64,void <lambda>(unsigned > __int64),kj::_::PropagateException>::getImpl(kj::_::ExceptionOrValue & > output) Line 396 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get::__l3::<lambda>() > Line 703 C++ > avrenderer.exe!kj::_::RunnableImpl<void <lambda>(void) >::run() Line 303 > C++ > avrenderer.exe!kj::_::runCatchingExceptions(kj::_::Runnable & runnable) > Line 1023 C++ > avrenderer.exe!kj::runCatchingExceptions<void <lambda>(void) > >(kj::_::TransformPromiseNodeBase::get::__l3::void <lambda>(void) && func) > Line 315 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get(kj::_::ExceptionOrValue > & output) Line 703 C++ > > avrenderer.exe!kj::_::TransformPromiseNodeBase::getDepResult(kj::_::ExceptionOrValue > > & output) Line 721 C++ > avrenderer.exe!kj::_::TransformPromiseNode<bool,kj::_::Void,bool > <lambda>(void),kj::_::PropagateException>::getImpl(kj::_::ExceptionOrValue > & output) Line 396 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get::__l3::<lambda>() > Line 703 C++ > avrenderer.exe!kj::_::RunnableImpl<void <lambda>(void) >::run() Line 303 > C++ > avrenderer.exe!kj::_::runCatchingExceptions(kj::_::Runnable & runnable) > Line 1023 C++ > avrenderer.exe!kj::runCatchingExceptions<void <lambda>(void) > >(kj::_::TransformPromiseNodeBase::get::__l3::void <lambda>(void) && func) > Line 315 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get(kj::_::ExceptionOrValue > & output) Line 703 C++ > > avrenderer.exe!kj::_::TransformPromiseNodeBase::getDepResult(kj::_::ExceptionOrValue > > & output) Line 721 C++ > > avrenderer.exe!kj::_::TransformPromiseNode<kj::Maybe<kj::Own<capnp::MessageReader> > > >,bool,kj::CaptureByMove<kj::Maybe<kj::Own<capnp::MessageReader> > > <lambda>(kj::Own<capnp::MessageReader> &&, bool),kj::Own<capnp::`anonymous > namespace'::AsyncMessageReader> > >,kj::_::PropagateException>::getImpl(kj::_::ExceptionOrValue & output) > Line 396 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get::__l3::<lambda>() > Line 703 C++ > avrenderer.exe!kj::_::RunnableImpl<void <lambda>(void) >::run() Line 303 > C++ > avrenderer.exe!kj::_::runCatchingExceptions(kj::_::Runnable & runnable) > Line 1023 C++ > avrenderer.exe!kj::runCatchingExceptions<void <lambda>(void) > >(kj::_::TransformPromiseNodeBase::get::__l3::void <lambda>(void) && func) > Line 315 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get(kj::_::ExceptionOrValue > & output) Line 703 C++ > > avrenderer.exe!kj::_::TransformPromiseNodeBase::getDepResult(kj::_::ExceptionOrValue > > & output) Line 721 C++ > > avrenderer.exe!kj::_::TransformPromiseNode<kj::Maybe<kj::Own<capnp::IncomingRpcMessage> > > >,kj::Maybe<kj::Own<capnp::MessageReader> > >,kj::Maybe<kj::Own<capnp::IncomingRpcMessage> > > <lambda>(kj::Maybe<kj::Own<capnp::MessageReader> > > &&),kj::_::PropagateException>::getImpl(kj::_::ExceptionOrValue & output) > Line 396 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get::__l3::<lambda>() > Line 703 C++ > avrenderer.exe!kj::_::RunnableImpl<void <lambda>(void) >::run() Line 303 > C++ > avrenderer.exe!kj::_::runCatchingExceptions(kj::_::Runnable & runnable) > Line 1023 C++ > avrenderer.exe!kj::runCatchingExceptions<void <lambda>(void) > >(kj::_::TransformPromiseNodeBase::get::__l3::void <lambda>(void) && func) > Line 315 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get(kj::_::ExceptionOrValue > & output) Line 703 C++ > > avrenderer.exe!kj::_::TransformPromiseNodeBase::getDepResult(kj::_::ExceptionOrValue > > & output) Line 721 C++ > > avrenderer.exe!kj::_::TransformPromiseNode<bool,kj::Maybe<kj::Own<capnp::IncomingRpcMessage> > > >,bool <lambda>(kj::Maybe<kj::Own<capnp::IncomingRpcMessage> > > &&),kj::_::PropagateException>::getImpl(kj::_::ExceptionOrValue & output) > Line 396 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get::__l3::<lambda>() > Line 703 C++ > avrenderer.exe!kj::_::RunnableImpl<void <lambda>(void) >::run() Line 303 > C++ > avrenderer.exe!kj::_::runCatchingExceptions(kj::_::Runnable & runnable) > Line 1023 C++ > avrenderer.exe!kj::runCatchingExceptions<void <lambda>(void) > >(kj::_::TransformPromiseNodeBase::get::__l3::void <lambda>(void) && func) > Line 315 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get(kj::_::ExceptionOrValue > & output) Line 703 C++ > > avrenderer.exe!kj::_::TransformPromiseNodeBase::getDepResult(kj::_::ExceptionOrValue > > & output) Line 721 C++ > avrenderer.exe!kj::_::TransformPromiseNode<kj::_::Void,bool,void > <lambda>(bool),kj::_::PropagateException>::getImpl(kj::_::ExceptionOrValue > & output) Line 396 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get::__l3::<lambda>() > Line 703 C++ > avrenderer.exe!kj::_::RunnableImpl<void <lambda>(void) >::run() Line 303 > C++ > avrenderer.exe!kj::_::runCatchingExceptions(kj::_::Runnable & runnable) > Line 1023 C++ > avrenderer.exe!kj::runCatchingExceptions<void <lambda>(void) > >(kj::_::TransformPromiseNodeBase::get::__l3::void <lambda>(void) && func) > Line 315 C++ > avrenderer.exe!kj::_::TransformPromiseNodeBase::get(kj::_::ExceptionOrValue > & output) Line 703 C++ > avrenderer.exe!kj::TaskSet::Task::fire() Line 180 C++ > avrenderer.exe!kj::EventLoop::turn() Line 373 C++ > avrenderer.exe!kj::WaitScope::poll() Line 413 C++ > avrenderer.exe!aardvark::CServerThread::Run() Line 689 C++ The specific exception in this case is that AsyncStreamFd wants to read some bytes but none are available, presumably because the client has disconnected. The overall flow of the system is something like this: 1. server starts up 2. several clients start up. Some are in-process. Some are other processes on the same system. 3. Run for a while 4. Clean up all the clients 5. sleep(1000) <-- this is where the exceptions happen 6. clean up the server The sleep is only there to help me sort out this problem. Once I make shutdown deterministic it'll go away. But it appears that clients disconnecting and being freed is actually causing an exception on the server. Is there some way for a server to handle client disconnections at arbitrary times without throwing? I could just swallow all exceptions as "must be a disconnect", but that doesn't seem quite right either since there could also be bugs in my own server code causing exceptions. I could make changes client-side too, but since clients can always just crash and not tell me about it that doesn't fully solve things. I *am* able to disconnect and reconnect clients while running in general. This seems to be unique to shutdown in some way I don't understand. (The server doesn't know it's shutting down yet when the exception occurs.) Any ideas? Joe -- You received this message because you are subscribed to the Google Groups "Cap'n Proto" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. Visit this group at https://groups.google.com/group/capnproto. To view this discussion on the web visit https://groups.google.com/d/msgid/capnproto/b816998f-a402-4f7f-a7ff-c2ace394f3b7%40googlegroups.com.
