commit ddc49fb123fbca081091847a8f0f7a66475518b8 Author: Joel Brobecker Date: Wed Sep 9 22:09:53 2009 -0400 * stack.c (frame_info): Do not try to print the location of the saved registers for frames that have a NULL frame ID. diff --git a/gdb/stack.c b/gdb/stack.c index 1c37801..99459fe 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -986,6 +986,7 @@ static void frame_info (char *addr_exp, int from_tty) { struct frame_info *fi; + int outer_frame_p; struct symtab_and_line sal; struct symbol *func; struct symtab *s; @@ -1001,6 +1002,16 @@ frame_info (char *addr_exp, int from_tty) fi = parse_frame_specification_1 (addr_exp, "No stack.", &selected_frame_p); gdbarch = get_frame_arch (fi); + /* The outer frame may have a null frame ID. This can happen when + to a program that is stopped at the entry point, for instance. + We have to be careful of this case, because we cannot unwind registers + unless we have a valid frame ID. + + FIXME: brobecker/2009-09-09: This distinction is necessary only + because the unwinding machinery does not have a way to distinguish + null frames from outer frames. If we fix that, we should be able + to get rid of this check and all the associated code that uses it. */ + outer_frame_p = !frame_id_p (get_frame_id (fi)); /* Name of the value returned by get_frame_pc(). Per comments, "pc" is not a good name. */ if (gdbarch_pc_regnum (gdbarch) >= 0) @@ -1077,9 +1088,15 @@ frame_info (char *addr_exp, int from_tty) if (sal.symtab) printf_filtered (" (%s:%d)", sal.symtab->filename, sal.line); puts_filtered ("; "); - wrap_here (" "); - printf_filtered ("saved %s ", pc_regname); - fputs_filtered (paddress (gdbarch, frame_unwind_caller_pc (fi)), gdb_stdout); + if (!outer_frame_p) + { + /* This is the outer frame: None of the registers have been saved. + So do not try to print the address were the PC has been saved. */ + wrap_here (" "); + printf_filtered ("saved %s ", pc_regname); + fputs_filtered (paddress (gdbarch, frame_unwind_caller_pc (fi)), + gdb_stdout); + } printf_filtered ("\n"); if (calling_frame_info == NULL) @@ -1175,6 +1192,18 @@ frame_info (char *addr_exp, int from_tty) int i; int need_nl = 1; + /* We need to be careful with the outer frame which has a null + frame ID, as most of the register unwinding routines assume + a non-null frame ID. We know that there are no saved register + at this point of the execution anyway, so just report this to + the user and return. */ + if (outer_frame_p) + { + printf_filtered (" no saved registers.\n"); + do_cleanups (back_to); + return; + } + /* The sp is special; what's displayed isn't the save address, but the value of the previous frame's sp. This is a legacy thing, at one stage the frame cached the previous frame's SP instead