This is the mail archive of the gdb-patches@sourceware.org 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]
Other format: [Raw text]

[patch 00/12] entryval#3: Fix x86_64 <optimized out> parameters, virtual tail call frames


Hi,

hopefully a final re-post of the series:
	[patch 00/12] entryval#2: Fix x86_64 <optimized out> parameters, virtual tail call frames
	http://sourceware.org/ml/gdb-patches/2011-09/msg00222.html

Here is attached a diff against the patch series #2 above, mostly Eli's doc
fixes and the implied debugging output code changes.

I will check it in if no new issues appear.


Thanks,
Jan


--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -100,14 +100,14 @@ info auto-load-scripts [REGEXP]
 
 set print entry-values (both|compact|default|if-needed|no|only|preferred)
 show print entry-values
-  Set printing of frame arguments values at function entry.  In some cases
+  Set printing of frame argument values at function entry.  In some cases
   GDB can determine the value of function argument which was passed by the
-  function caller, despite the argument value may be already modified.
+  function caller, even if the value was modified inside the called function.
 
-set debug tailcall
-show debug tailcall
-  Control display of debugging info for determining virtual tail call frames,
-  present in inferior debug info together with the @entry values.
+set debug entry-values
+show debug entry-values
+  Control display of debugging info for determining frame argument values at
+  function entry and virtual tail call frames.
 
 * New remote packets
 
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -26,6 +26,7 @@
 #include "cp-support.h"
 #include "addrmap.h"
 #include "gdbtypes.h"
+#include "exceptions.h"
 
 /* This is used by struct block to store namespace-related info for
    C++ files, namely using declarations and the current namespace in
@@ -161,25 +162,34 @@ blockvector_for_pc_sect (CORE_ADDR pc, struct obj_section *section,
   return 0;
 }
 
-/* Return call_site for specified PC.  PC must match exactly, it must be the
-   next instruction after call (or after tail call jump).  Return NULL if it
-   cannot be found.  */
+/* Return call_site for specified PC in GDBARCH.  PC must match exactly, it
+   must be the next instruction after call (or after tail call jump).  Throw
+   NO_ENTRY_VALUE_ERROR otherwise.  This function never returns NULL.  */
 
 struct call_site *
-call_site_for_pc (CORE_ADDR pc)
+call_site_for_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   struct symtab *symtab;
-  void **slot;
+  void **slot = NULL;
 
   /* -1 as tail call PC can be already after the compilation unit range.  */
   symtab = find_pc_symtab (pc - 1);
 
-  if (symtab == NULL || symtab->call_site_htab == NULL)
-    return NULL;
+  if (symtab != NULL && symtab->call_site_htab != NULL)
+    slot = htab_find_slot (symtab->call_site_htab, &pc, NO_INSERT);
 
-  slot = htab_find_slot (symtab->call_site_htab, &pc, NO_INSERT);
   if (slot == NULL)
-    return NULL;
+    {
+      struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (pc);
+
+      /* DW_TAG_gnu_call_site will be missing just if GCC could not determine
+	 the call target.  */
+      throw_error (NO_ENTRY_VALUE_ERROR,
+		   _("DW_OP_GNU_entry_value resolving cannot find "
+		     "DW_TAG_GNU_call_site %s in %s"),
+		   paddress (gdbarch, pc),
+		   msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
+    }
 
   return *slot;
 }
--- a/gdb/block.h
+++ b/gdb/block.h
@@ -142,7 +142,8 @@ extern struct blockvector *blockvector_for_pc_sect (CORE_ADDR,
 						    struct block **,
                                                     struct symtab *);
 
-extern struct call_site *call_site_for_pc (CORE_ADDR pc);
+extern struct call_site *call_site_for_pc (struct gdbarch *gdbarch,
+					   CORE_ADDR pc);
 
 extern struct block *block_for_pc (CORE_ADDR);
 
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -7280,6 +7280,8 @@ type>}.  @xref{Symbols, incomplete type}, for more about this.
 If you append @kbd{@@entry} string to a function parameter name you get its
 value at the time the function got called.  If the value is not available an
 error message is printed.  Entry values are available only with some compilers.
+Entry values are normally also printed at the function parameter list according
+to @ref{set print entry-values}.
 
 @smallexample
 Breakpoint 1, d (i=30) at gdb.base/entry-value.c:29
