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() {