Crash on locking mutex

I'm trying to lock a C++11 mutex, but whenever I do this, I get

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



The try_lock is returning "0" before the call. The code works perfect on Ubuntu, but crashes on my Windows 10 partition.

I'm using MinGW W64 to compile. Any way to get rid of this crash?
Last edited on
When I tried to google information about this, I got a lot of results from people trying to compile bitcoin wallets under Windows :D

Can you post the smallest program you can create that generates the same error reliably? I'd like to try compiling it under Cygwin and see if the same thing happens, then again in Visual Studio Community to see if it happens there too. That would at least narrow the problem down a bit.
I tried to replicate it with
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <thread>
#include <mutex>
#include <stdio.h>


int main()
{
	std::mutex* lock = new std::mutex();
	printf("locking\n");
	lock->lock();
	printf("unlocking\n");
	lock->unlock();
	printf("done\n");
	delete lock;
	return 0;
}


but it ran fine. here is the minimum code that it crashes with, it a thread wrapper I'm writing

m.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <unistd.h>
#include "J118/Thread.h"

using namespace std;
using namespace J118;

class TestThread : public Thread
{
public:
	TestThread();
	void run();
};

TestThread::TestThread() : Thread()
{
	printf("Thread Created\n");
}

void TestThread::run()
{
	printf("Thread Started...\n");
	sleep(10);
	printf("Thread done\n");
}

int main()
{
	FILE* output = fopen("DEBUG.txt", "w");
	fprintf(output, "TEST\n");
	fclose(output);
	output = NULL;
	printf("TEST\n");
	Thread* t = new TestThread();
	t->start();
	printf("The thread is running...\n");
	t->join();
	//delete t;
	usleep(10000000);
	
	return 0;
}


src/Thread.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125

#include "J118/Thread.h"


//TODO: Fix crash when deleting right after creation.
namespace J118
{
	
Thread::Thread()
{
	thread_handle = NULL;
	strcpy(thread_name,"Uknown");
	running = false;
}

Thread::Thread(const char* n)\
{
	thread_handle = NULL;
	strcpy(thread_name,n);
	running = false;
	data_lock = new std::mutex();
}
	
Thread::~Thread()
{
	printf("Deleting thread\n");
	//data_lock->lock();
	if(thread_handle != NULL)
	{
		//data_lock->unlock();
		printf("ID001\n");
		join();
		printf("ID002\n");
		//thread_handle->detach();
		delete thread_handle;
		thread_handle = NULL;
	}
	else
	{
		data_lock->unlock();
	}
		
	
	SAFE_DELETE(data_lock);
}
	
void Thread::runProxy(void* me)
{
	
	printf("In thread...\n");
	
	Thread* callee = (Thread*)me;
	printf("Casted\n");
	callee->running = true;
	//callee->data_lock->unlock(); // Unlocking after thread is started [ID001]
	callee->run();
	//printf("POINT %x\n",((void*)callee->thread_handle));
	//delete callee->thread_handle;
	//callee->thread_handle = NULL;
	callee->running = false;
}
	
	
void Thread::start()
{
	printf("SSSSS\n");
	if(thread_handle != NULL)
	{
		//throw ThreadRunningException();
		if(running)
		{
			printf("Oh no...\n");
			throw ThreadRunningException();
			return;
		}
		else
		{
			join();
			//thread_handle->detach();
			delete thread_handle;
			thread_handle = NULL;
		}
	}
	else
	{
		printf("Starting\n");
		//data_lock->lock(); //Locking to start the thread [ID001]
		thread_handle = new std::thread(runProxy,this);
		printf("started\n");
	}
	
	
	
}
	
void Thread::join()
{
	int result = data_lock->try_lock();
	printf("Try lock returned %d\n", result);
	data_lock->lock(); //----------------------------------------CRASHES HERE------------------------------------------------
	printf("LOCKED\n");
	if(thread_handle != NULL && thread_handle->joinable())
	{
		printf("ID003\n");
		thread_handle->join();
		printf("ID004\n");
		delete thread_handle;
		thread_handle = NULL;
		data_lock->unlock();
	}
	else
	{
		data_lock->unlock();
	}
	
}

const char* ThreadRunningException::what() const throw()
{
	return "Instance of thread already running";
}


	
}/* namespace J118 */


include/J118/Thread.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#pragma once

//Universal Includes
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <exception>
#include <thread>
#include <mutex>

//J118 Library Includ1es
#include <J118/UtilityMacros.h>

//OS Specific Includes
#ifdef __linux__
#include <pthread.h>
#elif _WIN32

#else
#error "Cant determain type system, Threads failed to build!"
#endif

#define J118_THREAD_NAME_LENGTH 16
namespace J118
{

class ThreadRunningException: public std::exception
{
public:
	virtual const char* what() const throw();
};
	

class Thread
{
	
	
private:
	std::thread* thread_handle;
	std::mutex* data_lock;
	
	
protected:
	char thread_name[J118_THREAD_NAME_LENGTH];
	bool running;
	virtual void run() = 0;
	static void runProxy(void* me);
public:
	~Thread();
	Thread();
	Thread(const char* n);
	void start();
	void join();
	
	
};
} /*namespace J118 */


include/J118/UtilityMacros.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

#define SAFE_DELETE(pointer)\
if( pointer != nullptr)\
{\
	delete pointer;\
	pointer = nullptr;\
}\

#define SAFE_DELETE_ARRAY(pointer)\
if( pointer != nullptr)\
{\
	delete [] pointer;\
	pointer = nullptr;\
}


#define SAFE_FILE_CLOSE(pointer)\
if( pointer != nullptr)\
{\
	fclose(pointer);\
	pointer = nullptr;\
}


and I compile it with
G++ -o m m.cpp .\src\Thread.cpp -I include -static-libstdc++ -g -l pthread

and the output I get is
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
TEST
Thread Created
SSSSS
Starting
started
The thread is running...
Try lock returned 0
In tterminate called after throwing an instance of 'hstd::system_errorr'e
ad . what():  .Invalid argument.


This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Casted
Thread Started... 
I found the issue, I forgot to initialize the mutex in the default constructor. It's always the simplest things.
Why are you creating your mutexes with new? If you had made it a regular variable (i.e. std::mutex data_lock;) you couldn't have forgotten because it would be initialized automatically. The same could be said about your std::thread object.
Last edited on
Topic archived. No new replies allowed.