summaryrefslogtreecommitdiffstats
path: root/debuggerd/debuggerd.c
diff options
context:
space:
mode:
Diffstat (limited to 'debuggerd/debuggerd.c')
-rw-r--r--debuggerd/debuggerd.c66
1 files changed, 42 insertions, 24 deletions
diff --git a/debuggerd/debuggerd.c b/debuggerd/debuggerd.c
index 02bab2c..3b2972a 100644
--- a/debuggerd/debuggerd.c
+++ b/debuggerd/debuggerd.c
@@ -42,6 +42,14 @@
#include "utility.h"
+#ifdef WITH_VFP
+#ifdef WITH_VFP_D32
+#define NUM_VFP_REGS 32
+#else
+#define NUM_VFP_REGS 16
+#endif
+#endif
+
/* Main entry point to get the backtrace from the crashing process */
extern int unwind_backtrace_with_ptrace(int tfd, pid_t pid, mapinfo *map,
unsigned int sp_list[],
@@ -121,7 +129,7 @@ void dump_build_info(int tfd)
void dump_stack_and_code(int tfd, int pid, mapinfo *map,
int unwind_depth, unsigned int sp_list[],
- int frame0_pc_sane, bool at_fault)
+ bool at_fault)
{
unsigned int sp, pc, p, end, data;
struct pt_regs r;
@@ -133,19 +141,11 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map,
sp = r.ARM_sp;
pc = r.ARM_pc;
- /* Died because calling the weeds - dump
- * the code around the PC in the next frame instead.
- */
- if (frame0_pc_sane == 0) {
- pc = r.ARM_lr;
- }
-
- _LOG(tfd, only_in_tombstone,
- "\ncode around %s:\n", frame0_pc_sane ? "pc" : "lr");
+ _LOG(tfd, only_in_tombstone, "\ncode around pc:\n");
end = p = pc & ~3;
- p -= 16;
- end += 16;
+ p -= 32;
+ end += 32;
/* Dump the code around PC as:
* addr contents
@@ -164,12 +164,12 @@ void dump_stack_and_code(int tfd, int pid, mapinfo *map,
_LOG(tfd, only_in_tombstone, "%s\n", code_buffer);
}
- if (frame0_pc_sane) {
+ if ((unsigned) r.ARM_lr != pc) {
_LOG(tfd, only_in_tombstone, "\ncode around lr:\n");
end = p = r.ARM_lr & ~3;
- p -= 16;
- end += 16;
+ p -= 32;
+ end += 32;
/* Dump the code around LR as:
* addr contents
@@ -286,6 +286,24 @@ void dump_registers(int tfd, int pid, bool at_fault)
_LOG(tfd, only_in_tombstone,
" ip %08x sp %08x lr %08x pc %08x cpsr %08x\n",
r.ARM_ip, r.ARM_sp, r.ARM_lr, r.ARM_pc, r.ARM_cpsr);
+
+#ifdef WITH_VFP
+ struct user_vfp vfp_regs;
+ int i;
+
+ if(ptrace(PTRACE_GETVFPREGS, pid, 0, &vfp_regs)) {
+ _LOG(tfd, only_in_tombstone,
+ "cannot get registers: %s\n", strerror(errno));
+ return;
+ }
+
+ for (i = 0; i < NUM_VFP_REGS; i += 2) {
+ _LOG(tfd, only_in_tombstone,
+ " d%-2d %016llx d%-2d %016llx\n",
+ i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]);
+ }
+ _LOG(tfd, only_in_tombstone, " scr %08lx\n\n", vfp_regs.fpscr);
+#endif
}
const char *get_signame(int sig)
@@ -421,8 +439,7 @@ void dump_crash_report(int tfd, unsigned pid, unsigned tid, bool at_fault)
dump_pc_and_lr(tfd, tid, milist, stack_depth, at_fault);
}
- dump_stack_and_code(tfd, tid, milist, stack_depth, sp_list, frame0_pc_sane,
- at_fault);
+ dump_stack_and_code(tfd, tid, milist, stack_depth, sp_list, at_fault);
while(milist) {
mapinfo *next = milist->next;
@@ -611,15 +628,16 @@ static void wait_for_user_action(unsigned tid, struct ucred* cr)
(void)tid;
/* First log a helpful message */
LOG( "********************************************************\n"
- "* process %d crashed. debuggerd waiting for gdbserver \n"
- "* \n"
- "* adb shell gdbserver :port --attach %d & \n"
- "* \n"
- "* and press the HOME key. \n"
+ "* Process %d has been suspended while crashing. To\n"
+ "* attach gdbserver for a gdb connection on port 5039:\n"
+ "*\n"
+ "* adb shell gdbserver :5039 --attach %d &\n"
+ "*\n"
+ "* Press HOME key to let the process continue crashing.\n"
"********************************************************\n",
cr->pid, cr->pid);
- /* wait for HOME key */
+ /* wait for HOME key (TODO: something useful for devices w/o HOME key) */
if (init_getevent() == 0) {
int ms = 1200 / 10;
int dit = 1;
@@ -703,7 +721,7 @@ static void handle_crashing_process(int fd)
sprintf(buf,"/proc/%d/task/%d", cr.pid, tid);
if(stat(buf, &s)) {
- LOG("tid %d does not exist in pid %d. ignorning debug request\n",
+ LOG("tid %d does not exist in pid %d. ignoring debug request\n",
tid, cr.pid);
close(fd);
return;