Skip to content

Commit af7c3d5

Browse files
pccGerrit Code Review
authored and
Gerrit Code Review
committed
Merge "Fix dumping of heap memory."
2 parents 4aa0733 + 10e428d commit af7c3d5

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

debuggerd/debuggerd_test.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ class CrasherTest : public ::testing::Test {
172172
void StartCrasher(const std::string& crash_type);
173173
void FinishCrasher();
174174
void AssertDeath(int signo);
175+
176+
static void Trap(void* ptr);
175177
};
176178

177179
CrasherTest::CrasherTest() {
@@ -334,6 +336,48 @@ TEST_F(CrasherTest, tagged_fault_addr) {
334336
R"(signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr (0x100000000000dead|0xdead))");
335337
}
336338

339+
// Marked as weak to prevent the compiler from removing the malloc in the caller. In theory, the
340+
// compiler could still clobber the argument register before trapping, but that's unlikely.
341+
__attribute__((weak)) void CrasherTest::Trap(void* ptr ATTRIBUTE_UNUSED) {
342+
__builtin_trap();
343+
}
344+
345+
TEST_F(CrasherTest, heap_addr_in_register) {
346+
#if defined(__i386__)
347+
GTEST_SKIP() << "architecture does not pass arguments in registers";
348+
#endif
349+
int intercept_result;
350+
unique_fd output_fd;
351+
StartProcess([]() {
352+
// Crash with a heap pointer in the first argument register.
353+
Trap(malloc(1));
354+
});
355+
356+
StartIntercept(&output_fd);
357+
FinishCrasher();
358+
int status;
359+
ASSERT_EQ(crasher_pid, TIMEOUT(30, waitpid(crasher_pid, &status, 0)));
360+
ASSERT_TRUE(WIFSIGNALED(status)) << "crasher didn't terminate via a signal";
361+
// Don't test the signal number because different architectures use different signals for
362+
// __builtin_trap().
363+
FinishIntercept(&intercept_result);
364+
365+
ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
366+
367+
std::string result;
368+
ConsumeFd(std::move(output_fd), &result);
369+
370+
#if defined(__aarch64__)
371+
ASSERT_MATCH(result, "memory near x0");
372+
#elif defined(__arm__)
373+
ASSERT_MATCH(result, "memory near r0");
374+
#elif defined(__x86_64__)
375+
ASSERT_MATCH(result, "memory near rdi");
376+
#else
377+
ASSERT_TRUE(false) << "unsupported architecture";
378+
#endif
379+
}
380+
337381
#if defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
338382
static void SetTagCheckingLevelSync() {
339383
int tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);

debuggerd/libdebuggerd/utility.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const s
135135
addr -= 32;
136136
}
137137

138+
// We don't want the address tag to interfere with the bounds check below or appear in the
139+
// addresses in the memory dump.
140+
addr = untag_address(addr);
141+
138142
// Don't bother if the address looks too low, or looks too high.
139143
if (addr < 4096 ||
140144
#if defined(__LP64__)

0 commit comments

Comments
 (0)