This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [RFA]: Add IN_EPILOGUE() predicate
- To: gdb-patches <gdb-patches at sources dot redhat dot com>
- Subject: Re: [RFA]: Add IN_EPILOGUE() predicate
- From: Corinna Vinschen <vinschen at redhat dot com>
- Date: Fri, 2 Nov 2001 11:29:18 +0100
- References: <20011101170645.B31655@cygbert.vinschen.de> <3BE21383.7040506@cygnus.com>
- Reply-To: gdb-patches <gdb-patches at sources dot redhat dot com>
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.
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 10:27:21
@@ -111,6 +111,12 @@ generic_in_solib_call_trampoline (CORE_A
return 0;
}
+int
+generic_in_function_epilogue_p (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 10:27:21
@@ -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 (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 10:27:25
@@ -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 10:27:29
@@ -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
}