aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorPeter Schauer <Peter.Schauer@mytum.de>1997-05-15 15:01:54 +0000
committerPeter Schauer <Peter.Schauer@mytum.de>1997-05-15 15:01:54 +0000
commit4cc56716560b564c7b7f27e5eae03f9366f7ecab (patch)
treea0d42de06cd329a04a3157f575434c3942bc0d55 /gdb
parent2ce0e027f4eaa476131b7588ec6ab87bb5a25793 (diff)
downloadgdb-4cc56716560b564c7b7f27e5eae03f9366f7ecab.zip
gdb-4cc56716560b564c7b7f27e5eae03f9366f7ecab.tar.gz
gdb-4cc56716560b564c7b7f27e5eae03f9366f7ecab.tar.bz2
* config/rs6000/tm-rs6000.h (SIG_FRAME_LR_OFFSET): Define.
* rs6000-tdep.c (frameless_function_invocation): Mark frames with a zero PC as frameless to improve backtraces from core dumps caused by dereferencing a NULL function pointer. (frameless_function_invocation, frame_saved_pc, rs6000_frame_chain): Handle frameless functions interrupted by a signal. * sparc-tdep.c (sparc_init_extra_frame_info, sparc_frame_saved_pc): Handle frameless functions interrupted by a signal.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog12
-rw-r--r--gdb/rs6000-tdep.c35
2 files changed, 40 insertions, 7 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1aa5fc8..8fdbff9 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,15 @@
+Thu May 15 07:56:50 1997 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
+
+ * config/rs6000/tm-rs6000.h (SIG_FRAME_LR_OFFSET): Define.
+ * rs6000-tdep.c (frameless_function_invocation): Mark frames
+ with a zero PC as frameless to improve backtraces from core dumps
+ caused by dereferencing a NULL function pointer.
+ (frameless_function_invocation, frame_saved_pc, rs6000_frame_chain):
+ Handle frameless functions interrupted by a signal.
+
+ * sparc-tdep.c (sparc_init_extra_frame_info, sparc_frame_saved_pc):
+ Handle frameless functions interrupted by a signal.
+
Wed May 14 08:58:55 1997 Jeffrey A Law (law@cygnus.com)
* mn10200-tdep.c (mn10200_analyze_prologue): Update prologue comments
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 5b616f5..d4b7659 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -947,20 +947,29 @@ frameless_function_invocation (fi)
CORE_ADDR func_start;
struct rs6000_framedata fdata;
- if (fi->next != NULL)
- /* Don't even think about framelessness except on the innermost frame. */
- /* FIXME: Can also be frameless if fi->next->signal_handler_caller (if
- a signal happens while executing in a frameless function). */
+ /* Don't even think about framelessness except on the innermost frame
+ or if the function was interrupted by a signal. */
+ if (fi->next != NULL && !fi->next->signal_handler_caller)
return 0;
- func_start = get_pc_function_start (fi->pc) + FUNCTION_START_OFFSET;
+ func_start = get_pc_function_start (fi->pc);
/* If we failed to find the start of the function, it is a mistake
to inspect the instructions. */
if (!func_start)
- return 0;
+ {
+ /* A frame with a zero PC is usually created by dereferencing a NULL
+ function pointer, normally causing an immediate core dump of the
+ inferior. Mark function as frameless, as the inferior has no chance
+ of setting up a stack frame. */
+ if (fi->pc == 0)
+ return 1;
+ else
+ return 0;
+ }
+ func_start += FUNCTION_START_OFFSET;
(void) skip_prologue (func_start, &fdata);
return fdata.frameless;
}
@@ -987,7 +996,13 @@ frame_saved_pc (fi)
(void) skip_prologue (func_start, &fdata);
if (fdata.lr_offset == 0 && fi->next != NULL)
- return read_memory_integer (rs6000_frame_chain (fi) + DEFAULT_LR_SAVE, 4);
+ {
+ if (fi->next->signal_handler_caller)
+ return read_memory_integer (fi->next->frame + SIG_FRAME_LR_OFFSET, 4);
+ else
+ return read_memory_integer (rs6000_frame_chain (fi) + DEFAULT_LR_SAVE,
+ 4);
+ }
if (fdata.lr_offset == 0)
return read_register (LR_REGNUM);
@@ -1136,6 +1151,12 @@ rs6000_frame_chain (thisframe)
return 0;
if (thisframe->signal_handler_caller)
fp = read_memory_integer (thisframe->frame + SIG_FRAME_FP_OFFSET, 4);
+ else if (thisframe->next != NULL
+ && thisframe->next->signal_handler_caller
+ && frameless_function_invocation (thisframe))
+ /* A frameless function interrupted by a signal did not change the
+ frame pointer. */
+ fp = FRAME_FP (thisframe);
else
fp = read_memory_integer ((thisframe)->frame, 4);