From 00185ee4e4c650923ce81439f2742a0977324aeb Mon Sep 17 00:00:00 2001 From: Mikhail Bautin Date: Thu, 2 Jan 2020 18:01:35 -0800 Subject: [PATCH] [YSQL] #2509 Force network library initialization on postmaster startup on macOS Summary: Add a DNS lookup of the local hostname to postmaster startup to force macOS network libraries to get initialized before any fork() calls happen. This fixes failures of ~20 tests in macOS debug mode. Without this, PostgreSQL backends would frequently crash with SIGSEGV and dump cores when trying to do the same DNS lookup. Here is a SIGSEGV stack trace that we would previously get without this fix: ``` frame #0: 0x00007fff7bd53e34 libsystem_trace.dylib`_os_log_cmp_key + 4 frame #1: 0x00007fff7bbfcb74 libsystem_c.dylib`rb_tree_find_node + 53 frame #2: 0x00007fff7bd52021 libsystem_trace.dylib`os_log_create + 368 frame #3: 0x00007fff7bc5b127 libsystem_info.dylib`gai_log_init + 23 frame #4: 0x00007fff7bd37ce3 libsystem_pthread.dylib`__pthread_once_handler + 65 frame #5: 0x00007fff7bd2daab libsystem_platform.dylib`_os_once_callout + 18 frame #6: 0x00007fff7bd37c7f libsystem_pthread.dylib`pthread_once + 56 frame #7: 0x00007fff7bc5a4ab libsystem_info.dylib`gai_log + 27 frame #8: 0x00007fff7bc5b33f libsystem_info.dylib`_gai_load_libnetwork_once + 63 frame #9: 0x00007fff7bd37ce3 libsystem_pthread.dylib`__pthread_once_handler + 65 frame #10: 0x00007fff7bd2daab libsystem_platform.dylib`_os_once_callout + 18 frame #11: 0x00007fff7bd37c7f libsystem_pthread.dylib`pthread_once + 56 frame #12: 0x00007fff7bc5b29b libsystem_info.dylib`_gai_load_libnetwork + 27 frame #13: 0x00007fff7bc5b64f libsystem_info.dylib`_gai_nat64_v4_address_requires_synthesis + 31 frame #14: 0x00007fff7bc5aaa0 libsystem_info.dylib`_gai_nat64_second_pass + 512 frame #15: 0x00007fff7bc39847 libsystem_info.dylib`si_addrinfo + 1959 frame #16: 0x00007fff7bc38f77 libsystem_info.dylib`_getaddrinfo_internal + 231 frame #17: 0x00007fff7bc38e7d libsystem_info.dylib`getaddrinfo + 61 frame #18: 0x000000011512f8e5 libyb_util.dylib`yb::GetFQDN(hostname="...") at net_util.cc:371:20 ``` Test Plan: Jenkins Reviewers: mihnea, dmitry Reviewed By: dmitry Subscribers: yql Differential Revision: https://phabricator.dev.yugabyte.com/D7757 --- src/postgres/src/backend/postmaster/postmaster.c | 13 +++++++++++++ src/yb/common/ybc_util.cc | 11 +++++++++++ src/yb/common/ybc_util.h | 2 ++ 3 files changed, 26 insertions(+) diff --git a/src/postgres/src/backend/postmaster/postmaster.c b/src/postgres/src/backend/postmaster/postmaster.c index a50aff56632d..6456f408905c 100644 --- a/src/postgres/src/backend/postmaster/postmaster.c +++ b/src/postgres/src/backend/postmaster/postmaster.c @@ -944,6 +944,19 @@ PostmasterMain(int argc, char *argv[]) } YBReportIfYugaByteEnabled(); +#ifdef __APPLE__ + if (YBIsEnabledInPostgresEnvVar()) { + /* + * Resolve local hostname to initialize macOS network libraries. If we + * don't do this, there might be a lot of segmentation faults in + * PostgreSQL backend processes in tests on macOS (especially debug + * mode). + * + * See https://github.com/yugabyte/yugabyte-db/issues/2509 for details. + */ + YBCResolveHostname(); + } +#endif /* * Create lockfile for data directory. diff --git a/src/yb/common/ybc_util.cc b/src/yb/common/ybc_util.cc index e51faf665b71..1a71e6eaac3d 100644 --- a/src/yb/common/ybc_util.cc +++ b/src/yb/common/ybc_util.cc @@ -30,6 +30,8 @@ #include "yb/util/status.h" #include "yb/util/version_info.h" +#include "yb/util/net/net_util.h" + #include "yb/gutil/stringprintf.h" using std::string; @@ -258,6 +260,15 @@ const char* YBCGetStackTrace() { return YBCPAllocStdString(yb::GetStackTrace()); } +void YBCResolveHostname() { + string fqdn; + auto status = GetFQDN(&fqdn); + if (!status.ok()) { + LOG(WARNING) << "Failed to get fully qualified domain name of the local hostname: " + << status; + } +} + } // extern "C" } // namespace yb diff --git a/src/yb/common/ybc_util.h b/src/yb/common/ybc_util.h index a15b2004bd03..1e7a1bda49d6 100644 --- a/src/yb/common/ybc_util.h +++ b/src/yb/common/ybc_util.h @@ -42,6 +42,8 @@ const char* YBCStatusCodeAsCString(YBCStatus s); bool YBCIsRestartReadError(uint16_t txn_errcode); +void YBCResolveHostname(); + #define CHECKED_YBCSTATUS __attribute__ ((warn_unused_result)) YBCStatus typedef void* (*YBCPAllocFn)(size_t size);