Move stack logging entirely into palette library

Make SignalCatcher::Output the same on host and target.

Apply same logic of when to log stacks to system logger as prior to
PaletteTombstonedMessage introduction.

Add PaletteStatus::kFailedCheckLog

Bug: 130025619
Test: art/tools/buildbot-build.sh --host -j100 && art/test.py --host -j32
Test: adb shell killall -QUIT system_server and check /data/anr
Test: Fill /data using 'dd', again send SIGQUIT to system and \
  check logcat for stack traces.
Test: adb bugreport; check the produced report

Change-Id: I1b3b6780622b9799d61fb12ad11a28085729c5e9
diff --git a/libartpalette/Android.bp b/libartpalette/Android.bp
index 75bf97c..5a3e986 100644
--- a/libartpalette/Android.bp
+++ b/libartpalette/Android.bp
@@ -42,6 +42,7 @@
         host: {
           header_libs: ["libbase_headers"],
           srcs: ["system/palette_fake.cc",],
+          shared_libs: ["libbase"],
         },
         darwin: {
             enabled: false,
@@ -81,7 +82,10 @@
           header_libs: ["libbase_headers"],
             srcs: ["system/palette_fake.cc"],
             shared: {
-                shared_libs: ["liblog"],
+              shared_libs: [
+                "libbase",
+                "liblog"
+              ],
             },
             version_script: "libartpalette.map.txt",
         },
@@ -89,7 +93,10 @@
           header_libs: ["libbase_headers"],
             srcs: ["system/palette_fake.cc"],
             shared: {
-                shared_libs: ["liblog"],
+              shared_libs: [
+                "libbase",
+                "liblog"
+              ],
             },
             version_script: "libartpalette.map.txt",
         },
@@ -99,11 +106,19 @@
             enabled: true,
             header_libs: ["libbase_headers"],
             srcs: ["system/palette_fake.cc"],
+            static_libs: [
+              "libbase",
+              "liblog"
+            ],
         },
         windows: {
             enabled: true,
             header_libs: ["libbase_headers"],
             srcs: ["system/palette_fake.cc"],
+            static_libs: [
+              "libbase",
+              "liblog"
+            ],
         },
     }
 }
diff --git a/libartpalette/apex/palette.cc b/libartpalette/apex/palette.cc
index 1821a17..3570798 100644
--- a/libartpalette/apex/palette.cc
+++ b/libartpalette/apex/palette.cc
@@ -125,9 +125,10 @@
   return m(tid, java_priority);
 }
 
-enum PaletteStatus PaletteTombstonedMessage(/*in*/const char* msg, size_t msg_len) {
-  PaletteTombstonedMessageMethod m = PaletteLoader::Instance().GetPaletteTombstonedMessageMethod();
-  return m(msg, msg_len);
+enum PaletteStatus PaletteWriteCrashThreadStacks(/*in*/const char* stack, size_t stack_len) {
+  PaletteWriteCrashThreadStacksMethod m =
+      PaletteLoader::Instance().GetPaletteWriteCrashThreadStacksMethod();
+  return m(stack, stack_len);
 }
 
 enum PaletteStatus PaletteTraceEnabled(/*out*/int32_t* enabled) {
diff --git a/libartpalette/include/palette/palette_method_list.h b/libartpalette/include/palette/palette_method_list.h
index 3e730fd..2738b57 100644
--- a/libartpalette/include/palette/palette_method_list.h
+++ b/libartpalette/include/palette/palette_method_list.h
@@ -25,7 +25,7 @@
   M(PaletteGetVersion, /*out*/int32_t* version)                             \
   M(PaletteSchedSetPriority, int32_t tid, int32_t java_priority)            \
   M(PaletteSchedGetPriority, int32_t tid, /*out*/int32_t* java_priority)    \
-  M(PaletteTombstonedMessage, const char* msg, size_t msg_len)              \
+  M(PaletteWriteCrashThreadStacks, const char* stacks, size_t stacks_len)   \
   M(PaletteTraceEnabled, /*out*/int32_t* enabled)                           \
   M(PaletteTraceBegin, const char* name)                                    \
   M(PaletteTraceEnd)                                                        \
diff --git a/libartpalette/include/palette/palette_types.h b/libartpalette/include/palette/palette_types.h
index 837086e..c2cd6b8 100644
--- a/libartpalette/include/palette/palette_types.h
+++ b/libartpalette/include/palette/palette_types.h
@@ -29,6 +29,7 @@
   kCheckErrno = 1,
   kInvalidArgument = 2,
   kNotSupported = 3,
+  kFailedCheckLog = 4,
 };
 
 #ifdef __cplusplus
diff --git a/libartpalette/libartpalette.map.txt b/libartpalette/libartpalette.map.txt
index 78b33ac..e589986 100644
--- a/libartpalette/libartpalette.map.txt
+++ b/libartpalette/libartpalette.map.txt
@@ -20,7 +20,7 @@
     PaletteGetVersion;
     PaletteSchedSetPriority;
     PaletteSchedGetPriority;
-    PaletteTombstonedMessage;
+    PaletteWriteCrashThreadStacks;
     PaletteTraceEnabled;
     PaletteTraceBegin;
     PaletteTraceEnd;
diff --git a/libartpalette/system/palette_android.cc b/libartpalette/system/palette_android.cc
index 2314f30..0c9db9d 100644
--- a/libartpalette/system/palette_android.cc
+++ b/libartpalette/system/palette_android.cc
@@ -106,44 +106,50 @@
   return PaletteStatus::kOkay;
 }
 
