@@ -75,6 +75,7 @@ int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
void
sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
{
+ struct thread_info *ti;
struct pt_regs *thread_regs;
int regno;
@@ -86,24 +87,34 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
for (regno = 0; regno < GDB_MAX_REGS; regno++)
gdb_regs[regno] = 0;
- /* Otherwise, we have only some registers from switch_to() */
+ /*
+ * Try to get as much as we can from the thread_info since the
+ * pt_regs structure doesn't seem right in most cases.
+ */
+ ti = task_thread_info(task);
+ gdb_regs[_R4] = ti->cpu_context.r4;
+ gdb_regs[_R5] = ti->cpu_context.r5;
+ gdb_regs[_R6] = ti->cpu_context.r6;
+ gdb_regs[_R7] = ti->cpu_context.r7;
+ gdb_regs[_R8] = ti->cpu_context.r8;
+ gdb_regs[_R9] = ti->cpu_context.r9;
+ gdb_regs[_R10] = ti->cpu_context.sl;
+ gdb_regs[_FP] = ti->cpu_context.fp;
+ gdb_regs[_SPT] = ti->cpu_context.sp;
+ gdb_regs[_PC] = ti->cpu_context.pc;
+
+ /*
+ * task_thread_info() doesn't store callee-saved registers so we'll
+ * give task_pt_regs() a shot here. I've never actually seen that be
+ * valid, though
+ */
thread_regs = task_pt_regs(task);
gdb_regs[_R0] = thread_regs->ARM_r0;
gdb_regs[_R1] = thread_regs->ARM_r1;
gdb_regs[_R2] = thread_regs->ARM_r2;
gdb_regs[_R3] = thread_regs->ARM_r3;
- gdb_regs[_R4] = thread_regs->ARM_r4;
- gdb_regs[_R5] = thread_regs->ARM_r5;
- gdb_regs[_R6] = thread_regs->ARM_r6;
- gdb_regs[_R7] = thread_regs->ARM_r7;
- gdb_regs[_R8] = thread_regs->ARM_r8;
- gdb_regs[_R9] = thread_regs->ARM_r9;
- gdb_regs[_R10] = thread_regs->ARM_r10;
- gdb_regs[_FP] = thread_regs->ARM_fp;
gdb_regs[_IP] = thread_regs->ARM_ip;
- gdb_regs[_SPT] = thread_regs->ARM_sp;
gdb_regs[_LR] = thread_regs->ARM_lr;
- gdb_regs[_PC] = thread_regs->ARM_pc;
gdb_regs[_CPSR] = thread_regs->ARM_cpsr;
}
Dumping registers from other sleeping tasks in KGDB was totally failing for me. All registers were reported as 0. It looks as if the code was looking at at "task_pt_regs(task)" for the sleeping task and they were all 0. I'm not exactly sure why this structure was used and why it wasn't filled in. There is a more reliable place to look for all of the important registers for a sleeping task: the task_thread_info. This is the same place that is referred to when doing a dump of all sleeping task stacks (kdb_show_stack() -> show_stack() -> dump_backtrace() -> unwind_backtrace() -> thread_saved_sp()). Let's use the more reliable place for all registers that are saved there. We'll fall back to the task_pt_regs() for registers that we don't have. Signed-off-by: Doug Anderson <dianders@chromium.org> --- arch/arm/kernel/kgdb.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-)