gabime / spdlog

Fast C++ logging library.
Other
23.12k stars 4.38k forks source link

Missing "shutdown" in the "spdlog::details::registry" destructor #3109

Open xmirabel opened 1 month ago

xmirabel commented 1 month ago

CONTEXT: I have a specific use case :

The simulation is run, then

Each model use its own spdlog multisink logger :

Before a model is unloaded, its logger calls spdlog::drop

BUG:

WORKAROUND FOUND

PERENNIAL SOLUTION Could you please add a destructor with shutdown in the original spdlog::details::registry?

tt4g commented 1 month ago

It is not safe to call shutdown() in the spdlog::details::registry destructor, which is a static variable object. This is because calling shutdown destroys threads used internally, but there is no guarantee that these can be safely executed outside the main() function. shutdown() should always be called by the developer at the end of the main() function.

It is well known that after the main() function exits, the file descriptors that were opened are cleaned up, but similarly the resources that were associated with threads and mutexes are also cleaned up. It is not known which is called first, this cleanup process or the destructor of the static variable.

The phenomenon of threads and mutex crashing when spdlog is used before main() is called on Windows (i.e DLLMain() https://github.com/gabime/spdlog/issues/2304#issuecomment-1065060591 https://github.com/gabime/spdlog/issues/2998#issuecomment-1925305719) shows that it is unsafe.

xmirabel commented 1 month ago

I work on Linux Ubuntu 22.04. Is there also this issue on this operating system?

In my case :

spdlog is not used at all by the main application

tt4g commented 1 month ago

So why not have a function that cleanup library's resources and call it before the library is unloaded by dlclose()?

It is a common design to provide an initialization function and a cleanup function, which are called before and after the library resource is used (e.g., curl_easy_init()() and curl_easy_cleanup()).