Building gRPC, abseil-cpp, protobuf, etc. with static c-runtime with Visual Studio 2022 (/MT)

88 views
Skip to first unread message

Scott Mendel

unread,
Jul 10, 2025, 12:31:53 PM7/10/25
to grpc.io
Is there complete documentation to build gRPC v1.68.2 and its dependencies with /MT somewhere?  

I am building a java profiler that is trying to use gRPC. The profiler is dynamically loaded at runtime into a java process, but I do not have control over which version of VC runtime that process is using (linked with.) Microsoft recently introduced a breaking change in Visual Studio 17.10 with std::mutex, see https://developercommunity.visualstudio.com/t/Access-violation-with-std::mutex::lock-a/10664660 

I am getting crashes in gRPC with mtx_do_lock(); see the stack trace below. The only solution to the problem is to statically link VC runtime into my profiler (/MT instead of /MD) I have tried to use "-DgRPC_MSVC_STATIC_RUNTIME=ON" and "-Dprotobuf_MSVC_STATIC_RUNTIME=ON" to build gRPC v1.68.2, but the build fails linking mismatched binaries.  I have found bits and pieces (and failed attempts) with a web search. There is some suggestion that I need to use vcpkg.exe, but I was unable to configure it properly. There are just too many .vcxproj files to edit them manually.

I have already confirmed using the newest version of VC-runtime resolves the issue. And yes, I do understand the size increase of my profiler binary. Finally, I have discovered that JVMs are shipping with vcruntime140.dll and ucrtbase.dll in the JVM's "bin" directory which in the search path before the "\Windows\system32" directory even if I have the latest VC runtime installed (VC runtime 2015-2022 rollup) see https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170

msvcp140.dll!mtx_do_lock(_Mtx_internal_imp_t * mtx, const xtime * target) Line 103  C++
absl::lts_20240722::time_internal::cctz::time_zone::Impl::LoadTimeZone(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class absl::lts_20240722::time_internal::cctz::time_zone *)  C++
absl::lts_20240722::time_internal::cctz::local_time_zone(void)  C++
absl::lts_20240722::FormatTime(class absl::lts_20240722::Time)  C++
upb::Arena::~Arena(void)  C++
absl::lts_20240722::container_internal::raw_hash_set<struct absl::lts_20240722::container_internal::FlatHashMapPolicy<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class grpc_core::TraceFlag *>,struct absl::lts_20240722::container_internal::StringHash,struct absl::lts_20240722::container_internal::StringEq,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class grpc_core::TraceFlag *> > >::transfer_slot_fn(void *,void *,void *)  C++
absl::lts_20240722::status_internal::StatusRep::ForEachPayload(class absl::lts_20240722::FunctionRef<void >)  C++
grpc_core::StatusToString(class absl::lts_20240722::Status const &)  C++
grpc_error_get_status(class absl::lts_20240722::Status,class grpc_core::Timestamp,enum grpc_status_code *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,enum grpc_http2_error_code *,char const * *)  C++
grpc_core::FilterStackCall::SetFinalStatus(class absl::lts_20240722::Status)  C++
grpc_core::FilterStackCall::RecvTrailingFilter(struct grpc_metadata_batch *,class absl::lts_20240722::Status)  C++
grpc_core::FilterStackCall::BatchControl::ReceivingTrailingMetadataReady(class absl::lts_20240722::Status)  C++
grpc_core::ChannelStackBuilderImpl::Build(void)  C++
grpc_core::ExecCtx::Flush(void)  C++
grpc_core::Call::Run(void)  C++
grpc_event_engine::experimental::WindowsEventEngine::TimerClosure::Run(void)  C++
grpc_event_engine::experimental::WorkStealingThreadPool::ThreadState::Step(void)  C++
grpc_event_engine::experimental::WorkStealingThreadPool::ThreadState::ThreadBody(void)  C++
std::allocator<class std::weak_ptr<class grpc_event_engine::experimental::Forkable> >::deallocate(class std::weak_ptr<class grpc_event_engine::experimental::Forkable> * const,unsigned __int64)  C++
grpc_core::Thread::Signal(unsigned __int64,int)  C++
kernel32.dll!BaseThreadInitThunk ()  Unknown
ntdll.dll!RtlUserThreadStart ()  Unknown
Reply all
Reply to author
Forward
0 new messages