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.8k stars 929 forks source link

Crash on INTIALIZE_EASYLOGGINGPP #394

Open dassie opened 8 years ago

dassie commented 8 years ago

I am getting a crash on start up of my program. It happens on line 3029 inside unsafeGetConfigTypeByRef(). The error message from xtree.h is "map/set iterator not dereferencable".

The relevant part of the code:

    template <typename Conf_T>
    inline Conf_T& unsafeGetConfigByRef(Level level, std::map<Level, Conf_T>* confMap, const char* confName) {
        ELPP_UNUSED(confName);
        typename std::map<Level, Conf_T>::iterator it = confMap->find(level);
        if (it == confMap->end()) {
            try {
                return confMap->at(Level::Global);
            } catch (...) {
                ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level [" 
                    << LevelHelper::convertToString(level) << "]"
                        << std::endl << "Please ensure you have properly configured logger.", false);
            }
        }
        return it->second;
    }

The method is being called with level = Global, confMap's size = 0, and confName = "fileStream". The exception is caught but the return statement causes another error. Seems like it's not handling the exception correctly?

Here is the call stack:


    myprogram.exe!std::_Debug_message(const wchar_t * message, const wchar_t * file, unsigned int line) Line 17 C++
    myprogram.exe!std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<enum el::Level const ,std::shared_ptr<std::basic_fstream<char,std::char_traits<char> > > > > > >::operator*() Line 238 C++
    myprogram.exe!std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<enum el::Level const ,std::shared_ptr<std::basic_fstream<char,std::char_traits<char> > > > > > >::operator*() Line 401   C++
    myprogram.exe!std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<enum el::Level const ,std::shared_ptr<std::basic_fstream<char,std::char_traits<char> > > > > > >::operator->() Line 405  C++
>   myprogram.exe!el::base::TypedConfigurations::unsafeGetConfigByRef<std::shared_ptr<std::basic_fstream<char,std::char_traits<char> > > >(el::Level level, std::map<enum el::Level,std::shared_ptr<std::basic_fstream<char,std::char_traits<char> > >,std::less<enum el::Level>,std::allocator<std::pair<enum el::Level const ,std::shared_ptr<std::basic_fstream<char,std::char_traits<char> > > > > > * confMap, const char * confName) Line 3029    C++
    myprogram.exe!el::base::TypedConfigurations::unsafeValidateFileRolling(el::Level level, const std::function<void __cdecl(char const *,unsigned __int64)> & PreRollOutCallback) Line 3198    C++
    myprogram.exe!el::base::TypedConfigurations::build(el::Configurations * configurations) Line 3104   C++
    myprogram.exe!el::base::TypedConfigurations::TypedConfigurations(el::Configurations * configurations, std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::shared_ptr<std::basic_fstream<char,std::char_traits<char> > >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::shared_ptr<std::basic_fstream<char,std::char_traits<char> > > > > > * logStreamsReference) Line 2911  C++
    myprogram.exe!el::Logger::configure(const el::Configurations & configurations) Line 3491    C++
    myprogram.exe!el::Logger::Logger(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & id, const el::Configurations & configurations, std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::shared_ptr<std::basic_fstream<char,std::char_traits<char> > >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::shared_ptr<std::basic_fstream<char,std::char_traits<char> > > > > > * logStreamsReference) Line 3441   C++
    myprogram.exe!el::base::RegisteredLoggers::get(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & id, bool forceCreation) Line 3681   C++
    myprogram.exe!el::base::Storage::Storage(const std::shared_ptr<el::LogBuilder> & defaultLogBuilder) Line 3972   C++
    myprogram.exe!el::base::`dynamic initializer for 'elStorage''() Line 14 C++
    myprogram.exe!_initterm(void (void) * * first, void (void) * * last) Line 22    C++
    [External Code] 

I'm compiling on Windows 8.1 with VS 2015 with x64 platform.

dassie commented 8 years ago

Tried to investigate the problem. And found that by commenting out this line, the crash went away:

define ELPP_NO_DEFAULT_LOG_FILE

This caused the Filename configuration type to be added to the default configuration types list, and so the function above was able to find it.

But I still don't want a default log file. Any recommendations?

abumq commented 8 years ago

Why don't you change default log file at pre-processing time to be /tmp/ may be ? see ELPP_DEFAULT_LOG_FILE in https://github.com/easylogging/easyloggingpp/blob/master/README.md

dassie commented 8 years ago

And have it go to a location that I can ignore. Not a bad work around. If I have time in the future I will try to figure out more about the crash to try to fix it.

Does this flag work properly for you?

abumq commented 8 years ago

yes this is what changes the underlying file destination (i.e, std::ofstream)

rggjan commented 8 years ago

Duplicate of https://github.com/easylogging/easyloggingpp/issues/327

Also related to https://github.com/easylogging/easyloggingpp/issues/367 and https://github.com/easylogging/easyloggingpp/issues/336

It can by fixed by applying patch #350 and defining ELPP_NO_LOG_TO_FILE