Add a human readable description of the tagged_addr_ctrl value to tombstones.
Change-Id: Ib9860b282cf749891e0f6ef7697669b94235c236
diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
index 24ae169..002321f 100644
--- a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
+++ b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h
@@ -92,6 +92,7 @@
void get_signal_sender(char* buf, size_t n, const siginfo_t*);
const char* get_signame(const siginfo_t*);
const char* get_sigcode(const siginfo_t*);
+std::string describe_tagged_addr_ctrl(long ctrl);
// Number of bytes per MTE granule.
constexpr size_t kTagGranuleSize = 16;
diff --git a/debuggerd/libdebuggerd/test/utility_test.cpp b/debuggerd/libdebuggerd/test/utility_test.cpp
new file mode 100644
index 0000000..97328b7
--- /dev/null
+++ b/debuggerd/libdebuggerd/test/utility_test.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <sys/prctl.h>
+
+#include "libdebuggerd/utility.h"
+
+TEST(UtilityTest, describe_tagged_addr_ctrl) {
+ EXPECT_EQ("", describe_tagged_addr_ctrl(0));
+ EXPECT_EQ(" (PR_TAGGED_ADDR_ENABLE)", describe_tagged_addr_ctrl(PR_TAGGED_ADDR_ENABLE));
+ EXPECT_EQ(" (PR_TAGGED_ADDR_ENABLE, PR_MTE_TCF_SYNC, mask 0xfffe)",
+ describe_tagged_addr_ctrl(PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC |
+ (0xfffe << PR_MTE_TAG_SHIFT)));
+ EXPECT_EQ(
+ " (PR_TAGGED_ADDR_ENABLE, PR_MTE_TCF_SYNC, PR_MTE_TCF_ASYNC, mask 0xfffe, unknown "
+ "0xf0000000)",
+ describe_tagged_addr_ctrl(0xf0000000 | PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC |
+ PR_MTE_TCF_ASYNC | (0xfffe << PR_MTE_TAG_SHIFT)));
+}
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index ff03bcd..a4a3c9e 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -191,7 +191,8 @@
thread_info.tid, thread_info.thread_name.c_str(), process_name);
_LOG(log, logtype::HEADER, "uid: %d\n", thread_info.uid);
if (thread_info.tagged_addr_ctrl != -1) {
- _LOG(log, logtype::HEADER, "tagged_addr_ctrl: %016lx\n", thread_info.tagged_addr_ctrl);
+ _LOG(log, logtype::HEADER, "tagged_addr_ctrl: %016lx%s\n", thread_info.tagged_addr_ctrl,
+ describe_tagged_addr_ctrl(thread_info.tagged_addr_ctrl).c_str());
}
}
diff --git a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
index 053299a..0cba362 100644
--- a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
+++ b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
@@ -82,7 +82,8 @@
thread.name().c_str(), process_name);
CB(should_log, "uid: %d", tombstone.uid());
if (thread.tagged_addr_ctrl() != -1) {
- CB(should_log, "tagged_addr_ctrl: %016" PRIx64, thread.tagged_addr_ctrl());
+ CB(should_log, "tagged_addr_ctrl: %016" PRIx64 "%s", thread.tagged_addr_ctrl(),
+ describe_tagged_addr_ctrl(thread.tagged_addr_ctrl()).c_str());
}
}
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp
index a7506b7..3c4c271 100644
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -41,6 +41,7 @@
#include <unwindstack/Memory.h>
#include <unwindstack/Unwinder.h>
+using android::base::StringPrintf;
using android::base::unique_fd;
bool is_allowed_in_logcat(enum logtype ltype) {
@@ -444,6 +445,33 @@
return "?";
}
+std::string describe_tagged_addr_ctrl(long ctrl) {
+ std::string desc;
+ if (ctrl & PR_TAGGED_ADDR_ENABLE) {
+ desc += ", PR_TAGGED_ADDR_ENABLE";
+ ctrl &= ~PR_TAGGED_ADDR_ENABLE;
+ }
+ if (ctrl & PR_MTE_TCF_SYNC) {
+ desc += ", PR_MTE_TCF_SYNC";
+ ctrl &= ~PR_MTE_TCF_SYNC;
+ }
+ if (ctrl & PR_MTE_TCF_ASYNC) {
+ desc += ", PR_MTE_TCF_ASYNC";
+ ctrl &= ~PR_MTE_TCF_ASYNC;
+ }
+ if (ctrl & PR_MTE_TAG_MASK) {
+ desc += StringPrintf(", mask 0x%04lx", (ctrl & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT);
+ ctrl &= ~PR_MTE_TAG_MASK;
+ }
+ if (ctrl) {
+ desc += StringPrintf(", unknown 0x%lx", ctrl);
+ }
+ if (desc.empty()) {
+ return "";
+ }
+ return " (" + desc.substr(2) + ")";
+}
+
void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix) {
if (unwinder->elf_from_memory_not_file()) {
_LOG(log, logtype::BACKTRACE,