Repository navigation
Replacing checked-in OBJ files with /ALTERNATENAME broke linker compatibility #2655
Description
Activity
- addedbugSomething isn't workingSomething isn't workingresolvedSuccessfully resolved without a commitSuccessfully resolved without a commit
on Apr 14, 2022 akoeplinger commented
on May 10, 2022 MemberMore actionsStephan T. Lavavej (@StephanTLavavej) we hit this and tried the
#include <mutex>workaround but it did NOT work.Adding the linker options worked fine though 😄 In our case we used the pragmas like you do here:
Lines 33 to 43 in dd5be88
#if defined(_M_ARM64EC) || defined(_M_HYBRID) // <mutex> uses the forwarder fallbacks for ARM64EC and CHPE. #elif defined(_M_IX86) #pragma comment(linker, "/ALTERNATENAME:__imp____std_init_once_begin_initialize@16=__imp__InitOnceBeginInitialize@16") #pragma comment(linker, "/ALTERNATENAME:__imp____std_init_once_complete@12=__imp__InitOnceComplete@12") #elif defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64) #pragma comment(linker, "/ALTERNATENAME:__imp___std_init_once_begin_initialize=__imp_InitOnceBeginInitialize") #pragma comment(linker, "/ALTERNATENAME:__imp___std_init_once_complete=__imp_InitOnceComplete") #else // ^^^ known architecture / unknown architecture vvv #error Unknown architecture #endif // ^^^ unknown architecture ^^^ Reacted by Stephan T. Lavavejakoeplinger commented
on May 10, 2022 MemberMore actionsah and one difference I just noticed: we're building for x64 but still got the
error LNK2001: unresolved external symbol __imp___std_init_once_begin_initialize, not theLNK2019error codeStephanTLavavej commented
on May 10, 2022 MemberAuthorMore actionsThanks, I've updated the workaround list. I'm not sure what the difference is between the LNK2001 and LNK2019 numbers - thanks again for reporting what you observed.
Reacted by Alexander KöplingerWe have reports of this with our static library C++ built with VS 2019 being used with VS 2022 17.2 per forward compatibility, but none of our samples, regression validations, or tests broke.
Turns out the samples all built utility code that itself used
<future>which in turn pulls in init once. Since the utility code was built with the current toolset, it pulls in__std_init_once_link_alternate_names_and_abortand then the otherwise breaking static C++ library finds it's symbols there without having to use the explicit /linker workaround above.Therefore, another workaround is: "Use more of the C++ features in your code." :)
Reacted by Stephan T. Lavavej- removedresolvedSuccessfully resolved without a commitSuccessfully resolved without a commit
on May 19, 2022 StephanTLavavej commented
on May 19, 2022 MemberAuthorMore actionsWe'll look into ways to fully fix this, as many customers are encountering this break.
- addedfixedSomething works now, yay!Something works now, yay!
on May 24, 2022 StephanTLavavej commented
on May 24, 2022 MemberAuthorMore actionsMerged for VS 2022 17.3 Preview 3. I'll begin the process to port this to 17.2.x (no promises yet).
Whatever the change was... it seems to have found its way into an update for VS2019 as well and my build is b0rked.
1>libprotobufd.lib(any.cc.obj) : error LNK2001: unresolved external symbol __std_init_once_link_alternate_names_and_abort
.... etc.Which seems to be a bit different of an error than initially reported here. What lib am I now missing?
CaseyCarter commented
on Jun 7, 2022 ContributorMore actionsWhatever the change was... it seems to have found its way into an update for VS2019 as well and my build is b0rked.
That doesn't seem to be the case;
findstr std_init_once_link_alternate "c:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\include"finds nothing, indicating the change in question ins't part of VS2019.1>libprotobufd.lib(any.cc.obj) : error LNK2001: unresolved external symbol __std_init_once_link_alternate_names_and_abort
Are you certain you aren't using an older (VS2019) toolset to link to a library built with a newer (VS2022) toolset? That's not a supported configuration; the toolset used to link must be at as new as the newest toolset used to compile any object file/DLL.
You are indeed correct! We are using vcpkg... which apparently by design has been causing us to be linking with vs2022 toolchain artifacts since we installed it since we certainly didn't expect it to select a toolchain other than what msbuild was using.... This change being apparently the first breaking ABI change between vs2019 and vs2022... microsoft/vcpkg#23308. Thanks for the clue/apologies.
For supply chain security, #2381 replaced checked-in OBJ files (generated by an internal tool
aliasobj) with the linker's/ALTERNATENAMEoption (which is strictly more reproducible, although not officially documented).We had never done this before, and although I ensured that the mangled names were identical, I didn't consider all possible scenarios. In certain situations, using a third-party library compiled with an older MSVC toolset, and performing the final link with a newer MSVC toolset, can emit "unresolved external symbol" linker errors that look like:
I apologize for breaking linker compatibility here. Due to the supply chain security impact (and the fact that the
aliasobjtool is still not yet publicly available), we can't undo this change. There are a couple of options to resolve these errors:/ALTERNATENAME:__imp____std_init_once_begin_initialize@16=__imp__InitOnceBeginInitialize@16/ALTERNATENAME:__imp____std_init_once_complete@12=__imp__InitOnceComplete@12/ALTERNATENAME:__imp___std_init_once_begin_initialize=__imp_InitOnceBeginInitialize/ALTERNATENAME:__imp___std_init_once_complete=__imp_InitOnceCompleteI've filed this issue so that the error messages are searchable. I can also answer further questions if you've encountered these errors (I may not see GitHub notifications, so you may need to get my attention in the STL's Discord server.)
Also tracked by DevCom-1684365 / internal VSO-1495049 / AB#1495049 .