...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
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; }
Lastly, you can disable the final log file rotation in every file sink you
register in the logging core. For sinks added programmatically this can be
done by calling enable_final_rotation(false)
on the sink backend. If the sink is created from settings,
you can do this by setting EnableFinalRotation parameter to "false".