Table of Contents

C - C++ Threads - Troubleshooting - Program Crashes - Trying to acquire a std::mutex twice

Trying to acquire a mutex twice will cause undefined behavior.

In most debug implementations, it will likely result in a crash.


Example

The HelloWorld() function locks a mutex and then calls GoodBye().

What is interesting is that there will be no issue in the normal code path – the problem will only happen when the exception codepath is triggered, in which case we'll get in an undefined state/crash.

#include <iostream>
#include <thread>
#include <mutex>
 
std::mutex mu;
static int counter = 0;
 
 
void GoodBye()
{
  try
  {
    // Some operation.
  }
  catch (...)
  {
    std::lock_guard<std::mutex> lock(mu);
    std::cout << "Good Bye" << std::endl;
  }
}
 
 
void HelloWorld()
{
  std::lock_guard<std::mutex> lock(mu);
  counter++;
  GoodBye();
}
 
 
int main()
{
  std::thread t1(HelloWorld);
  t1.join();
  return 0;
}

Resolution

Structure the code in such a way that it does not try to acquire a previously locked mutex.

A superficial solution might be to just use a std::recursive_mutex — but this is almost always indicative of a bad design.