-enum PaletteStatus PaletteTombstonedMessage(/*in*/const char* msg, size_t msg_len) {
+enum PaletteStatus PaletteWriteCrashThreadStacks(/*in*/const char* stacks, size_t stacks_len) {
   android::base::unique_fd tombstone_fd;
   android::base::unique_fd output_fd;
+
   if (!tombstoned_connect(getpid(), &tombstone_fd, &output_fd, kDebuggerdJavaBacktrace)) {
-    return PaletteStatus::kCheckErrno;
+    // Failure here could be due to file descriptor resource exhaustion
+    // so write the stack trace message to the log in case it helps
+    // debug that.
+    LOG(INFO) << std::string_view(stacks, stacks_len);
+    // tombstoned_connect() logs failure reason.
+    return PaletteStatus::kFailedCheckLog;
   }
 
-  bool success = true;
-  if (!android::base::WriteFully(output_fd, msg, msg_len)) {
+  PaletteStatus status = PaletteStatus::kOkay;
+  if (!android::base::WriteFully(output_fd, stacks, stacks_len)) {
     PLOG(ERROR) << "Failed to write tombstoned output";
-    success = false;
-  } else if (TEMP_FAILURE_RETRY(fsync(output_fd)) == -1 && errno != EINVAL) {
+    TEMP_FAILURE_RETRY(ftruncate(output_fd, 0));
+    status = PaletteStatus::kFailedCheckLog;
+  }
+
+  if (TEMP_FAILURE_RETRY(fdatasync(output_fd)) == -1 && errno != EINVAL) {
     // Ignore EINVAL so we don't report failure if we just tried to flush a pipe
     // or socket.
-    PLOG(ERROR) << "Failed to fsync tombstoned output";
-    success = false;
-  } else if (close(output_fd.release()) == -1) {
-    // Shouldn't retry close after EINTR because the fd has been closed anyway,
-    // but don't count it as a failure either.
-    if (errno != EINTR) {
+    if (status == PaletteStatus::kOkay) {
+      PLOG(ERROR) << "Failed to fsync tombstoned output";
+      status = PaletteStatus::kFailedCheckLog;
+    }
+    TEMP_FAILURE_RETRY(ftruncate(output_fd, 0));
+    TEMP_FAILURE_RETRY(fdatasync(output_fd));
+  }
+
+  if (close(output_fd.release()) == -1 && errno != EINTR) {
+    if (status == PaletteStatus::kOkay) {
       PLOG(ERROR) << "Failed to close tombstoned output";
-      success = false;
+      status = PaletteStatus::kFailedCheckLog;
     }
   }
 
-  if (!success) {
-    int saved_errno = errno;
-    TEMP_FAILURE_RETRY(ftruncate(output_fd, 0));
-    TEMP_FAILURE_RETRY(fsync(output_fd));
-    close(output_fd.release());
-    errno = saved_errno;
-  }
-
   if (!tombstoned_notify_completion(tombstone_fd)) {
-    success = false;
+    // tombstoned_notify_completion() logs failure.
+    status = PaletteStatus::kFailedCheckLog;
   }
 
-  return success ? PaletteStatus::kOkay : PaletteStatus::kCheckErrno;
+  return status;
 }
 
 enum PaletteStatus PaletteTraceEnabled(/*out*/int32_t* enabled) {
diff --git a/libartpalette/system/palette_fake.cc b/libartpalette/system/palette_fake.cc
index 07a54df..4cc00d0 100644
--- a/libartpalette/system/palette_fake.cc
+++ b/libartpalette/system/palette_fake.cc
@@ -19,6 +19,7 @@
 #include <map>
 #include <mutex>
 
+#include <android-base/logging.h>
 #include <android-base/macros.h>  // For ATTRIBUTE_UNUSED
 
 #include "palette_system.h"
@@ -52,8 +53,8 @@
   return PaletteStatus::kOkay;
 }
 
-enum PaletteStatus PaletteTombstonedMessage(/*in*/ const char* msg ATTRIBUTE_UNUSED,
-                                            size_t msg_len ATTRIBUTE_UNUSED) {
+enum PaletteStatus PaletteWriteCrashThreadStacks(/*in*/ const char* stacks, size_t stacks_len) {
+  LOG(INFO) << std::string_view(stacks, stacks_len);
   return PaletteStatus::kOkay;
 }
 
diff --git a/runtime/signal_catcher.cc b/runtime/signal_catcher.cc
index 20c85c1..8da5fee 100644
--- a/runtime/signal_catcher.cc
+++ b/runtime/signal_catcher.cc
@@ -103,18 +103,14 @@
 }
 
 void SignalCatcher::Output(const std::string& s) {
-#if defined(ART_TARGET_ANDROID)
   ScopedThreadStateChange tsc(Thread::Current(), kWaitingForSignalCatcherOutput);
-  PaletteStatus status = PaletteTombstonedMessage(s.data(), s.size());
+  PaletteStatus status = PaletteWriteCrashThreadStacks(s.data(), s.size());
   if (status == PaletteStatus::kOkay) {
     LOG(INFO) << "Wrote stack traces to tombstoned";
   } else {
-    CHECK(status == PaletteStatus::kCheckErrno);
-    PLOG(ERROR) << "Failed to write stack traces to tombstoned";
+    CHECK(status == PaletteStatus::kFailedCheckLog);
+    LOG(ERROR) << "Failed to write stack traces to tombstoned";
   }
-#else
-  LOG(INFO) << s;
-#endif
 }
 
 void SignalCatcher::HandleSigQuit() {