am 6beca66f: am 3f94aa5f: am 51c4d4c4: Merge "AArch64: Port debuggerd"

* commit '6beca66f9ceaf5733ff5a4a00f1d272e42e871a2':
  AArch64: Port debuggerd
This commit is contained in:
Elliott Hughes 2014-01-31 23:11:20 +00:00 committed by Android Git Automerger
commit 033640c404
7 changed files with 220 additions and 7 deletions

View File

@ -1,7 +1,5 @@
# Copyright 2005 The Android Open Source Project
ifneq ($(filter arm mips x86 x86_64,$(TARGET_ARCH)),)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@ -60,12 +58,10 @@ ifeq ($(ARCH_ARM_HAVE_VFP_D32),true)
LOCAL_CFLAGS += -DWITH_VFP_D32
endif # ARCH_ARM_HAVE_VFP_D32
LOCAL_SRC_FILES := vfp-crasher.c vfp.S
LOCAL_SRC_FILES := vfp-crasher.c $(TARGET_ARCH)/vfp.S
LOCAL_MODULE := vfp-crasher
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES := libcutils liblog libc
include $(BUILD_EXECUTABLE)
endif # ARCH_ARM_HAVE_VFP == true
endif # arm or x86 in TARGET_ARCH

View File

@ -0,0 +1,47 @@
.globl crash1
.type crash1, %function
.globl crashnostack
.type crashnostack, %function
crash1:
ldr x0, =0xa5a50000
ldr x1, =0xa5a50001
ldr x2, =0xa5a50002
ldr x3, =0xa5a50003
ldr x4, =0xa5a50004
ldr x5, =0xa5a50005
ldr x6, =0xa5a50006
ldr x7, =0xa5a50007
ldr x8, =0xa5a50008
ldr x9, =0xa5a50009
ldr x10, =0xa5a50010
ldr x11, =0xa5a50011
ldr x12, =0xa5a50012
ldr x13, =0xa5a50013
ldr x14, =0xa5a50014
ldr x15, =0xa5a50015
ldr x16, =0xa5a50016
ldr x17, =0xa5a50017
ldr x18, =0xa5a50018
ldr x19, =0xa5a50019
ldr x20, =0xa5a50020
ldr x21, =0xa5a50021
ldr x22, =0xa5a50022
ldr x23, =0xa5a50023
ldr x24, =0xa5a50024
ldr x25, =0xa5a50025
ldr x26, =0xa5a50026
ldr x27, =0xa5a50027
ldr x28, =0xa5a50028
ldr x29, =0xa5a50029
mov x30, xzr
ldr x30, [x30]
b .
crashnostack:
mov x0, xzr
add sp, x0, xzr
ldr x0, [x0]
b .

123
debuggerd/arm64/machine.cpp Normal file
View File

