This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [RFA]: Add IN_EPILOGUE() predicate


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
 }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]