grpc: absl: Potential Mutex deadlock - when using signal handler
What version of gRPC and what language are you using?
1.33.2 / C++
What operating system (Linux, Windows,…) and version?
Ubuntu 18.04
What runtime / compiler are you using (e.g. python version or version of gcc)
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
What did you do?
Tried to implement shutdown of a grpc::Server with a signal handler when pressing ctrl+c (SIGINT). See repro case below.
#include <csignal>
static std::unique_ptr<grpc::Server> _server;
void shutdown(int)
{
_server->Shutdown();
}
int main()
{
signal(SIGINT, &shutdown);
grpc::ServerBuilder builder;
builder.AddListeningPort("127.0.0.1:5001", grpc::InsecureServerCredentials());
testing::EchoTestService::Service service;
builder.RegisterService(&service);
_server = builder.BuildAndStart();
_server->Wait();
return 0;
}
What did you expect to see?
Normal shutdown and exit.
What did you see instead?
When built with dbg
^C[mutex.cc : 1356] RAW: Potential Mutex deadlock:
@ 0x55fa744bdc5a absl::lts_2020_02_25::DebugOnlyDeadlockCheck()
@ 0x55fa744bdf30 absl::lts_2020_02_25::Mutex::Lock()
@ 0x55fa744a5dc2 gpr_mu_lock
@ 0x55fa742f677e grpc::CoreCodegen::gpr_mu_lock()
@ 0x55fa74124077 grpc::internal::MutexLock::MutexLock()
@ 0x55fa742da51b grpc::Server::ShutdownInternal()
@ 0x55fa741216d2 grpc::ServerInterface::Shutdown()
@ 0x55fa7412140f shutdown()
@ 0x7f15c2bb3f20
@ 0x55fa744c435b absl::lts_2020_02_25::synchronization_internal::Waiter::Wait()
@ 0x55fa744c4097 AbslInternalPerThreadSemWait
@ 0x55fa744c2a92 absl::lts_2020_02_25::synchronization_internal::PerThreadSem::Wait()
@ 0x55fa744c2e30 absl::lts_2020_02_25::Mutex::DecrementSynchSem()
@ 0x55fa744c1c11 absl::lts_2020_02_25::CondVar::WaitCommon()
@ 0x55fa744c1db9 absl::lts_2020_02_25::CondVar::Wait()
@ 0x55fa744a5e9c gpr_cv_wait
@ 0x55fa742f6822 grpc::CoreCodegen::gpr_cv_wait()
@ 0x55fa742dc11b grpc::internal::CondVar::Wait()
@ 0x55fa742dc0b5 grpc::internal::CondVar::Wait()
@ 0x55fa742da9f6 grpc::Server::Wait()
@ 0x55fa74121552 main
@ 0x7f15c2b96b97 __libc_start_main
[mutex.cc : 1366] RAW: Acquiring 0x55fa75cabe78 Mutexes held: 0x55fa75cabe78
[mutex.cc : 1367] RAW: Cycle:
[mutex.cc : 1381] RAW: mutex@0x55fa75cabe78 stack:
@ 0x55fa744bdc5a absl::lts_2020_02_25::DebugOnlyDeadlockCheck()
@ 0x55fa744bdf30 absl::lts_2020_02_25::Mutex::Lock()
@ 0x55fa744a5dc2 gpr_mu_lock
@ 0x55fa742f677e grpc::CoreCodegen::gpr_mu_lock()
@ 0x55fa74124077 grpc::internal::MutexLock::MutexLock()
@ 0x55fa742da51b grpc::Server::ShutdownInternal()
@ 0x55fa741216d2 grpc::ServerInterface::Shutdown()
@ 0x55fa7412140f shutdown()
@ 0x7f15c2bb3f20
@ 0x55fa744c435b absl::lts_2020_02_25::synchronization_internal::Waiter::Wait()
@ 0x55fa744c4097 AbslInternalPerThreadSemWait
@ 0x55fa744c2a92 absl::lts_2020_02_25::synchronization_internal::PerThreadSem::Wait()
@ 0x55fa744c2e30 absl::lts_2020_02_25::Mutex::DecrementSynchSem()
@ 0x55fa744c1c11 absl::lts_2020_02_25::CondVar::WaitCommon()
@ 0x55fa744c1db9 absl::lts_2020_02_25::CondVar::Wait()
@ 0x55fa744a5e9c gpr_cv_wait
@ 0x55fa742f6822 grpc::CoreCodegen::gpr_cv_wait()
@ 0x55fa742dc11b grpc::internal::CondVar::Wait()
@ 0x55fa742dc0b5 grpc::internal::CondVar::Wait()
@ 0x55fa742da9f6 grpc::Server::Wait()
@ 0x55fa74121552 main
@ 0x7f15c2b96b97 __libc_start_main
[mutex.cc : 1386] RAW: dying due to potential deadlock
Aborted (core dumped)
When built with opt
^C[mutex.cc : 2043] RAW: Check waitp == nullptr || waitp->thread->waitp == nullptr || waitp->thread->suppress_fatal_errors failed: detected illegal recursion into Mutex code
Aborted (core dumped)
Anything else we should know about your project / environment?
Works as expected on grpc 1.28.1 which was the previous version used before upgrading to 1.33.2.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 18 (9 by maintainers)
@vjpai @orzel Running a sort of infinite while loop seems very inefficient. The task can be easily achieved by conditional variables. Here is my more efficient approach…
For the record, here is what I do, and it works with recent grpc (1.43.0).