Added a workaround for MSVC linker eliminating path globals cleanup.

MSVC and possibly some other compilers that don't support __attribute__((used))
may remove the global p_init_path_globals pointer in a special data section
because it is not referenced anywhere. Add a dummy global object that
references the pointer in its constructor as a workaround.

Fixes https://github.com/boostorg/filesystem/issues/217.
This commit is contained in:
Andrey Semashev
2021-11-22 15:45:00 +03:00
parent 7de22d2dc1
commit fa53749ac7
2 changed files with 19 additions and 0 deletions

View File

@@ -52,6 +52,7 @@
<li>On Windows, <code>remove</code> now supports deleting read-only files. The operation will attempt to reset the read-only attribute prior to removal. Note that this introduces a possibility of the read-only attribute being left unset, if the operation fails and the original value of the attribute fails to be restored. This also affects <code>remove_all</code>. (<a href="https://github.com/boostorg/filesystem/issues/216">#216</a>)</li>
<li><code>remove_all</code> now returns <code>static_cast&lt; uintmax_t &gt;(-1)</code> in case of error, similar to C++17 std::filesystem.</li>
<li>Fixed a linking error about unresolved references to Boost.ContainerHash functions when user's code includes <code>boost/filesystem/path.hpp</code> but not <code>boost/container_hash/hash.hpp</code> and the compiler is set to preserve unused inline functions. (<a href="https://github.com/boostorg/filesystem/issues/215">#215</a>)</li>
<li>Added a workaround for MSVC and compatible compilers eliminating path globals cleanup in release builds. This could lead to a memory leak if Boost.Filesystem shared library was repeatedly loaded and unloaded in the process. (<a href="https://github.com/boostorg/filesystem/issues/217">#217</a>)</li>
</ul>
<h2>1.77.0</h2>

View File

@@ -1539,6 +1539,7 @@ BOOST_FILESYSTEM_INIT_FUNC init_path_globals()
#endif
#if !defined(BOOST_FILESYSTEM_ATTRIBUTE_RETAIN)
#define BOOST_FILESYSTEM_NO_ATTRIBUTE_RETAIN
#define BOOST_FILESYSTEM_ATTRIBUTE_RETAIN
#endif
@@ -1563,6 +1564,23 @@ extern const init_func_ptr_t p_init_path_globals = &init_path_globals;
#endif // _MSC_VER >= 1400
#if defined(BOOST_FILESYSTEM_NO_ATTRIBUTE_RETAIN)
//! Makes sure the global initializer pointers are referenced and not removed by linker
struct globals_retainer
{
const init_func_ptr_t* const m_p_init_path_globals;
globals_retainer() : m_p_init_path_globals(&p_init_path_globals) {}
};
BOOST_ATTRIBUTE_UNUSED
static const globals_retainer g_globals_retainer
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
{};
#else // !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
= globals_retainer();
#endif // !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
#endif // defined(BOOST_FILESYSTEM_NO_ATTRIBUTE_RETAIN)
#else // defined(_MSC_VER)
struct path_locale_deleter