MSVC constexpr Constructor with a non-constexpr Global Generates Dynamic Initializers (e.g. LazyInstance) |
|||||||||||
Issue descriptionDCHECK right at Chrome startup. 2:038> kn30 # ChildEBP RetAddr 00 007bdb18 6722e551 base!`anonymous namespace'::InvalidParameter+0x3 [e:\src\base\win\process_startup_helper.cc @ 21] 01 007bdb48 0e9854d7 ucrtbased!_invalid_parameter+0xa1 [minkernel\crts\ucrt\src\appcrt\misc\invalid_parameter.cpp @ 108] 02 007bdb68 0e987478 ipc!std::vector<std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> > > >,std::allocator<std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> > > > > >::operator[]+0x47 [e:\src\third_party\depot_tools\win_toolchain\vs_files\1180cb75833ea365097e279efb2d5d7a42dee4b0\vc\tools\msvc\14.11.25503\include\vector @ 1796] 03 007bdb78 0e986ca3 ipc!std::_Hash<std::_Umap_traits<unsigned int,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *),std::_Uhash_compare<unsigned int,base_hash::hash<unsigned int>,std::equal_to<unsigned int> >,std::allocator<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> >,0> >::_Vec_lo+0x18 [e:\src\third_party\depot_tools\win_toolchain\vs_files\1180cb75833ea365097e279efb2d5d7a42dee4b0\vc\tools\msvc\14.11.25503\include\xhash @ 822] 04 007bdb88 0e98770f ipc!std::_Hash<std::_Umap_traits<unsigned int,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *),std::_Uhash_compare<unsigned int,base_hash::hash<unsigned int>,std::equal_to<unsigned int> >,std::allocator<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> >,0> >::_Begin+0x13 [e:\src\third_party\depot_tools\win_toolchain\vs_files\1180cb75833ea365097e279efb2d5d7a42dee4b0\vc\tools\msvc\14.11.25503\include\xhash @ 841] 05 007bdbd0 0e987647 ipc!std::_Hash<std::_Umap_traits<unsigned int,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *),std::_Uhash_compare<unsigned int,base_hash::hash<unsigned int>,std::equal_to<unsigned int> >,std::allocator<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> >,0> >::lower_bound+0x2f [e:\src\third_party\depot_tools\win_toolchain\vs_files\1180cb75833ea365097e279efb2d5d7a42dee4b0\vc\tools\msvc\14.11.25503\include\xhash @ 647] 06 007bdbe4 0e985f81 ipc!std::_Hash<std::_Umap_traits<unsigned int,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *),std::_Uhash_compare<unsigned int,base_hash::hash<unsigned int>,std::equal_to<unsigned int> >,std::allocator<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> >,0> >::find+0x17 [e:\src\third_party\depot_tools\win_toolchain\vs_files\1180cb75833ea365097e279efb2d5d7a42dee4b0\vc\tools\msvc\14.11.25503\include\xhash @ 630] 07 007bdc30 0e9b0e23 ipc!IPC::Logging::GetMessageText+0x31 [e:\src\ipc\ipc_logging.cc @ 178] 08 007bdd98 2420af27 ipc!IPC::SyncChannel::Send+0x43 [e:\src\ipc\ipc_sync_channel.cc @ 606] 09 007bddac 2420ae90 gpu_ipc_service!gpu::SyncChannelFilteredSender::Send+0x27 [e:\src\gpu\ipc\service\gpu_channel.cc @ 332] 0a 007bdf34 241fd527 gpu_ipc_service!gpu::GpuChannel::Send+0x1a0 [e:\src\gpu\ipc\service\gpu_channel.cc @ 425] 0b 007be2d4 24208f88 gpu_ipc_service!IPC::MessageT<GpuChannelMsg_CreateCommandBuffer_Meta,std::tuple<GPUCreateCommandBufferConfig,int,base::SharedMemoryHandle>,std::tuple<enum gpu::ContextResult,gpu::Capabilities> >::Dispatch<gpu::GpuChannel,gpu::GpuChannel,void,void (__thiscall gpu::GpuChannel::*)(GPUCreateCommandBufferConfig const &,int,base::SharedMemoryHandle,enum gpu::ContextResult *,gpu::Capabilities *)>+0x277 [e:\src\ipc\ipc_message_templates.h @ 208] 0c 007be318 242084fe gpu_ipc_service!gpu::GpuChannel::OnControlMessageReceived+0x68 [e:\src\gpu\ipc\service\gpu_channel.cc @ 481] 0d 007be334 242085d3 gpu_ipc_service!gpu::GpuChannel::HandleMessageHelper+0x2e [e:\src\gpu\ipc\service\gpu_channel.cc @ 521] 0e 007be344 241fdb60 gpu_ipc_service!gpu::GpuChannel::HandleOutOfOrderMessage+0x13 [e:\src\gpu\ipc\service\gpu_channel.cc @ 539] 0f 007be350 241fe026 gpu_ipc_service!base::internal::FunctorTraits<void (__thiscall gpu::GpuChannel::*)(IPC::Message const &),void>::Invoke<base::WeakPtr<gpu::GpuChannel> const &,IPC::Message const &>+0x20 [e:\src\base\bind_internal.h @ 212] 10 007be368 241fe1c3 gpu_ipc_service!base::internal::InvokeHelper<1,void>::MakeItSo<void (__thiscall gpu::GpuChannel::*const &)(IPC::Message const &),base::WeakPtr<gpu::GpuChannel> const &,IPC::Message const &>+0x46 [e:\src\base\bind_internal.h @ 314] 11 007be37c 2420abf4 gpu_ipc_service!base::internal::Invoker<base::internal::BindState<void (__thiscall gpu::GpuChannel::*)(IPC::Message const &),base::WeakPtr<gpu::GpuChannel>,IPC::Message>,void __cdecl(void)>::RunImpl<void (__thiscall gpu::GpuChannel::*const &)(IPC::Message const &),std::tuple<base::WeakPtr<gpu::GpuChannel>,IPC::Message> const &,0,1>+0x53 [e:\src\base\bind_internal.h @ 368] 12 007be398 10050475 gpu_ipc_service!base::internal::Invoker<base::internal::BindState<void (__thiscall gpu::GpuChannel::*)(IPC::Message const &),base::WeakPtr<gpu::GpuChannel>,IPC::Message>,void __cdecl(void)>::Run+0x24 [e:\src\base\bind_internal.h @ 350] 13 007be3b0 100a6683 base!base::OnceCallback<void __cdecl(void)>::Run+0x35 [e:\src\base\callback.h @ 65] 14 007be48c 10122e98 base!base::debug::TaskAnnotator::RunTask+0x1e3 [e:\src\base\debug\task_annotator.cc @ 56] 15 007be558 1012cbb0 base!base::internal::IncomingTaskQueue::RunTask+0x88 [e:\src\base\message_loop\incoming_task_queue.cc @ 125] 16 007be6a8 1012acb8 base!base::MessageLoop::RunTask+0x200 [e:\src\base\message_loop\message_loop.cc @ 400] 17 007be6c4 1012b303 base!base::MessageLoop::DeferOrRunPendingTask+0x28 [e:\src\base\message_loop\message_loop.cc @ 414] 18 007be778 10130258 base!base::MessageLoop::DoWork+0x163 [e:\src\base\message_loop\message_loop.cc @ 455] 19 007be794 1012c88a base!base::MessagePumpDefault::Run+0x28 [e:\src\base\message_loop\message_pump_default.cc @ 37] 1a 007be928 101df5f4 base!base::MessageLoop::Run+0x17a [e:\src\base\message_loop\message_loop.cc @ 352] 1b 007beb64 109f4608 base!base::RunLoop::Run+0x164 [e:\src\base\run_loop.cc @ 136] 1c 007beeb0 13dc4417 content!content::GpuMain+0x6e8 [e:\src\content\gpu\gpu_main.cc @ 345] 1d 007bef7c 13dc42fc content!content::RunNamedProcessTypeMain+0x87 [e:\src\content\app\content_main_runner.cc @ 423] 1e 007bf148 13dbff84 content!content::ContentMainRunnerImpl::Run+0x18c [e:\src\content\app\content_main_runner.cc @ 713] 1f 007bf158 215cf690 content!content::ContentServiceManagerMainDelegate::RunEmbedderProcess+0x24 [e:\src\content\app\content_service_manager_main_delegate.cc @ 52] 20 007bf388 13dc1cc9 embedder!service_manager::Main+0x330 [e:\src\services\service_manager\embedder\main.cc @ 456] 21 007bf3c0 06236d95 content!content::ContentMain+0x29 [e:\src\content\app\content_main.cc @ 19] 22 007bf434 00436c04 chrome!ChromeMain+0x115 [e:\src\chrome\app\chrome_main.cc @ 144] 23 007bf510 00432617 chrome_exe!MainDllLoader::Launch+0x344 [e:\src\chrome\app\main_dll_loader_win.cc @ 199] 24 007bf7e0 00505b9e chrome_exe!wWinMain+0x2d7 [e:\src\chrome\app\chrome_exe_main_win.cc @ 230] 25 007bf7f8 00505a10 chrome_exe!invoke_main+0x1e [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 123] 26 007bf850 005058ad chrome_exe!__scrt_common_main_seh+0x150 [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 283] 27 007bf858 00505c18 chrome_exe!__scrt_common_main+0xd [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 326] 28 007bf860 762962c4 chrome_exe!wWinMainCRTStartup+0x8 [f:\dd\vctools\crt\vcstartup\src\startup\exe_wwinmain.cpp @ 17] 29 007bf874 77710f79 KERNEL32!BaseThreadInitThunk+0x24 2a 007bf8bc 77710f44 ntdll!__RtlUserThreadStart+0x2f 2b 007bf8cc 00000000 ntdll!_RtlUserThreadStart+0x1b
,
Jan 31 2018
,
Jan 31 2018
,
Jan 31 2018
The log_function_map is very sad
3:043> x ipc!IPC::Logging::log_function_map_
0ed812c8 ipc!IPC::Logging::log_function_map_ = 0x15b8f384 { size=0x0 }
3:043> dps 0x15b8f384 l10
15b8f384 00000000
15b8f388 00000000
15b8f38c 00000000
15b8f390 00000000
15b8f394 00000000
15b8f398 00000000
15b8f39c 00000000
15b8f3a0 00000000
15b8f3a4 00000000
15b8f3a8 00000000
15b8f3ac 00000000
15b8f3b0 00000000
15b8f3b4 00000000
15b8f3b8 00000000
15b8f3bc 00000000
15b8f3c0 00000000
,
Jan 31 2018
Initializers are running more than once for LazyInstance? Before: ipc!IPC::Logging::set_log_function_map+0x3: 0dc06813 8b4508 mov eax,dword ptr [ebp+8] ss:002b:007beda4=15b8f384 4:047> dt functions Local var @ 0x7beda4 Type std::unordered_map<unsigned int,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *),base_hash::hash<unsigned int>,std::equal_to<unsigned int>,std::allocator<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> > >* 0x15b8f384 +0x000 _Traitsobj : std::_Umap_traits<unsigned int,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *),std::_Uhash_compare<unsigned int,base_hash::hash<unsigned int>,std::equal_to<unsigned int> >,std::allocator<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> >,0> +0x004 _List : std::list<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)>,std::allocator<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> > > +0x010 _Vec : std::vector<std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> > > >,std::allocator<std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> > > > > > +0x020 _Mask : 7 +0x024 _Maxidx : 8 4:047> dps 0x15b8f384 l10 15b8f384 3f800000 15b8f388 01156a60 15b8f38c 0115eb60 15b8f390 00000000 15b8f394 011564b0 15b8f398 011575d8 15b8f39c 01157618 15b8f3a0 01157618 15b8f3a4 00000007 15b8f3a8 00000008 15b8f3ac 00000000 15b8f3b0 00000000 15b8f3b4 00000000 15b8f3b8 00000000 15b8f3bc 00000000 15b8f3c0 00000000 Later on 4:047> kn20 # ChildEBP RetAddr 00 007bedbc 109cb6ef content!base::LazyInstance<std::unordered_map<unsigned int,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *),base_hash::hash<unsigned int>,std::equal_to<unsigned int>,std::allocator<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> > >,base::internal::LeakyLazyInstanceTraits<std::unordered_map<unsigned int,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *),base_hash::hash<unsigned int>,std::equal_to<unsigned int>,std::allocator<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> > > > >::LazyInstance<std::unordered_map<unsigned int,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *),base_hash::hash<unsigned int>,std::equal_to<unsigned int>,std::allocator<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *)> > >,base::internal::LeakyLazyInstanceTraits<std::unordered_map<unsigned int,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::allocator<char> > *,IPC::Message const *,std::basic_string<char,std::char_traits<char>,std::allocator<char> > *),base_hash::hash<unsigned int>,std::equal_to<unsigned int>,std::allocator<std::pair<unsigned int const ,void (__cdecl*)(std::basic_string<char,std::char_traits<char>,std::+0x1a [e:\src\base\lazy_instance.h @ 205] 01 007bedc8 67235629 content!content::`anonymous namespace'::`dynamic initializer for 'g_log_function_mapping''+0xf [e:\src\content\common\content_ipc_logging.cc @ 25] 02 007beddc 147ef947 ucrtbased!_initterm+0x49 [minkernel\crts\ucrt\src\appcrt\startup\initterm.cpp @ 22] 03 007bee20 147ef809 content!dllmain_crt_process_attach+0xc7 [f:\dd\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp @ 63] 04 007bee38 147efbe3 content!dllmain_crt_dispatch+0x29 [f:\dd\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp @ 137] 05 007bee7c 147efdcf content!dllmain_dispatch+0x93 [f:\dd\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp @ 194] 06 007bee90 7771e52e content!_DllMainCRTStartup+0x1f [f:\dd\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp @ 252] 07 007beeb0 776f0df6 ntdll!LdrxCallInitRoutine+0x16 08 007bef00 776dab2c ntdll!LdrpCallInitRoutine+0x43 09 007bef80 776da9cb ntdll!LdrpInitializeNode+0x10e 0a 007befa4 776da9e2 ntdll!LdrpInitializeGraphRecurse+0x5d 0b 007befcc 776e0f66 ntdll!LdrpInitializeGraphRecurse+0x74 0c 007befe8 776f024b ntdll!LdrpPrepareModuleForExecution+0x8f 0d 007bf030 776ecd44 ntdll!LdrpLoadDllInternal+0x124 0e 007bf17c 776da67f ntdll!LdrpLoadDll+0x93 0f 007bf200 758b9698 ntdll!LdrLoadDll+0x7f 10 007bf240 00437063 KERNELBASE!LoadLibraryExW+0x138 11 007bf274 00436e6b chrome_exe!`anonymous namespace'::LoadModuleWithDirectory+0x63 [e:\src\chrome\app\main_dll_loader_win.cc @ 62] 12 007bf4d4 00436b84 chrome_exe!MainDllLoader::Load+0x13b [e:\src\chrome\app\main_dll_loader_win.cc @ 132] 13 007bf5a4 00432617 chrome_exe!MainDllLoader::Launch+0x2c4 [e:\src\chrome\app\main_dll_loader_win.cc @ 192] 14 007bf874 00505b9e chrome_exe!wWinMain+0x2d7 [e:\src\chrome\app\chrome_exe_main_win.cc @ 230] 15 007bf88c 00505a10 chrome_exe!invoke_main+0x1e [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 123] 16 007bf8e4 005058ad chrome_exe!__scrt_common_main_seh+0x150 [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 283] 17 007bf8ec 00505c18 chrome_exe!__scrt_common_main+0xd [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl @ 326] 18 007bf8f4 762962c4 chrome_exe!wWinMainCRTStartup+0x8 [f:\dd\vctools\crt\vcstartup\src\startup\exe_wwinmain.cpp @ 17] 19 007bf908 77710f79 KERNEL32!BaseThreadInitThunk+0x24 1a 007bf950 77710f44 ntdll!__RtlUserThreadStart+0x2f 1b 007bf960 00000000 ntdll!_RtlUserThreadStart+0x1b 4:047> dps 0x15b8f384 l10 15b8f384 00000000 15b8f388 01156a60 15b8f38c 0115eb60 15b8f390 0000042f 15b8f394 011564b0 15b8f398 0117dc40 15b8f39c 01181c40 15b8f3a0 01181c40 15b8f3a4 000007ff 15b8f3a8 00000800 15b8f3ac 00000000 15b8f3b0 00000000 15b8f3b4 00000000 15b8f3b8 00000000 15b8f3bc 00000000 15b8f3c0 00000000
,
Jan 31 2018
Hmmm? I don't see how these stacks are related? The second one initializes g_log_function_mapping, the first one doesn't seem to?
,
Jan 31 2018
The second one is a dynamic initializer for LazyInstance which blows away the initialized g_log_function_mapping. For some reason, this is getting generated and this is causing the problem.
,
Jan 31 2018
It appears making LazyInstance constexpr somehow introduced some dynamic initializers. Reverting this change (and the changes on top of it in LazyInstance) fixes the break: commit ddb183db518bcfdd867b2188c30781fd8d375a06 Author: Gabriel Charette <gab@chromium.org> Date: Fri Jan 19 10:19:52 2018 +0000 Make LazyInstance's constructor constexpr. This allows hiding the buffer into private state, this will allow adding more POD members as a follow-up. Believe it or not, there was a user of this private state up until very recently..! https://chromium-review.googlesource.com/c/chromium/src/+/850294 This also allows removing the need for the LAZY_INSTANCE_INITIALIZER construction hack (will follow-up with a mass removal CL). -Wglobal-constructors (https://chromium-review.googlesource.com/c/chromium/src/+/866738) in //base guarantees that this doesn't result in global constructors. Bug: 797129 Change-Id: Id891d051180b18155f0e23c0ec55cb0f4d3018ac Reviewed-on: https://chromium-review.googlesource.com/861426 Commit-Queue: Gabriel Charette <gab@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Cr-Commit-Position: refs/heads/master@{#530469} base/lazy_instance.h | 54 +++++++++++++++++++++++------------------- base/lazy_instance_unittest.cc | 14 +++++++++++ 2 files changed, 43 insertions(+), 25 deletions(-)
,
Jan 31 2018
A simple instance simulating LazyInstance shows that MSVC generates a dynamic initializer for g_foo in the following snippet:
class Foo {
public:
constexpr Foo(int i) {}
int val() { return val_; }
private:
int val_ = 0;
};
Foo g_foo = {0};
,
Feb 1 2018
And example stack: 0:000> kn # ChildEBP RetAddr 00 004ffd44 00cdd2ca Sandbox!Foo::Foo 01 004ffe1c 00d25fb9 Sandbox!`dynamic initializer for 'g_foo''+0x2a 02 004ffe30 00ce024e Sandbox!_initterm+0x49 03 004ffe90 00ce017d Sandbox!__scrt_common_main_seh+0xbe 04 004ffe98 00ce04e8 Sandbox!__scrt_common_main+0xd 05 004ffea0 769862c4 Sandbox!mainCRTStartup+0x8 06 004ffeb4 77010f79 KERNEL32!BaseThreadInitThunk+0x24 07 004ffefc 77010f44 ntdll!__RtlUserThreadStart+0x2f 08 004fff0c 00000000 ntdll!_RtlUserThreadStart+0x1b
,
Feb 1 2018
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/6c58b870ad54c73c124b20a1bdb7f4eb727403f8 commit 6c58b870ad54c73c124b20a1bdb7f4eb727403f8 Author: Robert Liao <robliao@chromium.org> Date: Thu Feb 01 04:47:01 2018 Revert "Make LazyInstance's constructor constexpr." This reverts commit ddb183db518bcfdd867b2188c30781fd8d375a06. Reason for revert: MSVC generates dynamic initializers for constexpr constructors with non-constexpr variables. It's not clear if the C++ spec allows for this. Original change's description: > Make LazyInstance's constructor constexpr. > > This allows hiding the buffer into private state, this will allow adding more POD > members as a follow-up. > Believe it or not, there was a user of this private state up until very recently..! > https://chromium-review.googlesource.com/c/chromium/src/+/850294 > > This also allows removing the need for the LAZY_INSTANCE_INITIALIZER > construction hack (will follow-up with a mass removal CL). > > -Wglobal-constructors (https://chromium-review.googlesource.com/c/chromium/src/+/866738) > in //base guarantees that this doesn't result in global constructors. > > Bug: 797129 > Change-Id: Id891d051180b18155f0e23c0ec55cb0f4d3018ac > Reviewed-on: https://chromium-review.googlesource.com/861426 > Commit-Queue: Gabriel Charette <gab@chromium.org> > Reviewed-by: Daniel Cheng <dcheng@chromium.org> > Cr-Commit-Position: refs/heads/master@{#530469} TBR=dcheng@chromium.org,gab@chromium.org,fdoray@chromium.org # Not skipping CQ checks because original CL landed > 1 day ago. Bug: 797129 , 807491 Change-Id: I3bac97268584295fdd39563428c7f7dbe9ae8560 Reviewed-on: https://chromium-review.googlesource.com/896603 Reviewed-by: Robert Liao <robliao@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Commit-Queue: Robert Liao <robliao@chromium.org> Cr-Commit-Position: refs/heads/master@{#533564} [modify] https://crrev.com/6c58b870ad54c73c124b20a1bdb7f4eb727403f8/base/lazy_instance.h [modify] https://crrev.com/6c58b870ad54c73c124b20a1bdb7f4eb727403f8/base/lazy_instance_unittest.cc
,
Feb 1 2018
,
Feb 1 2018
,
Feb 1 2018
Cc'ing brucedawson@ for C++ implementation trivia.
,
Feb 1 2018
I am sure that the C++ spec allows this. If the argument to the Foo constructor was a non-constant then the compiler would be *required* to create a dynamic initializer.
I have seen instances of this happening with MSVC before so I am not surprised. This behavior is not efficient, and probably worth filing a bug on (if we were going to continue using VC++) but it would be a performance bug, not a correctness bug.
However, I could only repro this behavior with the sample code above in non-optimized builds. With an optimized compilation the object appeared to be statically initialized:
cl /O2 /Zi /c main.cpp & link /DEBUG main.obj
// main.cpp
class Foo {
public:
constexpr Foo(int i) {}
int val() { return val_; }
//private:
int val_ = 0;
};
Foo g_foo = {0};
int main(int argc, char* argv[]) {
return g_foo.val_;
}
,
Feb 1 2018
Given that the standard doesn't provide a guarantee around this, it's not entirely surprising. While I'm glad we experimented with this, it makes me reluctant to proceed further along this route without getting stronger guarantees from the standard. My other concern is that we'll still be emitting destructors for these global objects even if compilers get better about constexpr: even if not run, there is a binary size cost to doing that. Maybe a constexpr dtor...?
,
Feb 1 2018
> However, I could only repro this behavior with the sample code above in non-optimized builds. With an optimized compilation the object appeared to be statically initialized: I should have mentioned that this was for a debug build. This is why we don't really see an issue on the bots as they run with Release + DCHECK_IS_ON IIRC.
,
Feb 1 2018
The contract for unoptimized builds is, roughly speaking, do everything possible at run-time to allow stepping through it. So, generating a constructor for the debug-build case is, IMHO, WAI.
,
Feb 1 2018
That suggests interesting debuggability issues on clang with respect to constexpr constructors. At the same time, there are strict limits on what can be placed in a constexpr constructors, so it's debatable how useful it is to allow debug stepping. When I ran with '-g' in clang, the constructor disappeared as a symbol (at least lldb couldn't find it).
,
Feb 7 2018
,
Feb 12 2018
|
|||||||||||
►
Sign in to add a comment |
|||||||||||
Comment 1 by robliao@chromium.org
, Jan 31 20182:038> .frame 07 007bdc30 0e9b0e23 ipc!IPC::Logging::GetMessageText+0x31 2:038> dv type = 0xfffffff0 name = 0x007bdd78 "" message = 0x00b72758 {size = 0x410} params = 0x00000000 it = {...}