abumq / easyloggingpp

C++ logging library. It is powerful, supports asynchronous low latency, extendable, light-weight, fast performing, thread and type safe and consists of many built-in features. It provides ability to write logs in your own customized format. It also provide support for logging your classes, third-party libraries, STL and third-party containers etc.
MIT License
3.79k stars 926 forks source link

Deadlock with ELPP_AS_DLL and ELPP_THREAD_SAFE defined on Windows 7 (and lower) #258

Open grishavanika opened 9 years ago

grishavanika commented 9 years ago

How to reproduce (v 9.80):

// log.h
#ifndef LOG_H_
#define LOG_H_
#define ELPP_AS_DLL
#if defined(EL_EXPORTS)
#  define ELPP_EXPORT_SYMBOLS
#endif
#define ELPP_THREAD_SAFE
#include "easyloggingpp/easylogging++.h"
#endif
// log.cpp
#include "log.h"
INITIALIZE_EASYLOGGINGPP
// main.cpp
#include <iostream>
#include "../el/log.h"
int main()
{
    std::cout << "TEST\n";
    LOG(ERROR) << "TEST";
}

(solution for Microsoft Visual Studio 2013) Compile an run it on Windows 7. Application will stuck and you will not see any console output.

Looks like the problem is with using std::mutex (possibly call to ::CreateMutex()) as global variable. Here are few links, that has such problem with using std::mutex inside ::DllMain():

The simplest solution is to use CRITICAL_SECTION instead std::mutex. So, in case of Windows, I fix the problem by using class Mutex:

#if ELPP_OS_WINDOWS && defined(ELPP_AS_DLL) && ELPP_THREADING_ENABLED
#  if defined(ELPP_USE_STD_THREADING)
#    undef ELPP_USE_STD_THREADING
#  endif
#endif

I do not see such problem on Windows 8 (8.1). And found it on Windows 7 that is running on VM,

Thanks

abumq commented 9 years ago

We can safely undefine ELPP_USE_STD_THREADING to use CRITICAL_SECTION as you suggested. Leaving this open for other suggestions using std::mutex (or to later have a look at links in detail)