Merge changes from topic 'debuggerd_fallback'

* changes:
  linker_memory: allow fallback allocator to be turned on and off.
  Increase signal stack size on 32-bit to 16kB.
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index b170299..6faf5a4 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -141,13 +141,11 @@
 
 __LIBC_HIDDEN__ void pthread_key_clean_all(void);
 
-#if defined(__LP64__)
-// SIGSTKSZ is not big enough for 64-bit arch.
-// See https://code.google.com/p/android/issues/detail?id=187064.
+// SIGSTKSZ (8kB) is not big enough.
+// snprintf to a stack buffer of size PATH_MAX consumes ~7kB of stack.
+// Also, on 64-bit, logging uses more than 8kB by itself:
+// https://code.google.com/p/android/issues/detail?id=187064
 #define SIGNAL_STACK_SIZE_WITHOUT_GUARD_PAGE (16 * 1024)
-#else
-#define SIGNAL_STACK_SIZE_WITHOUT_GUARD_PAGE SIGSTKSZ
-#endif
 
 /*
  * Traditionally we gave threads a 1MiB stack. When we started
diff --git a/linker/linker_memory.cpp b/linker/linker_memory.cpp
index 18ef93e..f8852e1 100644
--- a/linker/linker_memory.cpp
+++ b/linker/linker_memory.cpp
@@ -39,16 +39,22 @@
 
 // Used by libdebuggerd_handler to switch allocators during a crash dump, in
 // case the linker heap is corrupted. Do not use this function.
-extern "C" void __linker_use_fallback_allocator() {
+extern "C" void __linker_enable_fallback_allocator() {
   if (fallback_tid != 0) {
-    __libc_format_log(ANDROID_LOG_ERROR, "libc",
-                      "attempted to set fallback allocator multiple times");
-    return;
+    __libc_fatal("attempted to use currently-in-use fallback allocator");
   }
 
   fallback_tid = gettid();
 }
 
+extern "C" void __linker_disable_fallback_allocator() {
+  if (fallback_tid == 0) {
+    __libc_fatal("attempted to disable unused fallback allocator");
+  }
+
+  fallback_tid = 0;
+}
+
 static LinkerMemoryAllocator& get_fallback_allocator() {
   static LinkerMemoryAllocator fallback_allocator;
   return fallback_allocator;
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 024a675..4fb15ad 100755
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -1888,17 +1888,26 @@
 
 static void SignalHandlerOnAltStack(int signo, siginfo_t*, void*) {
   ASSERT_EQ(SIGUSR1, signo);
-  // Check if we have enough stack space for unwinding.
-  int count = 0;
-  _Unwind_Backtrace(FrameCounter, &count);
-  ASSERT_GT(count, 0);
-  // Check if we have enough stack space for logging.
-  std::string s(2048, '*');
-  GTEST_LOG_(INFO) << s;
-  signal_handler_on_altstack_done = true;
+  {
+    // Check if we have enough stack space for unwinding.
+    int count = 0;
+    _Unwind_Backtrace(FrameCounter, &count);
+    ASSERT_GT(count, 0);
+  }
+  {
+    // Check if we have enough stack space for logging.
+    std::string s(2048, '*');
+    GTEST_LOG_(INFO) << s;
+    signal_handler_on_altstack_done = true;
+  }
+  {
+    // Check if we have enough stack space for snprintf to a PATH_MAX buffer, plus some extra.
+    char buf[PATH_MAX + 2048];
+    ASSERT_GT(snprintf(buf, sizeof(buf), "/proc/%d/status", getpid()), 0);
+  }
 }
 
-TEST(pthread, big_enough_signal_stack_for_64bit_arch) {
+TEST(pthread, big_enough_signal_stack) {
   signal_handler_on_altstack_done = false;
   ScopedSignalHandler handler(SIGUSR1, SignalHandlerOnAltStack, SA_SIGINFO | SA_ONSTACK);
   kill(getpid(), SIGUSR1);