@@ -7956,26 +7958,26 @@ thus speeding up the display of each Ada frame.
 @item show print frame-arguments
 Show how the value of arguments should be displayed when printing a frame.
 
+@anchor{set print entry-values}
 @item set print entry-values @var{value}
 @kindex set print entry-values
-Set printing of frame arguments values at function entry.  In some cases
+Set printing of frame argument values at function entry.  In some cases
 @value{GDBN} can determine the value of function argument which was passed by
-the function caller, despite the argument value may be already modified by the
-current function and therefore different.  For optimized code also the current
-value may be possibly not available and the entry value may be still known,
-which aids the debugging of production code.
+the function caller, even if the value was modified inside the called function
+and therefore is different.  With optimized code, the current value could be
+unavailable, but the entry value may still be known.
 
 The default value is @code{default} (see below for its description).  Older
 @value{GDBN} behaved as with the setting @code{no}.  Compilers not supporting
-this feature will behave in the default @code{default} setting the same way as
-with the @code{no} setting.
+this feature will behave in the @code{default} setting the same way as with the
+@code{no} setting.
 
 This functionality is currently supported only by DWARF 2 debugging format and
-the compiler has to produce @samp{DW_TAG_GNU_call_site} tags.  For example for
-@value{NGCC} additionally optimization and debugging compilation options must
-be enabled (@option{-O -g}).  Still even with the required debug info there
-exist many reasons why the code path analysis by @value{GDBN} may fail in
-specific cases.
+the compiler has to produce @samp{DW_TAG_GNU_call_site} tags.  With
+@value{NGCC}, you need to specify @option{-O -g} during compilation, to get
+this information.
+
+The @var{value} parameter can be one of the following:
 
 @table @code
 @item no
@@ -7990,7 +7992,6 @@ point.
 @end smallexample
 
 @item only
-set print entry-values only
 Print only parameter values from function entry point.  The actual parameter
 values are never printed.
 @smallexample
@@ -8003,32 +8004,32 @@ values are never printed.
 
 @item preferred
 Print only parameter values from function entry point.  If value from function
-entry point is not known while the actual value is known print at least the
-actual value for such parameter.
+entry point is not known while the actual value is known, print the actual
+value for such parameter.
 @smallexample
 #0  equal (val@@entry=5)
 #0  different (val@@entry=5)
 #0  lost (val@@entry=5)
-#0  born (val@@entry=<optimized out>)
+#0  born (val=10)
 #0  invalid (val@@entry=<optimized out>)
 @end smallexample
 
 @item if-needed
 Print actual parameter values.  If actual parameter value is not known while
-value from function entry point is known print at least the entry point value
-for such parameter.
+value from function entry point is known, print the entry point value for such
+parameter.
 @smallexample
-#0  equal (val@@entry=5)
-#0  different (val@@entry=5)
+#0  equal (val=5)
+#0  different (val=6)
 #0  lost (val@@entry=5)
 #0  born (val=10)
-#0  invalid (val@@entry=<optimized out>)
+#0  invalid (val=<optimized out>)
 @end smallexample
 
 @item both
-set print entry-values both
 Always print both the actual parameter value and its value from function entry
-point.  Still print both even if one of them or both are @code{<optimized out>}.
+point, even if values of one or both are not available due to compiler
+optimizations.
 @smallexample
 #0  equal (val=5, val@@entry=5)
 #0  different (val=6, val@@entry=5)
@@ -8038,10 +8039,10 @@ point.  Still print both even if one of them or both are @code{<optimized out>}.
 @end smallexample
 
 @item compact
-Print the actual parameter value if it is know and also its value from
-function entry point if it is known.  If neither is known print for the actual
+Print the actual parameter value if it is known and also its value from
+function entry point if it is known.  If neither is known, print for the actual
 value @code{<optimized out>}.  If not in MI mode (@pxref{GDB/MI}) and if both
-values are known and they are equal print the shortened
+values are known and identical, print the shortened
 @code{param=param@@entry=VALUE} notation.
 @smallexample
 #0  equal (val=val@@entry=5)
@@ -8053,8 +8054,8 @@ values are known and they are equal print the shortened
 
 @item default
 Always print the actual parameter value.  Print also its value from function
