terminate called without an active exception

Added by Gerd Hirsch 2 months ago

hello cute team,
I got the following exception:
terminate called without an active exception
3 [main] RingBufferTest 13500 cygwin_exception::open_stackdumpfile: Dumping stack trace to RingBufferTest.exe.stackdump

Tests an lockfree implementation of a SingleProducerSingleConsumer Queue:
the idea of the test is to stop a thread via a mutex until another
has changed the world, one thread pushes, the other pops:

My Reader Task: as a lambda in the test

auto readerTask = [&buffer, &popValue, &popReturnValue](){
popReturnValue = buffer.pop(popValue);

};
{
Guard lock(readerMutex); // pop runs on the mutex
Thread t(readerTask);
pushReturnValue = buffer.push(i+MAX, skippedValue); // this works
// next line produces the error, same code of the SUT
ASSERT_EQUALM("push()", !!expectedIsSkipped, buffer.push(i+MAX, skippedValue));
lock.unlock();
t.join();
}

some code of pop()
is like the following:
bool advanceReadPosition(){
this_outer->BlockingPolicy::waitForWriter();
bool retVal = this_outer->advanceReadPositionFrom(lastReadPosition);
if(retVal) ++lastReadPosition;
return retVal;
}

thx for support
gerd


Replies (1)

RE: terminate called without an active exception - Added by Peter Sommerlad 2 months ago

With high probability this terminate() is called be the std::thread destructor, because you are deleting a thread object that has not been joined. If an assertion fails it throws an exception causing your t.join and the lock.unlock to be skipped.

Using a lock-guard you should not need to unlock explicitly. to get the auto-join behavior for threads you'd need a ScopedThread adapter that, for example, Anthony Williams shows in his book. But since you seem not to use standard threads, I am speculating.

struct scoped_thread {
  scoped_thread(std::thread && t)
      : the_thread { std::move(t) } {
    if (!the_thread.joinable())
      throw std::logic_error { "no thread" };
  }
  ~scoped_thread() {
    the_thread.join();
  }
private:
  std::thread the_thread;
};

(1-1/1)