There are known problems with Boost.Filesystem (for example, #8642 and #9219), which affect Boost.Log file sink backends. When the file sink is destroyed, it attempts to perform a final log file rotation, which involves Boost.Filesystem for moving files. This typically happens when Boost.Log core is deinitialized, at the global deinitialization stage, after leaving main()
. The crux of the problem is that Boost.Filesystem uses a global locale object internally to perform character code conversion for path
s, and this locale may get destroyed before Boost.Log is deinitialized, which results in a crash.
There is no way for Boost.Log to influence the order of global deinitialization, but the problem can be worked around on the user's side. One solution is to make sure the locale is initialized before Boost.Log. This can be achieved by calling boost::filesystem::path::codecvt()
or boost::filesystem::path::imbue()
early during the application startup, before performing any calls to Boost.Log. For example:
int main(int argc, char* argv[]) { boost::filesystem::path::imbue(std::locale("C")); initialize_log(); // ... }
Note that in this case you can't use Boost.Log in global constructors or you have to make sure that boost::filesystem::path::imbue()
is still called first.
Another solution is to remove and destroy file sinks from the logging core before returning from main()
. This way file rotation will happen before leaving main()
, while the locale is still valid. The file sinks can be removed either individually or as a part of the remove_all_sinks()
call:
int main(int argc, char* argv[]) { // ... logging::core::get()->remove_all_sinks(); return 0; }