-entry point but only if it is known.  If not in MI mode (@pxref{GDB/MI}) and if
-both values are known and they are equal print the shortened
+entry point, but only if it is known.  If not in MI mode (@pxref{GDB/MI}) and
+if both values are known and identical, print the shortened
 @code{param=param@@entry=VALUE} notation.
 @smallexample
 #0  equal (val=val@@entry=5)
@@ -8065,8 +8066,12 @@ both values are known and they are equal print the shortened
 @end smallexample
 @end table
 
+For analysis messages on possible failures of frame argument values at function
+entry resolution see @ref{set debug entry-values}.
+
 @item show print entry-values
-Show printing of frame arguments values at function entry.
+Show the method being used for printing of frame argument values at function
+entry.
 
 @item set print repeats
 @cindex repeated array elements
@@ -9685,31 +9690,39 @@ and print a variable where your program stored the return value.
 @section Tail Call Frames
 @cindex tail call frames, debugging
 
-Function @code{B} can call function @code{C} by its very last statement.  In
+Function @code{B} can call function @code{C} in its very last statement.  In
 unoptimized compilation the call of @code{C} is immediately followed by return
 instruction at the end of @code{B} code.  Optimizing compiler may replace the
 call and return in function @code{B} into one jump to function @code{C}
-instead.  Such use of a jump instruction is called tail call.
-
-During execution of function @code{C} there will remain no indication it has
-been tail called from function @code{B}.  If function @code{A} regularly calls
-function @code{B} which tail calls function @code{C} then @value{GDBN} sees as
-the caller of function @code{C} the function @code{A}.  @value{GDBN} can in
-some cases search all the possible code paths and if it determintes there
-exists an unambiguous code path it will create call frames for it (in this case
-a frame with @code{$pc} in function @code{B}).  The virtual return address into
-such tail call frame will be pointing pointing right after the jump instruction
-(as if it would be a call instructions).
+instead.  Such use of a jump instruction is called @dfn{tail call}.
+
+During execution of function @code{C}, there will be no indication in the
+function call stack frames that it was tail-called from @code{B}.  If function
+@code{A} regularly calls function @code{B} which tail-calls function @code{C},
+then @value{GDBN} will see @code{A} as the caller of @code{C}.  However, in
+some cases @value{GDBN} can determine that @code{C} was tail-called from
+@code{B}, and it will then create fictitious call frame for that, with the
+return address set up as if @code{B} called @code{C} normally.
 
 This functionality is currently supported only by DWARF 2 debugging format and
-the compiler has to produce @samp{DW_TAG_GNU_call_site} tags.  For example for
-@value{NGCC} additionally optimization and debugging compilation options must
-be enabled (@option{-O -g}).  Still even with the required debug info there
-exist many reasons why the code path analysis by @value{GDBN} may fail in
-specific cases.
+the compiler has to produce @samp{DW_TAG_GNU_call_site} tags.  With
+@value{NGCC}, you need to specify @option{-O -g} during compilation, to get
+this information.
 
 @kbd{info frame} command (@pxref{Frame Info}) will indicate the tail call frame
