Merge "Add missing <complex.h> functions."
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 863b07c..e050619 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -334,8 +334,8 @@
   }
 
   // Initialize malloc debugging in the loaded module.
-  void* sym = dlsym(malloc_impl_handle, "debug_initialize");
-  auto init_func = reinterpret_cast<bool (*)(const MallocDispatch*, int*)>(sym);
+  auto init_func = reinterpret_cast<bool (*)(const MallocDispatch*, int*)>(
+      dlsym(malloc_impl_handle, "debug_initialize"));
   if (init_func == nullptr) {
     error_log("%s: debug_initialize routine not found in %s", getprogname(), DEBUG_SHARED_LIB);
     dlclose(malloc_impl_handle);
@@ -343,41 +343,36 @@
   }
 
   // Get the syms for the external functions.
-  sym = dlsym(malloc_impl_handle, "debug_finalize");
-  if (sym == nullptr) {
+  void* finalize_sym = dlsym(malloc_impl_handle, "debug_finalize");
+  if (finalize_sym == nullptr) {
     error_log("%s: debug_finalize routine not found in %s", getprogname(), DEBUG_SHARED_LIB);
     dlclose(malloc_impl_handle);
     return;
   }
-  g_debug_finalize_func = reinterpret_cast<void (*)()>(sym);
 
-  sym = dlsym(malloc_impl_handle, "debug_get_malloc_leak_info");
-  if (sym == nullptr) {
+  void* get_leak_info_sym = dlsym(malloc_impl_handle, "debug_get_malloc_leak_info");
+  if (get_leak_info_sym == nullptr) {
     error_log("%s: debug_get_malloc_leak_info routine not found in %s", getprogname(),
               DEBUG_SHARED_LIB);
     dlclose(malloc_impl_handle);
     return;
   }
-  g_debug_get_malloc_leak_info_func = reinterpret_cast<void (*)(uint8_t**, size_t*, size_t*,
-                                                                size_t*, size_t*)>(sym);
 
-  sym = dlsym(malloc_impl_handle, "debug_free_malloc_leak_info");
-  if (sym == nullptr) {
+  void* free_leak_info_sym = dlsym(malloc_impl_handle, "debug_free_malloc_leak_info");
+  if (free_leak_info_sym == nullptr) {
     error_log("%s: debug_free_malloc_leak_info routine not found in %s", getprogname(),
               DEBUG_SHARED_LIB);
     dlclose(malloc_impl_handle);
     return;
   }
-  g_debug_free_malloc_leak_info_func = reinterpret_cast<void (*)(uint8_t*)>(sym);
 
-  sym = dlsym(malloc_impl_handle, "debug_malloc_backtrace");
-  if (sym == nullptr) {
+  void* malloc_backtrace_sym = dlsym(malloc_impl_handle, "debug_malloc_backtrace");
+  if (malloc_backtrace_sym == nullptr) {
     error_log("%s: debug_malloc_backtrace routine not found in %s", getprogname(),
               DEBUG_SHARED_LIB);
     dlclose(malloc_impl_handle);
     return;
   }
-  g_debug_malloc_backtrace_func = reinterpret_cast<ssize_t (*)(void*, uintptr_t*, size_t)>(sym);
 
   if (!init_func(&__libc_malloc_default_dispatch, &gMallocLeakZygoteChild)) {
     dlclose(malloc_impl_handle);
@@ -386,11 +381,19 @@
 
   MallocDispatch malloc_dispatch_table;
   if (!InitMalloc(malloc_impl_handle, &malloc_dispatch_table, "debug")) {
-    g_debug_finalize_func();
+    auto finalize_func = reinterpret_cast<void (*)()>(finalize_sym);
+    finalize_func();
     dlclose(malloc_impl_handle);
     return;
   }
 
+  g_debug_finalize_func = reinterpret_cast<void (*)()>(finalize_sym);
+  g_debug_get_malloc_leak_info_func = reinterpret_cast<void (*)(
+      uint8_t**, size_t*, size_t*, size_t*, size_t*)>(get_leak_info_sym);
+  g_debug_free_malloc_leak_info_func = reinterpret_cast<void (*)(uint8_t*)>(free_leak_info_sym);
+  g_debug_malloc_backtrace_func = reinterpret_cast<ssize_t (*)(
+      void*, uintptr_t*, size_t)>(malloc_backtrace_sym);
+
   globals->malloc_dispatch = malloc_dispatch_table;
   libc_malloc_impl_handle = malloc_impl_handle;
 
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 125b3c9..cff6288 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -124,8 +124,8 @@
     case _SC_THREAD_DESTRUCTOR_ITERATIONS: return PTHREAD_DESTRUCTOR_ITERATIONS;
     case _SC_THREAD_KEYS_MAX:   return PTHREAD_KEYS_MAX;
     case _SC_THREAD_STACK_MIN:    return PTHREAD_STACK_MIN;
-    case _SC_THREAD_THREADS_MAX:  return PTHREAD_THREADS_MAX;
-    case _SC_TTY_NAME_MAX:        return 32;  // Seems default on linux.
+    case _SC_THREAD_THREADS_MAX:  return -1; // No specific limit.
+    case _SC_TTY_NAME_MAX:        return 32; // Seems default on linux.
     case _SC_THREADS:             return _POSIX_THREADS;
     case _SC_THREAD_ATTR_STACKADDR:   return _POSIX_THREAD_ATTR_STACKADDR;
     case _SC_THREAD_ATTR_STACKSIZE:   return _POSIX_THREAD_ATTR_STACKSIZE;
diff --git a/libc/include/sys/limits.h b/libc/include/sys/limits.h
index be79cf3..f84253e 100644
--- a/libc/include/sys/limits.h
+++ b/libc/include/sys/limits.h
@@ -120,8 +120,11 @@
 #define  _XOPEN_VERSION             700       /* by Posix definition */
 
 
-#define PTHREAD_DESTRUCTOR_ITERATIONS 4     // >= _POSIX_THREAD_DESTRUCTOR_ITERATIONS
-#define PTHREAD_KEYS_MAX              128   // >= _POSIX_THREAD_KEYS_MAX
-#define PTHREAD_THREADS_MAX           2048  // bionic has no specific limit
+/* >= _POSIX_THREAD_DESTRUCTOR_ITERATIONS */
+#define PTHREAD_DESTRUCTOR_ITERATIONS 4
+/* >= _POSIX_THREAD_KEYS_MAX */
+#define PTHREAD_KEYS_MAX 128
+/* bionic has no specific limit */
+#undef PTHREAD_THREADS_MAX
 
 #endif
diff --git a/libc/malloc_debug/Config.cpp b/libc/malloc_debug/Config.cpp
index 4586fda3..ded618c 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -333,9 +333,9 @@
   size_t value;
   bool value_set;
   PropertyParser parser(property_str);
-  bool found = false;
   bool valid = true;
   while (valid && parser.Get(&property, &value, &value_set)) {
+    bool found = false;
     for (size_t i = 0; i < sizeof(features)/sizeof(Feature); i++) {
       if (property == features[i].name) {
         if (features[i].option == 0 && features[i].combo_option) {
diff --git a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
index a6cea98..85d5cb5 100644
--- a/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_config_tests.cpp
@@ -124,6 +124,14 @@
   ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
 }
 
+TEST_F(MallocDebugConfigTest, good_option_and_bad_option) {
+  ASSERT_FALSE(InitConfig("backtrace unknown_option"));
+
+  ASSERT_STREQ("", getFakeLogBuf().c_str());
+  std::string log_msg("6 malloc_debug malloc_testing: unknown option unknown_option\n");
+  ASSERT_STREQ((log_msg + usage_string).c_str(), getFakeLogPrint().c_str());
+}
+
 TEST_F(MallocDebugConfigTest, unparseable_number) {
   ASSERT_FALSE(InitConfig("backtrace=XXX"));
 
diff --git a/tests/signal_test.cpp b/tests/signal_test.cpp
index 8c1e834..32308aa 100644
--- a/tests/signal_test.cpp
+++ b/tests/signal_test.cpp
@@ -387,13 +387,15 @@
     "* https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=66dd34ad31e5963d72a700ec3f2449291d322921\n";
   static siginfo received;
 
-  struct sigaction handler = {};
+  struct sigaction handler;
+  memset(&handler, 0, sizeof(handler));
   handler.sa_sigaction = [](int, siginfo_t* siginfo, void*) { received = *siginfo; };
   handler.sa_flags = SA_SIGINFO;
 
   ASSERT_EQ(0, sigaction(SIGUSR1, &handler, nullptr));
 
-  siginfo sent = {};
+  siginfo sent;
+  memset(&sent, 0, sizeof(sent));
 
   sent.si_code = SI_TKILL;
   ASSERT_EQ(0, syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), SIGUSR1, &sent))