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

Loading…
Cancel
Save