-kind by text @code{tail call frame}.
+kind by text @code{tail call frame} such as in this sample @value{GDBN} output:
+
+@smallexample
+(gdb) x/i $pc - 2
+   0x40066b <b(int, double)+11>: jmp 0x400640 <c(int, double)>
+(gdb) info frame
+Stack level 1, frame at 0x7fffffffda30:
+ rip = 0x40066d in b (amd64-entry-value.cc:59); saved rip 0x4004c5
+ tail call frame, caller of frame at 0x7fffffffda30
+ source language c++.
+ Arglist at unknown address.
+ Locals at unknown address, Previous frame's sp is 0x7fffffffda30
+@end smallexample
 
 The detection of all the possible code path executions can find them ambiguous.
 There is no execution history stored (possible @ref{Reverse Execution} is never
@@ -9718,23 +9731,108 @@ callee by multiple different jump sequences.  In such case @value{GDBN} still
 tries to show at least all the unambiguous top tail callers and all the
 unambiguous bottom tail calees, if any.
 
-@kbd{set verbose} command (@pxref{Messages/Warnings, ,Optional Warnings and
-Messages}.) can show some reasons why the complete code path analysis did not
-succeed in a specific case.
-
 @table @code
-@item set debug tailcall
-@kindex set debug tailcall
-When set to on, enables tail calls analysis messages printing.  It will show
-all the possible valid tail calls code paths it has considered.  It will also
-print the intersection of them with the final unambiguous (possibly partial or
-even empty) code path result.
-
-@item show debug tailcall
-@kindex show debug tailcall
-Show the current state of tail calls analysis messages.
-@end table
-
+@anchor{set debug entry-values}
+@item set debug entry-values
+@kindex set debug entry-values
+When set to on, enables printing of analysis messages for both frame argument
+values at function entry and tail calls.  It will show all the possible valid
+tail calls code paths it has considered.  It will also print the intersection
+of them with the final unambiguous (possibly partial or even empty) code path
+result.
+
+@item show debug entry-values
+@kindex show debug entry-values
+Show the current state of analysis messages printing for both frame argument
+values at function entry and tail calls.
+@end table
+
+The analysis messages for tail calls can for example show why the virtual tail
+call frame for function @code{c} has not been recognized (due to the indirect
+reference by variable @code{x}):
+
+@smallexample
+static void __attribute__((noinline, noclone)) c (void);
+void (*x) (void) = c;
+static void __attribute__((noinline, noclone)) a (void) @{ x++; @}
+static void __attribute__((noinline, noclone)) c (void) @{ a (); @}
+int main (void) @{ x (); return 0; @}
+
+Breakpoint 1, DW_OP_GNU_entry_value resolving cannot find
+DW_TAG_GNU_call_site 0x40039a in main
+a () at t.c:3
+3	static void __attribute__((noinline, noclone)) a (void) @{ x++; @}
+(gdb) bt
+#0  a () at t.c:3
+#1  0x000000000040039a in main () at t.c:5
+@end smallexample
+
+Another possibility is an ambiguous virtual tail call frames resolution:
+
+@smallexample
+int i;
+static void __attribute__((noinline, noclone)) f (void) @{ i++; @}
+static void __attribute__((noinline, noclone)) e (void) @{ f (); @}
+static void __attribute__((noinline, noclone)) d (void) @{ f (); @}
+static void __attribute__((noinline, noclone)) c (void) @{ d (); @}
+static void __attribute__((noinline, noclone)) b (void)
+@{ if (i) c (); else e (); @}
+static void __attribute__((noinline, noclone)) a (void) @{ b (); @}
+int main (void) @{ a (); return 0; @}
+
+tailcall: initial: 0x4004d2(a) 0x4004ce(b) 0x4004b2(c) 0x4004a2(d)
+tailcall: compare: 0x4004d2(a) 0x4004cc(b) 0x400492(e)
+tailcall: reduced: 0x4004d2(a) |
+(gdb) bt
+#0  f () at t.c:2
+#1  0x00000000004004d2 in a () at t.c:8
+#2  0x0000000000400395 in main () at t.c:9
+@end smallexample
+
+Frames #0 and #2 are real, #1 is a virtual tail call frame.  The code can have
+possible execution paths
+@code{main@arrow{}a@arrow{}b@arrow{}c@arrow{}d@arrow{}f} or
+@code{main@arrow{}a@arrow{}b@arrow{}e@arrow{}f}, @value{GDBN} cannot find which
+one from the inferior state.
+
+@code{initial:} state shows some random possible calling sequence @value{GDBN}
+has found.  It then finds another possible calling sequcen - that one is
+prefixed by @code{compare:}.  The non-ambiguous intersection of these two is
+printed as the @code{reduced:} calling sequence.  That one could have many
+futher @code{compare:} and @code{reduced:} statements as long as there remain
+any non-ambiguous sequence entries.
+
+For the frame of function @code{b} in both cases there are different possible
+@code{$pc} values (@code{0x4004cc} or @code{0x4004ce}), therefore this frame is
+also ambigous.  The only non-ambiguous frame is the one for function @code{a},
+therefore this one is displayed to the user while the ambiguous frames are
+omitted.
+
+There can be also reasons why printing of frame argument values at function
+entry may fail:
+
+@smallexample
+int v;
+static void __attribute__((noinline, noclone)) c (int i) @{ v++; @}
+static void __attribute__((noinline, noclone)) a (int i);
+static void __attribute__((noinline, noclone)) b (int i) @{ a (i); @}
+static void __attribute__((noinline, noclone)) a (int i)
+@{ if (i) b (i - 1); else c (0); @}
+int main (void) @{ a (5); return 0; @}
+
+(gdb) bt
+#0  c (i=i@@entry=0) at t.c:2
+#1  0x0000000000400428 in a (DW_OP_GNU_entry_value resolving has found
+function "a" at 0x400420 can call itself via tail calls
+i=<optimized out>) at t.c:6
+#2  0x000000000040036e in main () at t.c:7
+@end smallexample
+
+@value{GDBN} cannot find out from the inferior state if and how many times did
+function @code{a} call itself (via function @code{b}) as these calls would be
+tail calls.  Such tail calls would modify thue @code{i} variable, therefore
+@value{GDBN} cannot be sure the value it knows would be right - @value{GDBN}
+prints @code{<optimized out>} instead.
 
 @node Macros
 @chapter C Preprocessor Macros
