This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [RFA]: Add IN_EPILOGUE() predicate
On Fri, Nov 02, 2001 at 11:29:18AM +0100, Corinna Vinschen wrote:
> On Thu, Nov 01, 2001 at 10:31:15PM -0500, Andrew Cagney wrote:
> > Regarding multi-arch, since this is a new architecture method it should
> > be ``m'' rather than ``f''. (This will mean that only multi-arch
> > targets are able to exploit this mechanism which in turn provides an
> > incentive for non-multi-arch targets to get their act together :-). Can
> > I also suggest calling it IN_FUNCTION_EPILOGUE_P()? While more of a
> > keyboard-full it has a clearer meaning.
> >
> > Anyway, the real change (breakpoint.c) is a question for MichaelS.
> >
> > enjoy,
> > Andrew
> >
> > PS: An entry for doc/gdbint.texi would also be helpful.
>
> Thanks for looking into it. The below changed patch considers the
> above hints. However, while changing IN_FUNCTION_EPILOGUE_P() into
> a full multi-arched function, the IN_FUNCTION_EPILOGUE_P macro got
> lost. Therefore I'm now calling gdbarch_in_function_epilogue_p()
> in the watchpoint_check() function.
>
> That's no problem but... now I don't find the correct place to document
> the new functionality. gdbinit.texinfo contains a list of all the
> macros but there don't seem to be a list of full multi-arched functions.
> If we hadn't lost the above macro, I would have added the following
> words:
>
> @item IN_FUNCTION_EPILOGUE_P (@var{pc})
> @findex IN_FUNCTION_EPILOGUE_P
> Returns non-zero if the given @var{pc} is in the epilogue of a function.
> The epilogue of a function is defined as the part of a function where
> the stack frame of the function already has been destroyed up to the
> final `return from function call' instruction.
>
> Corinna
>
> 2001-11-01 Corinna Vinschen <vinschen@redhat.com>
>
> * arch-utils.c (generic_in_function_epilogue_p): New function.
> * arch-utils.h (generic_in_function_epilogue_p): Declare extern.
> * breakpoint.c (watchpoint_check): Add test whether the pc is
> currently in the epilogue of a function.
> * gdbarch.c: Autogenerated from gdbarch.sh.
> * gdbarch.h: Ditto.
> * gdbarch.sh (function_list): Add `in_function_epilogue_p' definition.
Sorry, the previous patch was a quick shot. I didn't change
generic_in_function_epilogue_p() in arch-utils.[ch] to have
a struct gdbarch * as first argument. Corrected patch attached.
Corinna
Index: arch-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.c,v
retrieving revision 1.37
diff -u -p -r1.37 arch-utils.c
--- arch-utils.c 2001/10/31 23:21:33 1.37
+++ arch-utils.c 2001/11/02 11:04:26
@@ -111,6 +111,12 @@ generic_in_solib_call_trampoline (CORE_A
return 0;
}
+int
+generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+ return 0;
+}
+
char *
legacy_register_name (int i)
{
Index: arch-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/arch-utils.h,v
retrieving revision 1.22
diff -u -p -r1.22 arch-utils.h
--- arch-utils.h 2001/10/31 23:21:33 1.22
+++ arch-utils.h 2001/11/02 11:04:26
@@ -134,4 +134,6 @@ extern CORE_ADDR generic_skip_trampoline
extern int generic_in_solib_call_trampoline (CORE_ADDR pc, char *name);
+extern int generic_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc);
+
#endif
Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.55
diff -u -p -r1.55 breakpoint.c
--- breakpoint.c 2001/10/20 23:54:29 1.55
+++ breakpoint.c 2001/11/02 11:04:30
@@ -2308,6 +2308,14 @@ watchpoint_check (PTR p)
reinit_frame_cache ();
fr = find_frame_addr_in_frame_chain (b->watchpoint_frame);
within_current_scope = (fr != NULL);
+ /* in_function_epilogue_p() returns a non-zero value if we're still
+ in the function but the stack frame has already been invalidated.
+ Since we can't rely on the values of local variables after the
+ stack has been destroyed, we are treating the watchpoint in that
+ state as `not changed' without further checking. */
+ if (within_current_scope && fr == get_current_frame ()
+ && gdbarch_in_function_epilogue_p (current_gdbarch, read_pc ()))
+ return WP_VALUE_NOT_CHANGED;
if (within_current_scope)
/* If we end up stopping, the current frame will get selected
in normal_stop. So this call to select_frame won't affect
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.84
diff -u -p -r1.84 gdbarch.sh
--- gdbarch.sh 2001/10/31 23:21:33 1.84
+++ gdbarch.sh 2001/11/02 11:04:33
@@ -546,6 +546,16 @@ f:2:SKIP_TRAMPOLINE_CODE:CORE_ADDR:skip_
# trampoline code in the ".plt" section. IN_SOLIB_CALL_TRAMPOLINE evaluates
# to nonzero if we are current stopped in one of these.
f:2:IN_SOLIB_CALL_TRAMPOLINE:int:in_solib_call_trampoline:CORE_ADDR pc, char *name:pc, name:::generic_in_solib_call_trampoline::0
+# A target might have problems with watchpoints as soon as the stack
+# frame of the current function has been destroyed. This mostly happens
+# as the first action in a funtion's epilogue. in_function_epilogue_p()
+# is defined to return a non-zero value if either the given addr is one
+# instruction after the stack destroying instruction up to the trailing
+# return instruction or if we can figure out that the stack frame has
+# already been invalidated regardless of the value of addr. Targets
+# which don't suffer from that problem could just let this functionality
+# untouched.
+m:::int:in_function_epilogue_p:CORE_ADDR addr:addr::0:generic_in_function_epilogue_p::0
EOF
}