From b7202faa33b382da19f2abf4b306ebdff3b69f8b Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Sun, 11 Jun 1995 00:03:02 +0000 Subject: [PATCH] * hppa-tdep.c (frame_chain): Try to compensate for incomplete register information in core files when backtracing. --- gdb/ChangeLog | 10 ++++++++ gdb/hppa-tdep.c | 63 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 82a66a8d0a2..72fd7041b1f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +Sat Jun 10 17:59:11 1995 Jeff Law (law@snake.cs.utah.edu) + + * hppa-tdep.c (frame_chain): Try to compensate for incomplete + register information in core files when backtracing. + +Fri Jun 9 14:51:38 1995 Stu Grossman (grossman@cygnus.com) + + * remote-nrom.c: Remove everything but download code. More + cleanups. + Thu Jun 8 15:06:00 1995 Stu Grossman (grossman@cygnus.com) * defs.h maint.c monitor.c remote-mips.c remote.c: Add support diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index d5595dcf7c8..a0f582c81c1 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -955,6 +955,7 @@ frame_chain (frame) int my_framesize, caller_framesize; struct unwind_table_entry *u; CORE_ADDR frame_base; + struct frame_info *tmp_frame; /* Handle HPUX, BSD, and OSF1 style interrupt frames first. These are easy; at *sp we have a full save state strucutre which we can @@ -1003,9 +1004,10 @@ frame_chain (frame) We use information from unwind descriptors to determine if %r3 is saved into the stack (Entry_GR field has this information). */ - while (frame) + tmp_frame = frame; + while (tmp_frame) { - u = find_unwind_entry (frame->pc); + u = find_unwind_entry (tmp_frame->pc); if (!u) { @@ -1013,34 +1015,73 @@ frame_chain (frame) think anyone has actually written any tools (not even "strip") which leave them out of an executable, so maybe this is a moot point. */ - warning ("Unable to find unwind for PC 0x%x -- Help!", frame->pc); + warning ("Unable to find unwind for PC 0x%x -- Help!", tmp_frame->pc); return 0; } /* Entry_GR specifies the number of callee-saved general registers saved in the stack. It starts at %r3, so %r3 would be 1. */ if (u->Entry_GR >= 1 || u->Save_SP - || frame->signal_handler_caller - || pc_in_interrupt_handler (frame->pc)) + || tmp_frame->signal_handler_caller + || pc_in_interrupt_handler (tmp_frame->pc)) break; else - frame = frame->next; + tmp_frame = tmp_frame->next; } - if (frame) + if (tmp_frame) { /* We may have walked down the chain into a function with a frame pointer. */ if (u->Save_SP - && !frame->signal_handler_caller - && !pc_in_interrupt_handler (frame->pc)) - return read_memory_integer (frame->frame, 4); + && !tmp_frame->signal_handler_caller + && !pc_in_interrupt_handler (tmp_frame->pc)) + return read_memory_integer (tmp_frame->frame, 4); /* %r3 was saved somewhere in the stack. Dig it out. */ else { struct frame_saved_regs saved_regs; - get_frame_saved_regs (frame, &saved_regs); + /* Sick. + + For optimization purposes many kernels don't have the + callee saved registers into the save_state structure upon + entry into the kernel for a syscall; the optimization + is usually turned off if the process is being traced so + that the debugger can get full register state for the + process. + + This scheme works well except for two cases: + + * Attaching to a process when the process is in the + kernel performing a system call (debugger can't get + full register state for the inferior process since + the process wasn't being traced when it entered the + system call). + + * Register state is not complete if the system call + causes the process to core dump. + + + The following heinous code is an attempt to deal with + the lack of register state in a core dump. It will + fail miserably if the function which performs the + system call has a variable sized stack frame. */ + + get_frame_saved_regs (tmp_frame, &saved_regs); + + /* Abominable hack. */ + if (current_target.to_has_execution == 0 + && saved_regs.regs[FLAGS_REGNUM] + && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4) & 0x2)) + { + u = find_unwind_entry (FRAME_SAVED_PC (frame)); + if (!u) + return read_memory_integer (saved_regs.regs[FP_REGNUM], 4); + else + return frame_base - (u->Total_frame_size << 3); + } + return read_memory_integer (saved_regs.regs[FP_REGNUM], 4); } } -- 2.30.2