@@ -23263,11 +23361,7 @@ A frame representing an inlined function.  The function was inlined
 into a @code{gdb.NORMAL_FRAME} that is older than this one.
 
 @item gdb.TAILCALL_FRAME
-A frame representing a tail call.  Tail calls are used if the last statement of
-an inferior function is a call of a (usually different) function.  Such call
-immediately followed by return instruction is in optimized code converted to
-just one jump instruction.  @value{GDBN} can in some cases guess such jump has
-been executed and it creates a @code{gdb.TAILCALL_FRAME} for it.
+A frame representing a tail call.  @xref{Tail Call Frames}.
 
 @item gdb.SIGTRAMP_FRAME
 A signal trampoline frame.  This is the frame created by the OS when
--- a/gdb/dwarf2-frame-tailcall.c
+++ b/gdb/dwarf2-frame-tailcall.c
@@ -389,8 +389,6 @@ dwarf2_tailcall_sniffer_first (struct frame_info *this_frame,
 
       /* Simulate frame_unwind_pc without setting this_frame->prev_pc.p.  */
       prev_pc = frame_unwind_register_unsigned (this_frame, pc_regnum);
-      if (call_site_for_pc (prev_pc) == NULL)
-	break;
 
       /* call_site_find_chain can throw an exception.  */
       chain = call_site_find_chain (prev_gdbarch, prev_pc, this_pc);
@@ -404,7 +402,11 @@ dwarf2_tailcall_sniffer_first (struct frame_info *this_frame,
       prev_sp_p = 1;
     }
   if (except.reason < 0)
-    return;
+    {
+      if (entry_values_debug)
+	exception_print (gdb_stdout, except);
+      return;
+    }
 
   /* Ambiguous unwind or unambiguous unwind verified as matching.  */
   if (chain == NULL || chain->length == 0)
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -317,12 +317,19 @@ dwarf_expr_get_base_type (struct dwarf_expr_context *ctx, size_t die_offset)
   return dwarf2_get_die_type (die_offset, debaton->per_cu);
 }
 
-static int tailcall_debug = 0;
+/* See dwarf2loc.h.  */
+
+int entry_values_debug = 0;
+
+/* Helper to set entry_values_debug.  */
+
 static void
-show_tailcall_debug (struct ui_file *file, int from_tty,
-		     struct cmd_list_element *c, const char *value)
+show_entry_values_debug (struct ui_file *file, int from_tty,
+			 struct cmd_list_element *c, const char *value)
 {
-  fprintf_filtered (file, _("Tail call frames debugging is %s.\n"), value);
+  fprintf_filtered (file,
+		    _("Entry values and tail call frames debugging is %s.\n"),
+		    value);
 }
 
 /* Find DW_TAG_GNU_call_site's DW_AT_GNU_call_site_target address.
@@ -330,7 +337,8 @@ show_tailcall_debug (struct ui_file *file, int from_tty,
    always returns valid address or it throws NO_ENTRY_VALUE_ERROR.  */
 
 static CORE_ADDR
