Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meaning of C++/pthread/join error message "what(): Invalid argument"

Tags:

c++

pthreads

It is a part of a larger application, a simple timer thread, which works correctly before an attempt to finish it:

boost::asio::io_service io_service;
shared_ptr<thread> loop;
// it is not initialised here, just shows the idea
boost::asio::deadline_timer timer(io_service, interval);

void Timer::spin() {
    loop = make_shared<thread>(&Timer::run, this);
}
void Timer::unspin() {
    io_service.stop();
    loop.get()->join();
}
void run() {
   timer.async_wait(bind(&Timer::callbackWrapper, this, _1));
   // restart
   io_service.run();    
}

The thread created in spin is in theory terminated and joined in unspin(). In case when the application ends with join() commented out, there in an error message

terminate called without an active exception

which, if I "decrypted" it well, means "main thread finished when some other threads are still running" (I do not know the C++ lingo.)

If, in turn, unspin() is called, the following spotty error message may show:

terminate called after throwing an instance of 'std::system_error'
  what():  Invalid argument

which is most probably thrown by thread.join(). The problem is, I searched around Stackexchange, but could not explain the other message. I realise that the problem can be outside the small fragment of code (the application is rather large, so I do not include it). But even if it is so, I would just ask for the meaning of the second error message and its possible causes.

like image 498
scriptfoo Avatar asked Oct 29 '25 14:10

scriptfoo


2 Answers

In my particular case, the exception was thrown because the thread had already been joined. Check joinable before joining.

like image 125
Daisuke Aramaki Avatar answered Oct 31 '25 05:10

Daisuke Aramaki


The possible causes for something to throw std::system_error (with EINVAL, as here, or with some other value) are numerous.

You could either:

  1. Google for instances of std::system_error on cppreference.com, or
  2. Instruct your debugger to break on throw, then you can see exactly what's caused an exception to be thrown — then go to the documentation for that thing and read why it would throw.

These messages aren't cryptic per se, they're just indirect oweing to the way the whole C++ ecosystem works. Could it have been designed to call some specific "terminate" function solely reserved for the case where you forget to join a thread? Sure.

But that would be really unwieldy, bulking up the size of the runtime module, for not really any gain. As you write more code you will gain experience and start just remembering or "feeling" what sort of things can cause what sort of problems. Anything about std::system_error or std::terminate in multi-threaded code is almost certainly something to do with improper handling of said threads. You just get to know that after a while.

In this case you can memorise the two following explanations:

terminate called without an active exception

Something called std::terminate directly. Again, you can search for utterances of this in library documentation and find out possible causes that relate to your code.

terminate called after throwing an instance of 'std::system_error'

An exception was thrown, but you have no try/catch in your program that caught it, so std::terminate was invoked by the exceptions system. Again, you can research what features you're using can throw std::system_error, and also consider adding some exception safety to your code while you're at it.

like image 44
Lightness Races in Orbit Avatar answered Oct 31 '25 03:10

Lightness Races in Orbit