[fork] Log when pthread_create fails (#32525)

There was evidence that a `pthread_create` failed in [this
comment](https://github.com/grpc/grpc/issues/31885#issuecomment-1433917201),
but without logging, we couldn't diagnose any further. This PR logs in
this case.
pull/32552/head
Richard Belleville 2 years ago committed by GitHub
parent 3de6b56ae5
commit 73bf7a364d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 78
      src/core/lib/gprpp/posix/thd.cc

@ -20,6 +20,8 @@
#include <grpc/support/port_platform.h> #include <grpc/support/port_platform.h>
#include <string>
#include <grpc/support/time.h> #include <grpc/support/time.h>
#ifdef GPR_POSIX_SYNC #ifdef GPR_POSIX_SYNC
@ -35,6 +37,7 @@
#include "src/core/lib/gpr/useful.h" #include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/fork.h" #include "src/core/lib/gprpp/fork.h"
#include "src/core/lib/gprpp/strerror.h"
#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/gprpp/thd.h"
namespace grpc_core { namespace grpc_core {
@ -106,49 +109,52 @@ class ThreadInternalsPosix : public internal::ThreadInternalsInterface {
GPR_ASSERT(pthread_attr_setstacksize(&attr, stack_size) == 0); GPR_ASSERT(pthread_attr_setstacksize(&attr, stack_size) == 0);
} }
*success = (pthread_create( int pthread_create_err = pthread_create(
&pthread_id_, &attr, &pthread_id_, &attr,
[](void* v) -> void* { [](void* v) -> void* {
thd_arg arg = *static_cast<thd_arg*>(v); thd_arg arg = *static_cast<thd_arg*>(v);
free(v); free(v);
if (arg.name != nullptr) { if (arg.name != nullptr) {
#if GPR_APPLE_PTHREAD_NAME #if GPR_APPLE_PTHREAD_NAME
// Apple supports 64 characters, and will // Apple supports 64 characters, and will
// truncate if it's longer. // truncate if it's longer.
pthread_setname_np(arg.name); pthread_setname_np(arg.name);
#elif GPR_LINUX_PTHREAD_NAME #elif GPR_LINUX_PTHREAD_NAME
// Linux supports 16 characters max, and will // Linux supports 16 characters max, and will
// error if it's longer. // error if it's longer.
char buf[16]; char buf[16];
size_t buf_len = GPR_ARRAY_SIZE(buf) - 1; size_t buf_len = GPR_ARRAY_SIZE(buf) - 1;
strncpy(buf, arg.name, buf_len); strncpy(buf, arg.name, buf_len);
buf[buf_len] = '\0'; buf[buf_len] = '\0';
pthread_setname_np(pthread_self(), buf); pthread_setname_np(pthread_self(), buf);
#endif // GPR_APPLE_PTHREAD_NAME #endif // GPR_APPLE_PTHREAD_NAME
} }
gpr_mu_lock(&arg.thread->mu_); gpr_mu_lock(&arg.thread->mu_);
while (!arg.thread->started_) { while (!arg.thread->started_) {
gpr_cv_wait(&arg.thread->ready_, &arg.thread->mu_, gpr_cv_wait(&arg.thread->ready_, &arg.thread->mu_,
gpr_inf_future(GPR_CLOCK_MONOTONIC)); gpr_inf_future(GPR_CLOCK_MONOTONIC));
} }
gpr_mu_unlock(&arg.thread->mu_); gpr_mu_unlock(&arg.thread->mu_);
if (!arg.joinable) { if (!arg.joinable) {
delete arg.thread; delete arg.thread;
} }
(*arg.body)(arg.arg); (*arg.body)(arg.arg);
if (arg.tracked) { if (arg.tracked) {
Fork::DecThreadCount(); Fork::DecThreadCount();
} }
return nullptr; return nullptr;
}, },
info) == 0); info);
*success = (pthread_create_err == 0);
GPR_ASSERT(pthread_attr_destroy(&attr) == 0); GPR_ASSERT(pthread_attr_destroy(&attr) == 0);
if (!(*success)) { if (!(*success)) {
gpr_log(GPR_ERROR, "pthread_create failed: %s",
StrError(pthread_create_err).c_str());
// don't use gpr_free, as this was allocated using malloc (see above) // don't use gpr_free, as this was allocated using malloc (see above)
free(info); free(info);
if (options.tracked()) { if (options.tracked()) {

Loading…
Cancel
Save