From 47d784e9f2ffe128a5564b111698c0103e88d62b Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 5 Nov 2021 18:40:52 -0700 Subject: [PATCH] Add a human readable description of the tagged_addr_ctrl value to tombstones. Change-Id: Ib9860b282cf749891e0f6ef7697669b94235c236 --- debuggerd/Android.bp | 1 + debuggerd/debuggerd_test.cpp | 3 +- .../include/libdebuggerd/utility.h | 1 + debuggerd/libdebuggerd/test/utility_test.cpp | 33 +++++++++++++++++++ debuggerd/libdebuggerd/tombstone.cpp | 3 +- .../libdebuggerd/tombstone_proto_to_text.cpp | 3 +- debuggerd/libdebuggerd/utility.cpp | 28 ++++++++++++++++ 7 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 debuggerd/libdebuggerd/test/utility_test.cpp diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp index f713ff2df..16cbbb0b4 100644 --- a/debuggerd/Android.bp +++ b/debuggerd/Android.bp @@ -272,6 +272,7 @@ cc_test { "libdebuggerd/test/log_fake.cpp", "libdebuggerd/test/open_files_list_test.cpp", "libdebuggerd/test/tombstone_test.cpp", + "libdebuggerd/test/utility_test.cpp", ], target: { diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp index 59643d9d3..75f9921aa 100644 --- a/debuggerd/debuggerd_test.cpp +++ b/debuggerd/debuggerd_test.cpp @@ -343,7 +343,8 @@ TEST_F(CrasherTest, smoke) { if (mte_supported()) { // Test that the default TAGGED_ADDR_CTRL value is set. - ASSERT_MATCH(result, R"(tagged_addr_ctrl: 000000000007fff3)"); + ASSERT_MATCH(result, R"(tagged_addr_ctrl: 000000000007fff3)" + R"( \(PR_TAGGED_ADDR_ENABLE, PR_MTE_TCF_SYNC, mask 0xfffe\))"); } } diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h index 24ae16949..002321f93 100644 --- a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h +++ b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h @@ -92,6 +92,7 @@ bool signal_has_si_addr(const siginfo_t*); 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 000000000..97328b7f7 --- /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 +#include + +#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 ff03bcd1e..a4a3c9e73 100644 --- a/debuggerd/libdebuggerd/tombstone.cpp +++ b/debuggerd/libdebuggerd/tombstone.cpp @@ -191,7 +191,8 @@ static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) { 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 053299a81..0cba362d2 100644 --- a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp +++ b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp @@ -82,7 +82,8 @@ static void print_thread_header(CallbackType callback, const Tombstone& tombston 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 a7506b760..3c4c27149 100644 --- a/debuggerd/libdebuggerd/utility.cpp +++ b/debuggerd/libdebuggerd/utility.cpp @@ -41,6 +41,7 @@ #include #include +using android::base::StringPrintf; using android::base::unique_fd; bool is_allowed_in_logcat(enum logtype ltype) { @@ -444,6 +445,33 @@ const char* get_sigcode(const siginfo_t* si) { 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,