Opened 5 years ago
Closed 5 years ago
#13077 closed Bugs (fixed)
Linking to static 64bit libboost_thread fails DLL initialization
| Reported by: | Owned by: | viboes | |
|---|---|---|---|
| Milestone: | Boost 1.65.0 | Component: | thread |
| Version: | Boost 1.63.0 | Severity: | Showstopper |
| Keywords: | Cc: |
Description
If DLL links to static boost thread library the dll can not initialize and any exe that uses the DLL fails with error code (0xc0000142) 'DLL Initialization Failed'.
I've attached an minimal example project to demonstrate the problem. The package includes static boost libraries that were built with steps given below.
This example produces a thedll.dll that links libboost_thread (does not use any headers) and then theexe.exe that links to thedll.dll. theexe.exe fails to start with attached error prompt.
Root cause of the fail is beyond me, but I traced debugger to dll_dllmain.cpp on line 57. Here _initterm_e returns non-zero value and thedll.dll init fails. This happens only if libboost_thread is linked to the dll.
Environment:
- Visual Studio 15 2017 Community Edition
- 64 bit builds.
- CMake generator 'Visual Studio 15 2017 Win64'.
Boost build steps: (Called from VS environment cmd shell. Tools -> Visual Studio Command Prompt)
- C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat amd64
- bootstrap.bat
- bjam -j4 architecture=x86 address-model=64 link=static stage
- bjam --prefix=C:\opt\boost architecture=x86 address-model=64 link=static install
Change History (5)
comment:1 by , 5 years ago
comment:2 by , 5 years ago
Traced the error to a call to PVAPI on_tls_prepare(). This function gets called by _initterm_e that expects it to return 0 on success.
However in boost PVAPI is defined as void return type. I think this test is wrong for _MSC_VER 1910 in tss_pe.cpp.
#if (_MSC_VER < 1300) || (_MSC_VER > 1900) // 1300 == VC++ 7.0, 1900 == VC++ 14.0
typedef void (__cdecl *_PVFV)();
#define INIRETSUCCESS
#define PVAPI void __cdecl
#else
typedef int (__cdecl *_PVFV)();
#define INIRETSUCCESS 0
#define PVAPI int __cdecl
#endif
The runtime initializer function is supposed to return an int
/C/Program Files (x86) $ find . -name "*.h" -print0|xargs -0 grep _PIFV | grep typedef find: ‘./Google/CrashReports’: Permission denied ./Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.10.25017/crt/src/vcruntime/internal_shared.h: typedef int (__cdecl* _PIFV)(void); ./Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.10.25017/crt/src/vcruntime/minternal.h: typedef int (__clrcall* _PIFVM)(void); ./Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.10.25017/crt/src/vcruntime/vcruntime_internal.h:typedef int (__cdecl* _PIFV)(void); ./Microsoft Visual Studio/Shared/14.0/VC/crt/src/vcruntime/internal_shared.h: typedef int (__cdecl* _PIFV)(void); ./Microsoft Visual Studio/Shared/14.0/VC/crt/src/vcruntime/minternal.h: typedef int (__clrcall* _PIFVM)(void); ./Microsoft Visual Studio/Shared/14.0/VC/crt/src/vcruntime/vcruntime_internal.h:typedef int (__cdecl* _PIFV)(void); ./Windows Kits/10/Include/10.0.10240.0/ucrt/corecrt_startup.h:typedef int (__cdecl* _PIFV)(void); ./Windows Kits/10/Include/10.0.15063.0/ucrt/corecrt_startup.h:typedef int (__cdecl* _PIFV)(void);
comment:3 by , 5 years ago
This problem has been fixed in commit: https://github.com/boostorg/thread/commit/676521808d2fea63afcf295d8edb6f55df90f97a
comment:4 by , 5 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:5 by , 5 years ago
| Milestone: | To Be Determined → Boost 1.65.0 |
|---|---|
| Resolution: | → fixed |
| Status: | assigned → closed |

Maximum attachment size was mere few hundred kb's so I'm linking stuff here. Also I can't use proper urls as Trac will reject my comment as spam.. sigh.
project
Some debug screencaptures