am 51c4d4c4: Merge "AArch64: Port debuggerd"
* commit '51c4d4c431dbbabe6db1cea5bb21822c69b7546c': AArch64: Port debuggerd
This commit is contained in:
commit
3f94aa5fbb
7 changed files with 220 additions and 7 deletions
|
|
@ -1,7 +1,5 @@
|
||||||
# Copyright 2005 The Android Open Source Project
|
# Copyright 2005 The Android Open Source Project
|
||||||
|
|
||||||
ifneq ($(filter arm mips x86 x86_64,$(TARGET_ARCH)),)
|
|
||||||
|
|
||||||
LOCAL_PATH:= $(call my-dir)
|
LOCAL_PATH:= $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
|
@ -60,12 +58,10 @@ ifeq ($(ARCH_ARM_HAVE_VFP_D32),true)
|
||||||
LOCAL_CFLAGS += -DWITH_VFP_D32
|
LOCAL_CFLAGS += -DWITH_VFP_D32
|
||||||
endif # ARCH_ARM_HAVE_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 := vfp-crasher
|
||||||
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
|
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
|
||||||
LOCAL_MODULE_TAGS := optional
|
LOCAL_MODULE_TAGS := optional
|
||||||
LOCAL_SHARED_LIBRARIES := libcutils liblog libc
|
LOCAL_SHARED_LIBRARIES := libcutils liblog libc
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
endif # ARCH_ARM_HAVE_VFP == true
|
endif # ARCH_ARM_HAVE_VFP == true
|
||||||
|
|
||||||
endif # arm or x86 in TARGET_ARCH
|
|
||||||
|
|
|
||||||
47
debuggerd/arm64/crashglue.S
Normal file
47
debuggerd/arm64/crashglue.S
Normal 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
123
debuggerd/arm64/machine.cpp
Normal 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 = ®s;
|
||||||
|
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
42
debuggerd/arm64/vfp.S
Normal 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
|
||||||
|
|
||||||
|
|
@ -205,7 +205,8 @@ static int read_request(int fd, debugger_request_t* out_request) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (status == sizeof(debugger_msg_t)) {
|
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 {
|
} else {
|
||||||
LOG("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid);
|
LOG("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
||||||
|
|
@ -360,7 +360,7 @@ static void dump_nearby_maps(BacktraceMap* map, log_t* log, pid_t tid, int scope
|
||||||
return;
|
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));
|
reinterpret_cast<uintptr_t>(si.si_addr));
|
||||||
|
|
||||||
// Search for a match, or for a hole where the match would be. The list
|
// Search for a match, or for a hole where the match would be. The list
|
||||||
|
|
@ -653,7 +653,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.
|
// Returns the path of the tombstone file, allocated using malloc(). Caller must free() it.
|
||||||
static char* find_and_open_tombstone(int* fd) {
|
static char* find_and_open_tombstone(int* fd) {
|
||||||
|
#ifdef __aarch64__
|
||||||
|
long mtime = LONG_MAX;
|
||||||
|
#else
|
||||||
unsigned long mtime = ULONG_MAX;
|
unsigned long mtime = ULONG_MAX;
|
||||||
|
#endif
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
// XXX: Our stat.st_mtime isn't time_t. If it changes, as it probably ought
|
// XXX: Our stat.st_mtime isn't time_t. If it changes, as it probably ought
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue