summaryrefslogtreecommitdiff
path: root/debuggerd/debuggerd_test.cpp
diff options
context:
space:
mode:
authorPeter Collingbourne <pcc@google.com>2020-07-17 14:49:31 -0700
committerPeter Collingbourne <pcc@google.com>2020-07-17 17:35:49 -0700
commit10e428dd77181003942542d8de5c4615b693c610 (patch)
treea39bf752d803fba06954feb6e9bbafd54a346bc2 /debuggerd/debuggerd_test.cpp
parentc8e4154d899847a32f0fb7bbf999c39c7cb0dba7 (diff)
Fix dumping of heap memory.
After r.android.com/1288984 we started failing to dump memory contents for heap addresses because the tag started causing any addresses to fail this bounds check. Add an untag_address() call to the bounds check so that the tag is ignored. Bug: 154272452 Change-Id: I3a6d1a078b21871bd93164150a123549f83289f6
Diffstat (limited to 'debuggerd/debuggerd_test.cpp')
-rw-r--r--debuggerd/debuggerd_test.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 9d7658eb0..f1119cc03 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -172,6 +172,8 @@ class CrasherTest : public ::testing::Test {
void StartCrasher(const std::string& crash_type);
void FinishCrasher();
void AssertDeath(int signo);
+
+ static void Trap(void* ptr);
};
CrasherTest::CrasherTest() {
@@ -334,6 +336,48 @@ TEST_F(CrasherTest, tagged_fault_addr) {
R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr (0x100000000000dead|0xdead))");
}
+// Marked as weak to prevent the compiler from removing the malloc in the caller. In theory, the
+// compiler could still clobber the argument register before trapping, but that's unlikely.
+__attribute__((weak)) void CrasherTest::Trap(void* ptr ATTRIBUTE_UNUSED) {
+ __builtin_trap();
+}
+
+TEST_F(CrasherTest, heap_addr_in_register) {
+#if defined(__i386__)
+ GTEST_SKIP() << "architecture does not pass arguments in registers";
+#endif
+ int intercept_result;
+ unique_fd output_fd;
+ StartProcess([]() {
+ // Crash with a heap pointer in the first argument register.
+ Trap(malloc(1));
+ });
+
+ StartIntercept(&output_fd);
+ FinishCrasher();
+ int status;
+ ASSERT_EQ(crasher_pid, TIMEOUT(30, waitpid(crasher_pid, &status, 0)));
+ ASSERT_TRUE(WIFSIGNALED(status)) << "crasher didn't terminate via a signal";
+ // Don't test the signal number because different architectures use different signals for
+ // __builtin_trap().
+ FinishIntercept(&intercept_result);
+
+ ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
+
+ std::string result;
+ ConsumeFd(std::move(output_fd), &result);
+
+#if defined(__aarch64__)
+ ASSERT_MATCH(result, "memory near x0");
+#elif defined(__arm__)
+ ASSERT_MATCH(result, "memory near r0");
+#elif defined(__x86_64__)
+ ASSERT_MATCH(result, "memory near rdi");
+#else
+ ASSERT_TRUE(false) << "unsupported architecture";
+#endif
+}
+
#if defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
static void SetTagCheckingLevelSync() {
int tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);