summaryrefslogtreecommitdiffstats
path: root/debuggerd
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:08:08 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:08:08 -0800
commit35237d135807af84bf9b0e5b8d7f8633e58db6f5 (patch)
treed8bcf3ada2182d248604728285dd80abb466f22a /debuggerd
parent4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53 (diff)
downloadsystem_core-35237d135807af84bf9b0e5b8d7f8633e58db6f5.zip
system_core-35237d135807af84bf9b0e5b8d7f8633e58db6f5.tar.gz
system_core-35237d135807af84bf9b0e5b8d7f8633e58db6f5.tar.bz2
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'debuggerd')
-rw-r--r--debuggerd/Android.mk4
-rw-r--r--debuggerd/unwind-arm.c50
-rw-r--r--debuggerd/utility.c7
-rw-r--r--debuggerd/utility.h2
4 files changed, 54 insertions, 9 deletions
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index 03046bd..b22e1a8 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -1,5 +1,7 @@
# Copyright 2005 The Android Open Source Project
+ifeq ($(TARGET_ARCH),arm)
+
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
@@ -20,3 +22,5 @@ LOCAL_MODULE_TAGS := eng
#LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_SHARED_LIBRARIES := libcutils libc
include $(BUILD_EXECUTABLE)
+
+endif # TARGET_ARCH == arm
diff --git a/debuggerd/unwind-arm.c b/debuggerd/unwind-arm.c
index fdc0a6a..9642d2e 100644
--- a/debuggerd/unwind-arm.c
+++ b/debuggerd/unwind-arm.c
@@ -381,13 +381,15 @@ get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address, pid_t pid,
}
/* Print out the current call level, pc, and module name in the crash log */
-static _Unwind_Reason_Code log_function(_Unwind_Context *context, int tfd,
+static _Unwind_Reason_Code log_function(_Unwind_Context *context, pid_t pid,
+ int tfd,
int stack_level,
mapinfo *map,
unsigned int sp_list[],
bool at_fault)
{
_uw pc;
+ _uw rel_pc;
phase2_vrs *vrs = (phase2_vrs*) context;
const mapinfo *mi;
bool only_in_tombstone = !at_fault;
@@ -404,19 +406,53 @@ static _Unwind_Reason_Code log_function(_Unwind_Context *context, int tfd,
// For deeper framers, rollback pc by one instruction
else {
pc = vrs->core.r[R_PC];
- // Thumb mode
+ /* Thumb mode - need to check whether the bl(x) has long offset or not.
+ * Examples:
+ *
+ * arm blx in the middle of thumb:
+ * 187ae: 2300 movs r3, #0
+ * 187b0: f7fe ee1c blx 173ec
+ * 187b4: 2c00 cmp r4, #0
+ *
+ * arm bl in the middle of thumb:
+ * 187d8: 1c20 adds r0, r4, #0
+ * 187da: f136 fd15 bl 14f208
+ * 187de: 2800 cmp r0, #0
+ *
+ * pure thumb:
+ * 18894: 189b adds r3, r3, r2
+ * 18896: 4798 blx r3
+ * 18898: b001 add sp, #4
+ */
if (pc & 1) {
- pc = (pc & ~1) - 2;
+ _uw prev_word;
+ pc = (pc & ~1);
+ prev_word = get_remote_word(pid, (void *) pc-4);
+ // Long offset
+ if ((prev_word & 0xf0000000) == 0xf0000000 &&
+ (prev_word & 0x0000e000) == 0x0000e000) {
+ pc -= 4;
+ }
+ else {
+ pc -= 2;
+ }
}
else {
pc -= 4;
}
}
- mi = pc_to_mapinfo(map, pc);
+ /* We used to print the absolute PC in the back trace, and mask out the top
+ * 3 bits to guesstimate the offset in the .so file. This is not working for
+ * non-prelinked libraries since the starting offset may not be aligned on
+ * 1MB boundaries, and the library may be larger than 1MB. So for .so
+ * addresses we print the relative offset in back trace.
+ */
+ rel_pc = pc;
+ mi = pc_to_mapinfo(map, pc, &rel_pc);
_LOG(tfd, only_in_tombstone,
- " #%02d pc %08x %s\n", stack_level, pc,
+ " #%02d pc %08x %s\n", stack_level, rel_pc,
mi ? mi->name : "");
return _URC_NO_REASON;
@@ -459,7 +495,7 @@ int unwind_backtrace_with_ptrace(int tfd, pid_t pid, mapinfo *map,
*/
if (get_eitp(saved_vrs.core.r[R_PC], pid, map, NULL) == NULL) {
*frame0_pc_sane = 0;
- log_function ((_Unwind_Context *) &saved_vrs, tfd, stack_level,
+ log_function ((_Unwind_Context *) &saved_vrs, pid, tfd, stack_level,
map, sp_list, at_fault);
saved_vrs.core.r[R_PC] = saved_vrs.core.r[R_LR];
stack_level++;
@@ -493,7 +529,7 @@ int unwind_backtrace_with_ptrace(int tfd, pid_t pid, mapinfo *map,
_Unwind_SetGR((_Unwind_Context *)&saved_vrs, 12, (_Unwind_Ptr) ucbp);
/* Call log function. */
- if (log_function ((_Unwind_Context *) &saved_vrs, tfd, stack_level,
+ if (log_function ((_Unwind_Context *) &saved_vrs, pid, tfd, stack_level,
map, sp_list, at_fault) != _URC_NO_REASON) {
code = _URC_FAILURE;
break;
diff --git a/debuggerd/utility.c b/debuggerd/utility.c
index 0cb790f..8f3931c 100644
--- a/debuggerd/utility.c
+++ b/debuggerd/utility.c
@@ -18,6 +18,7 @@
#include <sys/ptrace.h>
#include <sys/exec_elf.h>
#include <assert.h>
+#include <string.h>
#include <errno.h>
#include "utility.h"
@@ -66,10 +67,14 @@ const char *map_to_name(mapinfo *mi, unsigned pc, const char* def)
}
/* Find the containing map info for the pc */
-const mapinfo *pc_to_mapinfo(mapinfo *mi, unsigned pc)
+const mapinfo *pc_to_mapinfo(mapinfo *mi, unsigned pc, unsigned *rel_pc)
{
while(mi) {
if((pc >= mi->start) && (pc < mi->end)){
+ // Only calculate the relative offset for shared libraries
+ if (strstr(mi->name, ".so")) {
+ *rel_pc = pc - mi->start;
+ }
return mi;
}
mi = mi->next;
diff --git a/debuggerd/utility.h b/debuggerd/utility.h
index 802e3ad..49f5951 100644
--- a/debuggerd/utility.h
+++ b/debuggerd/utility.h
@@ -45,7 +45,7 @@ extern int get_remote_word(int pid, void *src);
extern void get_remote_struct(int pid, void *src, void *dst, size_t size);
/* Find the containing map for the pc */
-const mapinfo *pc_to_mapinfo (mapinfo *mi, unsigned pc);
+const mapinfo *pc_to_mapinfo (mapinfo *mi, unsigned pc, unsigned *rel_pc);
/* Map a pc address to the name of the containing ELF file */
const char *map_to_name(mapinfo *mi, unsigned pc, const char* def);