-call_site_to_target_addr (struct call_site *call_site,
+call_site_to_target_addr (struct gdbarch *call_site_gdbarch,
+			  struct call_site *call_site,
 			  struct frame_info *caller_frame)
 {
   switch (FIELD_LOC_KIND (call_site->target))
@@ -344,13 +352,30 @@ call_site_to_target_addr (struct call_site *call_site,
 
 	dwarf_block = FIELD_DWARF_BLOCK (call_site->target);
 	if (dwarf_block == NULL)
-	  throw_error (NO_ENTRY_VALUE_ERROR,
-		       _("DW_AT_GNU_call_site_target is not specified"));
+	  {
+	    struct minimal_symbol *msym;
+	    
+	    msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
+	    throw_error (NO_ENTRY_VALUE_ERROR,
+			 _("DW_AT_GNU_call_site_target is not specified "
+			   "at %s in %s"),
+			 paddress (call_site_gdbarch, call_site->pc),
+			 msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
+			
+	  }
 	if (caller_frame == NULL)
-	  throw_error (NO_ENTRY_VALUE_ERROR,
-		       _("DW_AT_GNU_call_site_target DWARF block resolving "
-			 "requires known frame which is currently not "
-			 "available"));
+	  {
+	    struct minimal_symbol *msym;
+	    
+	    msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
+	    throw_error (NO_ENTRY_VALUE_ERROR,
+			 _("DW_AT_GNU_call_site_target DWARF block resolving "
+			   "requires known frame which is currently not "
+			   "available at %s in %s"),
+			 paddress (call_site_gdbarch, call_site->pc),
+			 msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
+			
+	  }
 	caller_arch = get_frame_arch (caller_frame);
 	caller_core_addr_type = builtin_type (caller_arch)->builtin_func_ptr;
 	val = dwarf2_evaluate_loc_desc (caller_core_addr_type, caller_frame,
@@ -372,9 +397,15 @@ call_site_to_target_addr (struct call_site *call_site,
 	physname = FIELD_STATIC_PHYSNAME (call_site->target);
 	msym = lookup_minimal_symbol_text (physname, NULL);
 	if (msym == NULL)
-	  throw_error (NO_ENTRY_VALUE_ERROR,
-		       _("Cannot find function \"%s\" for a call site target"),
-		       physname);
+	  {
+	    msym = lookup_minimal_symbol_by_pc (call_site->pc - 1);
+	    throw_error (NO_ENTRY_VALUE_ERROR,
+			 _("Cannot find function \"%s\" for a call site target "
+			   "at %s in %s"),
+			 physname, paddress (call_site_gdbarch, call_site->pc),
+			 msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
+			
+	  }
 	return SYMBOL_VALUE_ADDRESS (msym);
       }
 
@@ -462,7 +493,7 @@ func_verify_no_selftailcall (struct gdbarch *gdbarch, CORE_ADDR verify_addr)
 
 	  /* CALLER_FRAME with registers is not available for tail-call jumped
 	     frames.  */
-	  target_addr = call_site_to_target_addr (call_site, NULL);
+	  target_addr = call_site_to_target_addr (gdbarch, call_site, NULL);
 
 	  if (target_addr == verify_addr)
 	    {
@@ -491,7 +522,7 @@ func_verify_no_selftailcall (struct gdbarch *gdbarch, CORE_ADDR verify_addr)
 }
 
 /* Print user readable form of CALL_SITE->PC to gdb_stdlog.  Used only for
-   TAILCALL_DEBUG.  */
+   ENTRY_VALUES_DEBUG.  */
 
 static void
 tailcall_dump (struct gdbarch *gdbarch, const struct call_site *call_site)
@@ -512,9 +543,9 @@ DEF_VEC_P (call_sitep);
 
 /* Intersect RESULTP with CHAIN to keep RESULTP unambiguous, keep in RESULTP
    only top callers and bottom callees which are present in both.  GDBARCH is
-   used only for TAILCALL_DEBUG.  RESULTP is NULL after return if there are no
-   remaining possibilities to provide unambiguous non-trivial result.  RESULTP
-   should point to NULL on the first (initialization) call.  caller is
+   used only for ENTRY_VALUES_DEBUG.  RESULTP is NULL after return if there are
+   no remaining possibilities to provide unambiguous non-trivial result.
+   RESULTP should point to NULL on the first (initialization) call.  Caller is
    responsible for xfree of any RESULTP data.  */
 
 static void
@@ -537,7 +568,7 @@ chain_candidate (struct gdbarch *gdbarch, struct call_site_chain **resultp,
 	      sizeof (*result->call_site) * length);
       *resultp = result;
 
-      if (tailcall_debug)
+      if (entry_values_debug)
 	{
 	  fprintf_unfiltered (gdb_stdlog, "tailcall: initial:");
 	  for (idx = 0; idx < length; idx++)
@@ -548,7 +579,7 @@ chain_candidate (struct gdbarch *gdbarch, struct call_site_chain **resultp,
       return;
     }
 
-  if (tailcall_debug)
+  if (entry_values_debug)
     {
       fprintf_unfiltered (gdb_stdlog, "tailcall: compare:");
       for (idx = 0; idx < length; idx++)
@@ -577,7 +608,7 @@ chain_candidate (struct gdbarch *gdbarch, struct call_site_chain **resultp,
 	break;
       }
 
-  if (tailcall_debug)
+  if (entry_values_debug)
     {
       fprintf_unfiltered (gdb_stdlog, "tailcall: reduced:");
       for (idx = 0; idx < result->callers; idx++)
@@ -650,11 +681,11 @@ call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
 
   make_cleanup (VEC_cleanup (call_sitep), &chain);
 
-  /* Do not push CALL_SITE to CHAIN.  Push there only the first tail call site at
-     the target's function.  All the possible tail call sites in the target's
-     function will get iterated as already pushed into CHAIN via their
+  /* Do not push CALL_SITE to CHAIN.  Push there only the first tail call site
+     at the target's function.  All the possible tail call sites in the
+     target's function will get iterated as already pushed into CHAIN via their
      TAIL_CALL_NEXT.  */
-  call_site = call_site_for_pc (caller_pc);
+  call_site = call_site_for_pc (gdbarch, caller_pc);
 
   while (call_site)
     {
@@ -663,7 +694,7 @@ call_site_find_chain_1 (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
 
       /* CALLER_FRAME with registers is not available for tail-call jumped
 	 frames.  */
-      target_func_addr = call_site_to_target_addr (call_site, NULL);
+      target_func_addr = call_site_to_target_addr (gdbarch, call_site, NULL);
 
       if (target_func_addr == callee_pc)
 	{
@@ -771,7 +802,7 @@ call_site_find_chain (struct gdbarch *gdbarch, CORE_ADDR caller_pc,
     {
       if (e.error == NO_ENTRY_VALUE_ERROR)
 	{
-	  if (info_verbose)
+	  if (entry_values_debug)
 	    exception_print (gdb_stdout, e);
 
 	  return NULL;
@@ -829,22 +860,9 @@ dwarf_expr_reg_to_entry_parameter (struct frame_info *frame, int dwarf_reg,
 		   msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
     }
   caller_pc = get_frame_pc (caller_frame);
+  call_site = call_site_for_pc (gdbarch, caller_pc);
 
-  call_site = call_site_for_pc (caller_pc);
-  if (call_site == NULL)
-    {
-      struct minimal_symbol *msym = lookup_minimal_symbol_by_pc (caller_pc);
-
-      /* DW_TAG_gnu_call_site will be missing just if GCC could not determine
-	 the call target.  */
-      throw_error (NO_ENTRY_VALUE_ERROR,
-		   _("DW_OP_GNU_entry_value resolving cannot find "
-		     "DW_TAG_GNU_call_site %s in %s"),
-		   paddress (gdbarch, caller_pc),
-		   msym == NULL ? "???" : SYMBOL_PRINT_NAME (msym));
-    }
-
-  target_addr = call_site_to_target_addr (call_site, caller_frame);
+  target_addr = call_site_to_target_addr (gdbarch, call_site, caller_frame);
   if (target_addr != func_addr)
     {
       struct minimal_symbol *target_msym, *func_msym;
@@ -1097,7 +1115,8 @@ value_of_dwarf_reg_entry (struct type *type, struct frame_info *frame,
 				 target_val /* closure */);
 
   /* Copy the referencing pointer to the new computed value.  */
-  memcpy (value_contents_raw (val), value_contents_raw (outer_val), TYPE_LENGTH (checked_type));
+  memcpy (value_contents_raw (val), value_contents_raw (outer_val),
+	  TYPE_LENGTH (checked_type));
   set_value_lazy (val, 0);
 
   return val;
@@ -1975,7 +1994,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
 	}
       else if (ex.error == NO_ENTRY_VALUE_ERROR)
 	{
-	  if (info_verbose)
+	  if (entry_values_debug)
 	    exception_print (gdb_stdout, ex);
 	  do_cleanups (old_chain);
 	  return allocate_optimized_out_value (type);
@@ -3891,14 +3910,16 @@ const struct symbol_computed_ops dwarf2_loclist_funcs = {
 void
 _initialize_dwarf2loc (void)
 {
-  add_setshow_zinteger_cmd ("tailcall", class_maintenance,
-			    &tailcall_debug,
-			    _("Set tail call frames debugging."),
-			    _("Show tail call frames debugging."),
-			    _("When non-zero, the process of determining tail "
-			      "call frames will be printed.  You may also want "
-			      "to `set verbose 1' for more info."),
+  add_setshow_zinteger_cmd ("entry-values", class_maintenance,
+			    &entry_values_debug,
+			    _("Set entry values and tail call frames "
+			      "debugging."),
+			    _("Show entry values and tail call frames "
+			      "debugging."),
+			    _("When non-zero, the process of determining "
+			      "parameter values from function entry point "
+			      "and tail call frames will be printed."),
 			    NULL,
-			    show_tailcall_debug,
+			    show_entry_values_debug,
 			    &setdebuglist, &showdebuglist);
 }
--- a/gdb/dwarf2loc.h
+++ b/gdb/dwarf2loc.h
@@ -31,6 +31,9 @@ struct axs_value;
 /* This header is private to the DWARF-2 reader.  It is shared between
    dwarf2read.c and dwarf2loc.c.  */
 
+/* `set debug entry-values' setting.  */
+extern int entry_values_debug;
+
 /* Return the OBJFILE associated with the compilation unit CU.  If CU
    came from a separate debuginfo file, then the master objfile is
    returned.  */
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -2528,14 +2528,14 @@ source line."),
 
   add_setshow_enum_cmd ("entry-values", class_stack,
 			print_entry_values_choices, &print_entry_values,
-			_("Set printing of frame arguments values at function "
+			_("Set printing of function arguments at function "
 			  "entry"),
-			_("Show printing of frame arguments values at function "
+			_("Show printing of function arguments at function "
 			  "entry"),
 			_("\
-GDB can print in some cases besides frame arguments values also the values\n\
-they had at function entry (marked as `NAME@entry').  The value itself and/or\n\
-the entry value may be <optimized out>.  Which of this current or entry\n\
-values get printed in which case can be set by this option."),
+GDB can sometimes determine the values of function arguments at entry,\n\
+in addition to their current values.  This option tells GDB whether\n\
+to print the current value, the value at entry (marked as val@entry),\n\
+or both.  Note that one or both of these values may be <optimized out>."),
 			NULL, NULL, &setprintlist, &showprintlist);
 }
--- a/gdb/testsuite/gdb.arch/amd64-entry-value.exp
+++ b/gdb/testsuite/gdb.arch/amd64-entry-value.exp
@@ -230,6 +230,6 @@ gdb_continue_to_breakpoint "self: breakhere"
 gdb_test "bt" "^bt\r\n#0 +d \\(i=<optimized out>, j=<optimized out>\\)\[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in self \\(i=<optimized out>\\)\[^\r\n\]*\r\n#2 +0x\[0-9a-f\]+ in main \\(\\)\[^\r\n\]*" \
 	 "self: bt"
 
-gdb_test_no_output "set verbose on"
+gdb_test_no_output "set debug entry-values 1"
 gdb_test "bt" "DW_OP_GNU_entry_value resolving has found function \"self\\(int\\)\" at 0x\[0-9a-f\]+ can call itself via tail calls\r\n.*" \
-	 "self: bt verbose"
+	 "self: bt debug entry-values"
--- a/gdb/testsuite/gdb.mi/mi2-amd64-entry-value.exp
+++ b/gdb/testsuite/gdb.mi/mi2-amd64-entry-value.exp
@@ -30,7 +30,7 @@ if [info exists COMPILE] {
     set srcfile ${testfile}.c
     lappend opts debug optimize=-O2
 } elseif { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
-    verbose "Skipping amd64-entry-value."
+    verbose "Skipping mi2-amd64-entry-value."
     return
 }
 


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