@ -0,0 +1,123 @@
/*
*
* Copyright 2014, 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 <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/uio.h>
#include <linux/elf.h>
#include "../utility.h"
#include "../machine.h"
/* enable to dump memory pointed to by every register */
#define DUMP_MEMORY_FOR_ALL_REGISTERS 1
/*
* If configured to do so, dump memory around *all* registers
* for the crashing thread.
*/
void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
struct user_pt_regs regs;
struct iovec io;
io.iov_base = &regs;
io.iov_len = sizeof(regs);
if (ptrace(PTRACE_GETREGSET, tid, (void*)NT_PRSTATUS, &io) == -1) {
_LOG(log, scope_flags, "%s: ptrace failed to get registers: %s\n",
__func__, strerror(errno));
return;
}
if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
for (int reg = 0; reg < 31; reg++) {
uintptr_t addr = regs.regs[reg];
/*
* Don't bother if it looks like a small int or ~= null, or if
* it's in the kernel area.
*/
if (addr < 4096 || addr >= (1UL<<63)) {
continue;
}
_LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near x%d:\n", reg);
dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
}
}
_LOG(log, scope_flags, "\ncode around pc:\n");
dump_memory(log, tid, (uintptr_t)regs.pc, scope_flags);
if (regs.pc != regs.sp) {
_LOG(log, scope_flags, "\ncode around sp:\n");
dump_memory(log, tid, (uintptr_t)regs.sp, scope_flags);
}
}
void dump_registers(log_t* log, pid_t tid, int scope_flags)
{
struct user_pt_regs r;
struct iovec io;
io.iov_base = &r;
io.iov_len = sizeof(r);
bool only_in_tombstone = !IS_AT_FAULT(scope_flags);
if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRSTATUS, (void*) &io) == -1) {
_LOG(log, scope_flags, "ptrace error: %s\n", strerror(errno));
return;
}
for (int i = 0; i < 28; i += 4) {
_LOG(log, scope_flags, " x%-2d %016lx x%-2d %016lx x%-2d %016lx x%-2d %016lx\n",
i, (uint64_t)r.regs[i],
i+1, (uint64_t)r.regs[i+1],
i+2, (uint64_t)r.regs[i+2],
i+3, (uint64_t)r.regs[i+3]);
}
_LOG(log, scope_flags, " x28 %016lx x29 %016lx x30 %016lx\n",
(uint64_t)r.regs[28], (uint64_t)r.regs[29], (uint64_t)r.regs[30]);
_LOG(log, scope_flags, " sp %016lx pc %016lx\n",
(uint64_t)r.sp, (uint64_t)r.pc);
struct user_fpsimd_state f;
io.iov_base = &f;
io.iov_len = sizeof(f);
if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRFPREG, (void*) &io) == -1) {
_LOG(log, scope_flags, "ptrace error: %s\n", strerror(errno));
return;
}
for (int i = 0; i < 32; i += 4) {
_LOG(log, scope_flags, " v%-2d %016lx v%-2d %016lx v%-2d %016lx v%-2d %016lx\n",
i, (uint64_t)f.vregs[i],
i+1, (uint64_t)f.vregs[i+1],
i+2, (uint64_t)f.vregs[i+2],
i+3, (uint64_t)f.vregs[i+3]);
}
}

42
debuggerd/arm64/vfp.S Normal file
View File

@ -0,0 +1,42 @@
.text
.align 2
.global crash
.type crash, %function
crash:
fmov d0, XZR
fmov d1, 1.0
fmov d2, 2.0
fmov d3, 3.0
fmov d4, 4.0
fmov d5, 5.0
fmov d6, 6.0
fmov d7, 7.0
fmov d8, 8.0
fmov d9, 9.0
fmov d10, 10.0
fmov d11, 11.0
fmov d12, 12.0
fmov d13, 13.0
fmov d14, 14.0
fmov d15, 15.0
fmov d16, 16.0
fmov d17, 17.0
fmov d18, 18.0
fmov d19, 19.0
fmov d20, 20.0
fmov d21, 21.0
fmov d22, 22.0
fmov d23, 23.0
fmov d24, 24.0
fmov d25, 25.0
fmov d26, 26.0
fmov d27, 27.0
fmov d28, 28.0
fmov d29, 29.0
fmov d30, 30.0
fmov d31, 31.0
mov x0, xzr
str x0, [x0]
br x30

View File

@ -205,7 +205,8 @@ static int read_request(int fd, debugger_request_t* out_request) {
return -1;
}
if (status == sizeof(debugger_msg_t)) {
XLOG("crash request of size %d abort_msg_address=%#08x\n", status, msg.abort_msg_address);
XLOG("crash request of size %d abort_msg_address=0x%" PRIPTR "\n",
status, msg.abort_msg_address);
} else {
LOG("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid);
return -1;

View File

@ -360,7 +360,7 @@ static void dump_nearby_maps(BacktraceMap* map, log_t* log, pid_t tid, int scope
return;
}
_LOG(log, scope_flags, "\nmemory map around fault addr %" PRIxPTR ":\n",
_LOG(log, scope_flags, "\nmemory map around fault addr %" PRIPTR ":\n",
reinterpret_cast<uintptr_t>(si.si_addr));
// Search for a match, or for a hole where the match would be. The list
@ -647,7 +647,11 @@ static bool dump_crash(log_t* log, pid_t pid, pid_t tid, int signal, uintptr_t a
//
// Returns the path of the tombstone file, allocated using malloc(). Caller must free() it.
static char* find_and_open_tombstone(int* fd) {
#ifdef __aarch64__
long mtime = LONG_MAX;
#else
unsigned long mtime = ULONG_MAX;
#endif
struct stat sb;
// XXX: Our stat.st_mtime isn't time_t. If it changes, as it probably ought