public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* Re: [RFA] Have block_innermost_frame start from selected frame
@ 2011-12-30 21:54 Paul Hilfinger
  2011-12-31  8:58 ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Paul Hilfinger @ 2011-12-30 21:54 UTC (permalink / raw)
  To: gdb-patches


OK.  The discussion seems to have converged.  Here (and in the following) are
the revised patch (this time with documentation).  I will commit after a
suitable interval.  Thanks for the comments.

Paul N. Hilfinger
(Hilfinger@adacore.com)


Previously, GDB would search for the frame containing variables in a
particular lexical block starting from the current (top) frame,
ignoring any currently selected frame.  It is not clear why this is
desirable for variables that require a frame; why would a user
deliberately select one frame and then expect to see the value of a
variable in a more recent frame?  This change causes
block_innermost_frame to start looking from the selected frame, if
there is one.

This change is perhaps unnecessarily conservative.  It uses
get_selected_frame_if_set rather than get_selected_frame in order to
avoid the side effect of calling select_frame, which would probably be
harmless.

Add a paragraph to the "Program Variables" section of the texinfo
documentation concerning the use of "::" for accessing non-static variables.

2011-12-27  Paul Hilfinger  <hilfingr@adacore.com>

  * gdb/blockframe.c (block_innermost_frame): Start search from selected frame,
    if present, or otherwise the current frame.

  * gdb/doc/gdb.texinfo (Variables): Document use of :: for non-static
    variables.
---
 gdb/ChangeLog       |    5 +++++
 gdb/blockframe.c    |    9 ++++++---
 gdb/doc/ChangeLog   |    5 +++++
 gdb/doc/gdb.texinfo |   48 +++++++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 40f6169..d1b2401 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2011-12-30  Paul Hilfinger  <hilfingr@adacore.com>
+
+        * blockframe.c (block_innermost_frame): Start search from
+        selected frame, if present, or otherwise the current frame.
+
 2011-12-28  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	* gdbarch.sh (max_insn_length): Extend the comment by unit.
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index ef53a3d..2d2b45c 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -354,8 +354,9 @@ find_pc_partial_function (CORE_ADDR pc, char **name, CORE_ADDR *address,
   return find_pc_partial_function_gnu_ifunc (pc, name, address, endaddr, NULL);
 }
 
-/* Return the innermost stack frame executing inside of BLOCK, or NULL
-   if there is no such frame.  If BLOCK is NULL, just return NULL.  */
+/* Return the innermost stack frame that is executing inside of BLOCK and is 
+ * at least as old as the selected frame. Return NULL if there is no
+ * such frame.  If BLOCK is NULL, just return NULL.  */
 
 struct frame_info *
 block_innermost_frame (const struct block *block)
@@ -370,7 +371,9 @@ block_innermost_frame (const struct block *block)
   start = BLOCK_START (block);
   end = BLOCK_END (block);
 
-  frame = get_current_frame ();
+  frame = get_selected_frame_if_set ();
+  if (frame == NULL)
+    frame = get_current_frame ();
   while (frame != NULL)
     {
       struct block *frame_block = get_frame_block (frame, NULL);
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 0ede40b..00e876f 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2011-12-30  Paul Hilfinger  <hilfingr@adacore.com>
+
+	* gdb.texinfo (Variables): Document use of :: for non-static
+	variables.
+
 2011-12-23  Kevin Pouget  <kevin.pouget@st.com>
 
 	Introduce gdb.FinishBreakpoint in Python.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 3cd3b67..cd38e3f 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -7304,12 +7304,13 @@ examine the variable @code{b} while your program is executing inside
 the block where @code{b} is declared.
 
 @cindex variable name conflict
-There is an exception: you can refer to a variable or function whose
+You can refer to a variable or function whose
 scope is a single source file even if the current execution point is not
 in this file.  But it is possible to have more than one such variable or
 function with the same name (in different source files).  If that
 happens, referring to that name has unpredictable effects.  If you wish,
-you can specify a static variable in a particular function or file,
+you can specify a static variable in a particular function or file by
+qualifying its name
 using the colon-colon (@code{::}) notation:
 
 @cindex colon-colon, context for variables/functions
@@ -7332,8 +7333,49 @@ to print a global value of @code{x} defined in @file{f2.c}:
 (@value{GDBP}) p 'f2.c'::x
 @end smallexample
 
+The @code{::} qualifying notation is normally used for referring to
+static variables, since you typically disambiguate uses of local variables
+in functions by selecting the appropriate frame and using the
+unqualified name of the variable.  However, you may also use this notation
+to refer to local variables in frames enclosing the selected frame:
+
+@smallexample
+void
+foo (int a)
+@{
+  if (a < 10)
+      bar (a);
+  else
+      process (a);    /* Stop here */
+@}
+
+int
+bar (int a)
+@{
+  foo (a + 5);
+@}
+@end smallexample
+
+@noindent
+If you have a breakpoint at the indicated line above
+when the program executes the call @code{bar(0)}, then when the program
+stops, the commands
+
+@smallexample
+(@value{GDBP}) p a
+(@value{GDBP}) p bar::a
+(@value{GDBP}) up 2
+(@value{GDBP}) p a
+(@value{GDBP}) p bar::a
+
+@end smallexample
+
+@noindent
+will print the values @samp{10}, @samp{5}, @samp{5}, and @samp{0} in that
+order.
+
 @cindex C@t{++} scope resolution
-This use of @samp{::} is very rarely in conflict with the very similar
+These uses of @samp{::} are very rarely in conflict with the very similar
 use of the same notation in C@t{++}.  @value{GDBN} also supports use of the C@t{++}
 scope resolution operator in @value{GDBN} expressions.
 @c FIXME: Um, so what happens in one of those rare cases where it's in
-- 
1.7.0.4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] Have block_innermost_frame start from selected frame
  2011-12-30 21:54 [RFA] Have block_innermost_frame start from selected frame Paul Hilfinger
@ 2011-12-31  8:58 ` Eli Zaretskii
  2011-12-31 21:40   ` Paul Hilfinger
  2012-01-09  7:17   ` Paul Hilfinger
  0 siblings, 2 replies; 12+ messages in thread
From: Eli Zaretskii @ 2011-12-31  8:58 UTC (permalink / raw)
  To: Paul Hilfinger; +Cc: gdb-patches

> From: Paul Hilfinger <Hilfinger@adacore.com>
> Date: Fri, 30 Dec 2011 16:52:22 -0500 (EST)
> 
> @@ -7304,12 +7304,13 @@ examine the variable @code{b} while your program is executing inside
>  the block where @code{b} is declared.
>  
>  @cindex variable name conflict
> -There is an exception: you can refer to a variable or function whose
> +You can refer to a variable or function whose
>  scope is a single source file even if the current execution point is not
>  in this file.  But it is possible to have more than one such variable or
>  function with the same name (in different source files).  If that
>  happens, referring to that name has unpredictable effects.  If you wish,
> -you can specify a static variable in a particular function or file,
> +you can specify a static variable in a particular function or file by
> +qualifying its name
>  using the colon-colon (@code{::}) notation:
>  
>  @cindex colon-colon, context for variables/functions

This hunk seems to be limited to changes in style, rather than
content.  Can you tell why you thought these style changes are needed,
in particular the first one?

Also, I have reservations about using the term "qualifying" for this
notation.  Since we already use "scope resolution" for them in the C++
context, why not use "scope resolution" for C and other languages as
well?

> +unqualified name of the variable.  However, you may also use this notation
> +to refer to local variables in frames enclosing the selected frame:

I'm not sure "enclosing frame" is clear enough.  I think we tend to
use "outer frame" elsewhere in the manual.  Alternatively, you could
use "enclosing scope".

> +@smallexample
> +(@value{GDBP}) p a
> +(@value{GDBP}) p bar::a
> +(@value{GDBP}) up 2
> +(@value{GDBP}) p a
> +(@value{GDBP}) p bar::a
> +
> +@end smallexample

Please remove the empty line before "@end smallexample".

Anyway, this begs the question: is the scope resolution available only
for print commands, or also in other commands, like `watch'?  If the
latter can also use this, then I think we should mention that, here
and where watchpoints are described.  If the `watch' command cannot
use this, then it sounds like we are inconsistent here.

Thanks.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] Have block_innermost_frame start from selected frame
  2011-12-31  8:58 ` Eli Zaretskii
@ 2011-12-31 21:40   ` Paul Hilfinger
  2012-01-09  7:17   ` Paul Hilfinger
  1 sibling, 0 replies; 12+ messages in thread
From: Paul Hilfinger @ 2011-12-31 21:40 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches


> > @@ -7304,12 +7304,13 @@ examine the variable @code{b} while your program is executing inside
> >  the block where @code{b} is declared.
> >  
> >  @cindex variable name conflict
> > -There is an exception: you can refer to a variable or function whose
> > +You can refer to a variable or function whose
> >  scope is a single source file even if the current execution point is not
> >  in this file.  But it is possible to have more than one such variable or
> >  function with the same name (in different source files).  If that
> >  happens, referring to that name has unpredictable effects.  If you wish,
> > -you can specify a static variable in a particular function or file,
> > +you can specify a static variable in a particular function or file by
> > +qualifying its name
> >  using the colon-colon (@code{::}) notation:
> >  
> >  @cindex colon-colon, context for variables/functions
> 
> This hunk seems to be limited to changes in style, rather than
> content.  Can you tell why you thought these style changes are needed,
> in particular the first one?
> 
> Also, I have reservations about using the term "qualifying" for this
> notation.  Since we already use "scope resolution" for them in the C++
> context, why not use "scope resolution" for C and other languages as
> well?
> 

I'm not wed to these changes.  The first one is accidental: I had wanted to
modify the section so that first it talked about unqualified uses and then 
turned to qualified uses, not as an "exception" but rather as a separate case.
Apparently, I neglected to modify the preceding portion to specifically say it
concerned unqualified variables.

The second change was to introduce the term "qualified".  However, it also
corrects a slight problem---that comma after "file," is out of place, I think.
However, if you don't like "qualifying", I am happy to remove both changes.

> > +unqualified name of the variable.  However, you may also use this notation
> > +to refer to local variables in frames enclosing the selected frame:
> 
> I'm not sure "enclosing frame" is clear enough.  I think we tend to
> use "outer frame" elsewhere in the manual.  Alternatively, you could
> use "enclosing scope".
> 

Yeah, but I really need to say something like "frames that are at or outside
the selected frame".  Would that be understandable terminology, do you think?

I don't like "enclosing scope".  We are dealing with statically scoped
languages, where "enclosing scope" usually means "lexically enclosing
scope", and that is not what we are talking about here.

> > +@smallexample
> > +(@value{GDBP}) p a
> > +(@value{GDBP}) p bar::a
> > +(@value{GDBP}) up 2
> > +(@value{GDBP}) p a
> > +(@value{GDBP}) p bar::a
> > +
> > +@end smallexample
> 
> Please remove the empty line before "@end smallexample".

Right.

> Anyway, this begs the question: is the scope resolution available only
> for print commands, or also in other commands, like `watch'?  If the
> latter can also use this, then I think we should mention that, here
> and where watchpoints are described.  If the `watch' command cannot
> use this, then it sounds like we are inconsistent here.
> 
Well, since I don't see any circular arguments here, I wouldn't say
that any questions are being begged [sorry: obligatory pedantry
there], but you are certainly right that it does raise the question of
general applicability.  The section is about "Program variables" but
all examples use 'print'.  Furthermore, you are correct that watch
behaves incorrectly at the moment: it picks up the correct variable
value when 'watch' is issued, but then reverts to the old behavior
when deciding which variable to watch, giving nonsensical results.  I
will have to revise the patch.  Thanks for catching this.

-- 
Paul N. Hilfinger
(Hilfinger@adacore.com)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] Have block_innermost_frame start from selected frame
  2011-12-31  8:58 ` Eli Zaretskii
  2011-12-31 21:40   ` Paul Hilfinger
@ 2012-01-09  7:17   ` Paul Hilfinger
  2012-01-09 17:14     ` Eli Zaretskii
  2012-01-10  5:21     ` Joel Brobecker
  1 sibling, 2 replies; 12+ messages in thread
From: Paul Hilfinger @ 2012-01-09  7:17 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

[-- Attachment #1: Type: text/plain, Size: 2814 bytes --]

This is an update of my previous patch to address a problem that Eli
uncovered: references to BLOCK:LOCAL_VARIABLE did not work in watched
expressions.  In fact, due to a bug, a local variable referred to with
BLOCK:VAR has always been handled incorrectly in 'watch', even if it
is interpreted to refer to the innermost frame associated with BLOCK,
because no breakpoint would be set to remove the watch when the
variable's frame was deallocated.

Eli, your actual comment was a question about whether the syntax
applied to watch (given that all the examples used print).  On
consideration, I decided to keep things as they are, because if the
issue is that it is unclear where variables may be used, it is a
problem that extends to the entire chapter on "Examining Data", and
should be addressed by a rather larger editorial assault.

GDB used to search for the frame containing variables in a particular
lexical block starting from the current (top) frame, ignoring any
currently selected frame.  It is not clear why this is desirable for
variables that require a frame; why would a user deliberately select
one frame and then expect to see the value of a variable in a more
recent frame?  This change causes block_innermost_frame to start
looking from the selected frame, if there is one.

This change is perhaps unnecessarily conservative.  It uses
get_selected_frame_if_set rather than get_selected_frame in order to
avoid the side effect of calling select_frame, which would probably be
harmless.

Second, expression-parsing routines previously made the unwarranted assumption
that all block-qualified variables (written with the GDB extension
<block>::<variable>) are static.  As a result, they failed to update
innermost_block, which confused the watch commands about when variables in
watched expressions went out of scope, and also caused the wrong variables to
be watched.  This change modifies these routines to treat all local variables
the same whether or not they are block-qualified.

Finally, we add a paragraph to the "Program Variables" section of the texinfo
documentation concerning the use of "::" for accessing non-static variables.

Paul N. Hilfinger
(Hilfinger@adacore.com)


2011-12-27  Paul Hilfinger  <hilfingr@adacore.com>

  * gdb/blockframe.c (block_innermost_frame): Start search from selected frame,
    if present, or otherwise the current frame.

  * gdb/c-exp.y, gdb/m2-exp.y, gdb/objc-exp.y: Update innermost_block

  * gdb/doc/gdb.texinfo (Variables): Document use of :: for non-static
    variables.
---
 gdb/blockframe.c    |    9 ++++++---
 gdb/c-exp.y         |    7 +++++++
 gdb/doc/gdb.texinfo |   44 ++++++++++++++++++++++++++++++++++++++++++--
 gdb/m2-exp.y        |    7 +++++++
 gdb/objc-exp.y      |    7 +++++++
 5 files changed, 69 insertions(+), 5 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Have-block_innermost_frame-start-from-selected-frame.patch --]
[-- Type: text/x-patch; name="0001-Have-block_innermost_frame-start-from-selected-frame.patch", Size: 4908 bytes --]

diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index 3897366..1917b68 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -352,8 +352,9 @@ find_pc_partial_function (CORE_ADDR pc, char **name, CORE_ADDR *address,
   return find_pc_partial_function_gnu_ifunc (pc, name, address, endaddr, NULL);
 }
 
-/* Return the innermost stack frame executing inside of BLOCK, or NULL
-   if there is no such frame.  If BLOCK is NULL, just return NULL.  */
+/* Return the innermost stack frame that is executing inside of BLOCK and is
+ * at least as old as the selected frame. Return NULL if there is no
+ * such frame.  If BLOCK is NULL, just return NULL.  */
 
 struct frame_info *
 block_innermost_frame (const struct block *block)
@@ -368,7 +369,9 @@ block_innermost_frame (const struct block *block)
   start = BLOCK_START (block);
   end = BLOCK_END (block);
 
-  frame = get_current_frame ();
+  frame = get_selected_frame_if_set ();
+  if (frame == NULL)
+    frame = get_current_frame ();
   while (frame != NULL)
     {
       struct block *frame_block = get_frame_block (frame, NULL);
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index bdcae33..5b57f24 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -778,6 +778,13 @@ variable:	block COLONCOLON name
 			  if (sym == 0)
 			    error (_("No symbol \"%s\" in specified context."),
 				   copy_name ($3));
+			  if (symbol_read_needs_frame (sym))
+			    {
+			      if (innermost_block == 0
+				  || contained_in (block_found, 
+						   innermost_block))
+				innermost_block = block_found;
+			    }
 
 			  write_exp_elt_opcode (OP_VAR_VALUE);
 			  /* block_found is set by lookup_symbol.  */
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 2f4aa4f..d1a2dde 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -7306,7 +7306,7 @@ scope is a single source file even if the current execution point is not
 in this file.  But it is possible to have more than one such variable or
 function with the same name (in different source files).  If that
 happens, referring to that name has unpredictable effects.  If you wish,
-you can specify a static variable in a particular function or file,
+you can specify a static variable in a particular function or file by
 using the colon-colon (@code{::}) notation:
 
 @cindex colon-colon, context for variables/functions
@@ -7329,8 +7329,48 @@ to print a global value of @code{x} defined in @file{f2.c}:
 (@value{GDBP}) p 'f2.c'::x
 @end smallexample
 
+The @code{::} notation is normally used for referring to
+static variables, since you typically disambiguate uses of local variables
+in functions by selecting the appropriate frame and using the
+simple name of the variable.  However, you may also use this notation
+to refer to local variables in frames enclosing the selected frame:
+
+@smallexample
+void
+foo (int a)
+@{
+  if (a < 10)
+      bar (a);
+  else
+      process (a);    /* Stop here */
+@}
+
+int
+bar (int a)
+@{
+  foo (a + 5);
+@}
+@end smallexample
+
+@noindent
+If you have a breakpoint at the commented line
+when the program executes the call @code{bar(0)}, then when the program
+stops, the commands
+
+@smallexample
+(@value{GDBP}) p a
+(@value{GDBP}) p bar::a
+(@value{GDBP}) up 2
+(@value{GDBP}) p a
+(@value{GDBP}) p bar::a
+@end smallexample
+
+@noindent
+will print the values @samp{10}, @samp{5}, @samp{5}, and @samp{0} in that
+order.
+
 @cindex C@t{++} scope resolution
-This use of @samp{::} is very rarely in conflict with the very similar
+These uses of @samp{::} are very rarely in conflict with the very similar
 use of the same notation in C@t{++}.  @value{GDBN} also supports use of the C@t{++}
 scope resolution operator in @value{GDBN} expressions.
 @c FIXME: Um, so what happens in one of those rare cases where it's in
diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y
index 1e3e3cb..d59678b 100644
--- a/gdb/m2-exp.y
+++ b/gdb/m2-exp.y
@@ -588,6 +588,13 @@ variable:	block COLONCOLON NAME
 			  if (sym == 0)
 			    error (_("No symbol \"%s\" in specified context."),
 				   copy_name ($3));
+			  if (symbol_read_needs_frame (sym))
+			    {
+			      if (innermost_block == 0
+				  || contained_in (block_found, 
+						   innermost_block))
+				innermost_block = block_found;
+			    }
 
 			  write_exp_elt_opcode (OP_VAR_VALUE);
 			  /* block_found is set by lookup_symbol.  */
diff --git a/gdb/objc-exp.y b/gdb/objc-exp.y
index 346b404..00e5e7f 100644
--- a/gdb/objc-exp.y
+++ b/gdb/objc-exp.y
@@ -648,6 +648,13 @@ variable:	block COLONCOLON name
 			  if (sym == 0)
 			    error (_("No symbol \"%s\" in specified context."),
 				   copy_name ($3));
+			  if (symbol_read_needs_frame (sym))
+			    {
+			      if (innermost_block == 0
+				  || contained_in (block_found, 
+						   innermost_block))
+				innermost_block = block_found;
+			    }
 
 			  write_exp_elt_opcode (OP_VAR_VALUE);
 			  /* block_found is set by lookup_symbol.  */

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] Have block_innermost_frame start from selected frame
  2012-01-09  7:17   ` Paul Hilfinger
@ 2012-01-09 17:14     ` Eli Zaretskii
  2012-01-09 19:59       ` Paul Hilfinger
  2012-01-10  5:21     ` Joel Brobecker
  1 sibling, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2012-01-09 17:14 UTC (permalink / raw)
  To: Hilfinger; +Cc: gdb-patches

> From: Paul Hilfinger <Hilfinger@adacore.com>
> CC: gdb-patches@sourceware.org
> Date: Mon,  9 Jan 2012 02:16:45 -0500 (EST)
> 
> Eli, your actual comment was a question about whether the syntax
> applied to watch (given that all the examples used print).  On
> consideration, I decided to keep things as they are

What does this mean? what exactly did you leave unchanged?

And do I need to review the doc patch again, or is it largely
unchanged?

Thanks.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] Have block_innermost_frame start from selected frame
  2012-01-09 17:14     ` Eli Zaretskii
@ 2012-01-09 19:59       ` Paul Hilfinger
  0 siblings, 0 replies; 12+ messages in thread
From: Paul Hilfinger @ 2012-01-09 19:59 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches


> > Eli, your actual comment was a question about whether the syntax
> > applied to watch (given that all the examples used print).  On
> > consideration, I decided to keep things as they are
> 
> What does this mean? what exactly did you leave unchanged?
> 
> And do I need to review the doc patch again, or is it largely
> unchanged?
> 

Sorry.  I meant that you should not have to review the doc/ part of the
patch, which is unchanged since the last time I submitted it.  I did not
add any text specific to watchpoints, etc., on the grounds that the
entire chapter already appears intended to describe expressions in
general, and apparently has been understood as such up until now.

Thanks.

Paul

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] Have block_innermost_frame start from selected frame
  2012-01-09  7:17   ` Paul Hilfinger
  2012-01-09 17:14     ` Eli Zaretskii
@ 2012-01-10  5:21     ` Joel Brobecker
  2012-01-10 10:28       ` Eli Zaretskii
  2012-01-10 10:40       ` Joel Brobecker
  1 sibling, 2 replies; 12+ messages in thread
From: Joel Brobecker @ 2012-01-10  5:21 UTC (permalink / raw)
  To: Paul Hilfinger; +Cc: Eli Zaretskii, gdb-patches

Hi Paul,

> 2011-12-27  Paul Hilfinger  <hilfingr@adacore.com>
> 
>   * gdb/blockframe.c (block_innermost_frame): Start search from selected frame,
>     if present, or otherwise the current frame.
> 
>   * gdb/c-exp.y, gdb/m2-exp.y, gdb/objc-exp.y: Update innermost_block
> 
>   * gdb/doc/gdb.texinfo (Variables): Document use of :: for non-static
>     variables.

When you create an entry in gdb's ChangeLog file, can you remember
to remove the "gdb/" prefix? Also, the doc/ subdirectory has its own
ChangeLog file as well, so remember to remove the "gdb/doc/" prefix
in the filename.

> -/* Return the innermost stack frame executing inside of BLOCK, or NULL
> -   if there is no such frame.  If BLOCK is NULL, just return NULL.  */
> +/* Return the innermost stack frame that is executing inside of BLOCK and is
> + * at least as old as the selected frame. Return NULL if there is no
> + * such frame.  If BLOCK is NULL, just return NULL.  */

Minor issue with formatting: Can you remove the '*' at the start of
the second and third line?

> -  frame = get_current_frame ();
> +  frame = get_selected_frame_if_set ();
> +  if (frame == NULL)
> +    frame = get_current_frame ();

I really flip-flopped on this, between using get_selected_frame_if_set
or just get_selected_frame. In the end, to me, the real difference
between the two is the fact that the second could potentially *change*
the global state (selected frame, language). These could be considered
side-effects while I have a feeling that block_innermost_frame is
a function that should really be pure. So I agree with you that using
get_selected_frame_if_set was the right choice.

> +			  if (symbol_read_needs_frame (sym))
> +			    {
> +			      if (innermost_block == 0
> +				  || contained_in (block_found, 
> +						   innermost_block))
> +				innermost_block = block_found;
> +			    }

I know you copied this from elsewhere in the file, and that elsewhere
also has that extraneous trailing space (`|| contained_in (block_found, '),
but could you remove it from this new hunk?

> +@smallexample
> +void
> +foo (int a)
> +@{
> +  if (a < 10)
> +      bar (a);
> +  else
> +      process (a);    /* Stop here */
> +@}

Nit-picking: The formatting looks a little off for the if and else
blocks.  It would be nicer, I think, if we remained consistent the GDB
style...

Eli?

> +@smallexample
> +(@value{GDBP}) p a
> +(@value{GDBP}) p bar::a
> +(@value{GDBP}) up 2
> +(@value{GDBP}) p a
> +(@value{GDBP}) p bar::a
> +@end smallexample
> +
> +@noindent
> +will print the values @samp{10}, @samp{5}, @samp{5}, and @samp{0} in that
> +order.

My 2 cents: We could also embed the GDB transcript, rather than
having the input on one end, and the output on the other hand.
Not a request to change, just some thoughts...

-- 
Joel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] Have block_innermost_frame start from selected frame
  2012-01-10  5:21     ` Joel Brobecker
@ 2012-01-10 10:28       ` Eli Zaretskii
  2012-01-10 10:40       ` Joel Brobecker
  1 sibling, 0 replies; 12+ messages in thread
From: Eli Zaretskii @ 2012-01-10 10:28 UTC (permalink / raw)
  To: Joel Brobecker; +Cc: Hilfinger, gdb-patches

> Date: Tue, 10 Jan 2012 08:32:13 +0400
> From: Joel Brobecker <brobecker@adacore.com>
> Cc: Eli Zaretskii <eliz@gnu.org>, gdb-patches@sourceware.org
> 
> > +@smallexample
> > +void
> > +foo (int a)
> > +@{
> > +  if (a < 10)
> > +      bar (a);
> > +  else
> > +      process (a);    /* Stop here */
> > +@}
> 
> Nit-picking: The formatting looks a little off for the if and else
> blocks.  It would be nicer, I think, if we remained consistent the GDB
> style...
> 
> Eli?

Using the GNU style is preferable, yes.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFA] Have block_innermost_frame start from selected frame
  2012-01-10  5:21     ` Joel Brobecker
  2012-01-10 10:28       ` Eli Zaretskii
@ 2012-01-10 10:40       ` Joel Brobecker
  2012-01-11 10:59         ` [PATCH 1/3] Have block_innermost_frame start from selected frame and document Hilfinger
  1 sibling, 1 reply; 12+ messages in thread
From: Joel Brobecker @ 2012-01-10 10:40 UTC (permalink / raw)
  To: Paul Hilfinger; +Cc: gdb-patches

> > 2011-12-27  Paul Hilfinger  <hilfingr@adacore.com>
> > 
> >   * gdb/blockframe.c (block_innermost_frame): Start search from selected frame,
> >     if present, or otherwise the current frame.
> > 
> >   * gdb/c-exp.y, gdb/m2-exp.y, gdb/objc-exp.y: Update innermost_block
> > 
> >   * gdb/doc/gdb.texinfo (Variables): Document use of :: for non-static
> >     variables.

I had also meant to say that the patch is pre-approved, once
the small code changes I recommended are applied! Ooops...

Thank you, Paul.
-- 
Joel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 3/3] Add test for use of "<block>::<variable>" syntax for locals in watch.
  2012-01-11 15:54           ` [PATCH 2/3] Add testcase for locals identified with FUNCTION::VAR syntax Hilfinger
@ 2012-01-11 10:59             ` Hilfinger
  0 siblings, 0 replies; 12+ messages in thread
From: Hilfinger @ 2012-01-11 10:59 UTC (permalink / raw)
  To: gdb-patches; +Cc: Paul Hilfinger

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 919 bytes --]

I have committed this patch.

First, fix a technical problem with the function recurser.  The test sets a
watch on local_x at a point where its value is technically undefined.  The
test is written assuming that the value is not initially 2, but nothing in the
C standard guarantees that.

Second, augment the existing test for variables in recursive calls to check an
equivalent expression that explicitly sets the scope of the local variable
being tracked.

2012-01-11  Paul Hilfinger  <hilfingr@adacore.com>

	* gdb.base/watchpoint.c (recurser): Initialize local_x.
	(main): Repeat recurser call.
	* gdb.base/watchpoint.exp: Check that 'watch recurser::local_x' is
	equivalent to 'local_x'.
---
 gdb/testsuite/ChangeLog               |    7 +++++++
 gdb/testsuite/gdb.base/watchpoint.c   |    8 +++++++-
 gdb/testsuite/gdb.base/watchpoint.exp |   14 ++++++++++++++
 3 files changed, 28 insertions(+), 1 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0003-Add-test-for-use-of-block-variable-syntax-for-locals.patch --]
[-- Type: text/x-patch; name="0003-Add-test-for-use-of-block-variable-syntax-for-locals.patch", Size: 3168 bytes --]

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 8c811c9..6e18dfc 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,4 +1,11 @@
 2012-01-11  Paul Hilfinger  <hilfingr@adacore.com>
+
+	* gdb.base/watchpoint.c (recurser): Initialize local_x.
+	(main): Repeat recurser call.
+	* gdb.base/watchpoint.exp: Check that 'watch recurser::local_x' is
+	equivalent to 'local_x'.
+
+2012-01-11  Paul Hilfinger  <hilfingr@adacore.com>
     	    Joel Brobecker <brobecker@adacore.com>
 
 	* gdb.base/recpar.c, gdb.base/recpar.exp: New files.
diff --git a/gdb/testsuite/gdb.base/watchpoint.c b/gdb/testsuite/gdb.base/watchpoint.c
index 50f0a83..88c110f 100644
--- a/gdb/testsuite/gdb.base/watchpoint.c
+++ b/gdb/testsuite/gdb.base/watchpoint.c
@@ -80,7 +80,7 @@ void recurser (int  x)
 void recurser (x) int  x;
 #endif
 {
-  int  local_x;
+  int  local_x = 0;
 
   if (x > 0)
     recurser (x-1);
@@ -232,6 +232,12 @@ int main ()
   marker6 ();
   recurser (2);
 
+  /* This invocation is used for watches of a local variable with explicitly
+     specified scope when recursion happens.
+     */
+  marker6 ();
+  recurser (2);
+
   marker6 ();
 
   func3 ();
diff --git a/gdb/testsuite/gdb.base/watchpoint.exp b/gdb/testsuite/gdb.base/watchpoint.exp
index f321de5..1860368 100644
--- a/gdb/testsuite/gdb.base/watchpoint.exp
+++ b/gdb/testsuite/gdb.base/watchpoint.exp
@@ -580,6 +580,7 @@ proc test_complex_watchpoint {} {
         #
         gdb_test "tbreak recurser" ".*breakpoint.*"
         gdb_test "cont" "Continuing.*recurser.*"
+        gdb_test "next" "if \\(x > 0.*" "next past local_x initialization"
         gdb_test "watch local_x" ".*\[Ww\]atchpoint \[0-9\]*: local_x" \
                  "set local watch in recursive call"
         gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: local_x.*New value = 2.*" \
@@ -587,6 +588,19 @@ proc test_complex_watchpoint {} {
         gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \
                  "self-delete local watch in recursive call"
 
+        # Repeat the preceding test, but this time use "recurser::local_x" as
+        # the variable to track.
+        gdb_test "cont" "Continuing.*marker6.*"
+        gdb_test "tbreak recurser" ".*breakpoint.*"
+        gdb_test "cont" "Continuing.*recurser.*"
+        gdb_test "next" "if \\(x > 0.*" "next past local_x initialization"
+        gdb_test "watch recurser::local_x" ".*\[Ww\]atchpoint \[0-9\]*: recurser::local_x" \
+                 "set local watch in recursive call with explicit scope"
+        gdb_test "cont" "Continuing.*\[Ww\]atchpoint .*: recurser::local_x.*New value = 2.*" \
+                 "trigger local watch with explicit scope in recursive call"
+        gdb_test "cont" "Continuing.*\[Ww\]atchpoint .* deleted because the program has left the block in.*which its expression is valid.*" \
+                 "self-delete local watch with explicit scope in recursive call (2)"
+
 	# Disable everything so we can finish the program at full speed
 	gdb_test_no_output "disable" "disable in test_complex_watchpoint"
 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/3] Have block_innermost_frame start from selected frame and document.
  2012-01-10 10:40       ` Joel Brobecker
@ 2012-01-11 10:59         ` Hilfinger
  2012-01-11 15:54           ` [PATCH 2/3] Add testcase for locals identified with FUNCTION::VAR syntax Hilfinger
  0 siblings, 1 reply; 12+ messages in thread
From: Hilfinger @ 2012-01-11 10:59 UTC (permalink / raw)
  To: gdb-patches; +Cc: Paul Hilfinger

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 2100 bytes --]

I have committed this patch.

GDB used to search for the frame containing variables in a particular
lexical block starting from the current (top) frame, ignoring any
currently selected frame.  It is not clear why this is desirable for
variables that require a frame; why would a user deliberately select
one frame and then expect to see the value of a variable in a more
recent frame?  This change causes block_innermost_frame to start
looking from the selected frame, if there is one.  It may be
unnecessarily conservative: we use get_selected_frame_if_set rather
than get_selected_frame in order to avoid the side effect of calling
select_frame, which would probably be harmless.

Expression-parsing routines previously made the unwarranted assumption
that all block-qualified variables (written with the GDB extension
<block>::<variable>) are static.  As a result, they failed to update
innermost_block, which confused the watch commands about when
variables in watched expressions went out of scope, and also caused
the wrong variables to be watched.  This patch also modifies these
routines to treat all local variables the same whether or not they are
block-qualified.

Finally, we add a paragraph to the "Program Variables" section of the texinfo
documentation concerning the use of "::" for accessing non-static variables.

2012-01-11  Paul Hilfinger  <hilfingr@adacore.com>

	* gdb/blockframe.c (block_innermost_frame): Start search from selected
	frame, if present, or otherwise the current frame.

	* gdb/c-exp.y (variable): Update innermost_block for
	'block COLONCOLON NAME' clause.
	* gdb/m2-exp.y (variable): Ditto.
	* gdb/objc-exp.y (variable): Ditto.

	* gdb/doc/gdb.texinfo (Variables): Document use of :: for non-static
	variables.
---
 gdb/ChangeLog       |   10 ++++++++++
 gdb/blockframe.c    |    9 ++++++---
 gdb/c-exp.y         |    7 +++++++
 gdb/doc/ChangeLog   |    5 +++++
 gdb/doc/gdb.texinfo |   45 +++++++++++++++++++++++++++++++++++++++++++--
 gdb/m2-exp.y        |    7 +++++++
 gdb/objc-exp.y      |    7 +++++++
 7 files changed, 85 insertions(+), 5 deletions(-)


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-Have-block_innermost_frame-start-from-selected-frame.patch --]
[-- Type: text/x-patch; name="0001-Have-block_innermost_frame-start-from-selected-frame.patch", Size: 5810 bytes --]

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 1ac2510..29f2d1e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,13 @@
+2012-01-11  Paul Hilfinger  <hilfingr@adacore.com>
+
+	* blockframe.c (block_innermost_frame): Start search from selected
+	frame, if present, or otherwise the current frame.
+
+	* c-exp.y (variable): Update innermost_block for
+	'block COLONCOLON NAME' clause.
+	* m2-exp.y (variable): Ditto.
+	* objc-exp.y (variable): Ditto.
+
 2012-01-10  Tom Tromey  <tromey@redhat.com>
 
 	PR python/13199:
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index 3897366..cb61cf3 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -352,8 +352,9 @@ find_pc_partial_function (CORE_ADDR pc, char **name, CORE_ADDR *address,
   return find_pc_partial_function_gnu_ifunc (pc, name, address, endaddr, NULL);
 }
 
-/* Return the innermost stack frame executing inside of BLOCK, or NULL
-   if there is no such frame.  If BLOCK is NULL, just return NULL.  */
+/* Return the innermost stack frame that is executing inside of BLOCK and is
+   at least as old as the selected frame. Return NULL if there is no
+   such frame.  If BLOCK is NULL, just return NULL.  */
 
 struct frame_info *
 block_innermost_frame (const struct block *block)
@@ -368,7 +369,9 @@ block_innermost_frame (const struct block *block)
   start = BLOCK_START (block);
   end = BLOCK_END (block);
 
-  frame = get_current_frame ();
+  frame = get_selected_frame_if_set ();
+  if (frame == NULL)
+    frame = get_current_frame ();
   while (frame != NULL)
     {
       struct block *frame_block = get_frame_block (frame, NULL);
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 24a4761..bf4f4bc 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -778,6 +778,13 @@ variable:	block COLONCOLON name
 			  if (sym == 0)
 			    error (_("No symbol \"%s\" in specified context."),
 				   copy_name ($3));
+			  if (symbol_read_needs_frame (sym))
+			    {
+			      if (innermost_block == 0
+				  || contained_in (block_found,
+						   innermost_block))
+				innermost_block = block_found;
+			    }
 
 			  write_exp_elt_opcode (OP_VAR_VALUE);
 			  /* block_found is set by lookup_symbol.  */
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 5a9d2ff..2914190 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2012-01-11  Paul Hilfinger  <hilfingr@adacore.com>
+
+	* gdb.texinfo (Variables): Document use of :: for non-static
+	variables.
+
 2012-01-05  Joel Brobecker  <brobecker@adacore.com>
 
 	* gdbint.texinfo (Start of New Year Procedure): Update
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 2f4aa4f..4a8ff7b 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -7306,7 +7306,7 @@ scope is a single source file even if the current execution point is not
 in this file.  But it is possible to have more than one such variable or
 function with the same name (in different source files).  If that
 happens, referring to that name has unpredictable effects.  If you wish,
-you can specify a static variable in a particular function or file,
+you can specify a static variable in a particular function or file by
 using the colon-colon (@code{::}) notation:
 
 @cindex colon-colon, context for variables/functions
@@ -7329,8 +7329,49 @@ to print a global value of @code{x} defined in @file{f2.c}:
 (@value{GDBP}) p 'f2.c'::x
 @end smallexample
 
+The @code{::} notation is normally used for referring to
+static variables, since you typically disambiguate uses of local variables
+in functions by selecting the appropriate frame and using the
+simple name of the variable.  However, you may also use this notation
+to refer to local variables in frames enclosing the selected frame:
+
+@smallexample
+void
+foo (int a)
+@{
+  if (a < 10)
+    bar (a);
+  else
+    process (a);    /* Stop here */
+@}
+
+int
+bar (int a)
+@{
+  foo (a + 5);
+@}
+@end smallexample
+
+@noindent
+For example, if there is a breakpoint at the commented line,
+here is what you might see
+when the program stops after executing the call @code{bar(0)}:
+
+@smallexample
+(@value{GDBP}) p a
+$1 = 10
+(@value{GDBP}) p bar::a
+$2 = 5
+(@value{GDBP}) up 2
+#2  0x080483d0 in foo (a=5) at foobar.c:12
+(@value{GDBP}) p a
+$3 = 5
+(@value{GDBP}) p bar::a
+$4 = 0
+@end smallexample
+
 @cindex C@t{++} scope resolution
-This use of @samp{::} is very rarely in conflict with the very similar
+These uses of @samp{::} are very rarely in conflict with the very similar
 use of the same notation in C@t{++}.  @value{GDBN} also supports use of the C@t{++}
 scope resolution operator in @value{GDBN} expressions.
 @c FIXME: Um, so what happens in one of those rare cases where it's in
diff --git a/gdb/m2-exp.y b/gdb/m2-exp.y
index 1e3e3cb..ef9ec8e 100644
--- a/gdb/m2-exp.y
+++ b/gdb/m2-exp.y
@@ -588,6 +588,13 @@ variable:	block COLONCOLON NAME
 			  if (sym == 0)
 			    error (_("No symbol \"%s\" in specified context."),
 				   copy_name ($3));
+			  if (symbol_read_needs_frame (sym))
+			    {
+			      if (innermost_block == 0
+				  || contained_in (block_found,
+						   innermost_block))
+				innermost_block = block_found;
+			    }
 
 			  write_exp_elt_opcode (OP_VAR_VALUE);
 			  /* block_found is set by lookup_symbol.  */
diff --git a/gdb/objc-exp.y b/gdb/objc-exp.y
index 346b404..b43ba66 100644
--- a/gdb/objc-exp.y
+++ b/gdb/objc-exp.y
@@ -648,6 +648,13 @@ variable:	block COLONCOLON name
 			  if (sym == 0)
 			    error (_("No symbol \"%s\" in specified context."),
 				   copy_name ($3));
+			  if (symbol_read_needs_frame (sym))
+			    {
+			      if (innermost_block == 0
+				  || contained_in (block_found,
+						   innermost_block))
+				innermost_block = block_found;
+			    }
 
 			  write_exp_elt_opcode (OP_VAR_VALUE);
 			  /* block_found is set by lookup_symbol.  */

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/3] Add testcase for locals identified with FUNCTION::VAR syntax.
  2012-01-11 10:59         ` [PATCH 1/3] Have block_innermost_frame start from selected frame and document Hilfinger
@ 2012-01-11 15:54           ` Hilfinger
  2012-01-11 10:59             ` [PATCH 3/3] Add test for use of "<block>::<variable>" syntax for locals in watch Hilfinger
  0 siblings, 1 reply; 12+ messages in thread
From: Hilfinger @ 2012-01-11 15:54 UTC (permalink / raw)
  To: gdb-patches; +Cc: Paul Hilfinger

[-- Attachment #1: Type: text/plain, Size: 44 bytes --]

This is a multi-part message in MIME format.

[-- Attachment #2: Type: text/plain, Size: 802 bytes --]

I have committed this patch.

This test stops inside a recursive function after a few levels of recursion,
goes up some frames, and then accesses a local variable with 'print foo::val'
rather than the usual 'print val' to see if the former pays attention to the
selected frame.

2012-01-11  Paul Hilfinger  <hilfingr@adacore.com>
    	    Joel Brobecker <brobecker@adacore.com>

	* gdb.base/recpar.c, gdb.base/recpar.exp: New files.
---
 gdb/testsuite/ChangeLog           |    5 ++++
 gdb/testsuite/gdb.base/recpar.c   |   42 +++++++++++++++++++++++++++++++++++++
 gdb/testsuite/gdb.base/recpar.exp |   42 +++++++++++++++++++++++++++++++++++++
 3 files changed, 89 insertions(+), 0 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/recpar.c
 create mode 100644 gdb/testsuite/gdb.base/recpar.exp


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Add-testcase-for-locals-identified-with-FUNCTION-VAR.patch --]
[-- Type: text/x-patch; name="0002-Add-testcase-for-locals-identified-with-FUNCTION-VAR.patch", Size: 3388 bytes --]

diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index c79071c..8c811c9 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-01-11  Paul Hilfinger  <hilfingr@adacore.com>
+    	    Joel Brobecker <brobecker@adacore.com>
+
+	* gdb.base/recpar.c, gdb.base/recpar.exp: New files.
+
 2012-01-05  Pedro Alves  <alves.ped@gmail.com>
 
 	* gdb.mi/mi-stepn.c, gdb.mi/mi-stepn.exp: New files.
diff --git a/gdb/testsuite/gdb.base/recpar.c b/gdb/testsuite/gdb.base/recpar.c
new file mode 100644
index 0000000..e6c3e23
--- /dev/null
+++ b/gdb/testsuite/gdb.base/recpar.c
@@ -0,0 +1,42 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+int
+foo (int n)
+{
+  int val = n;
+
+  {
+    char val = n ? 'y' : 'n'; /* Hides upper-level `val'.  */
+
+    if (val == 'y') /* BREAK */
+      return n + foo (n - 1);
+  }
+
+  return 0;
+}
+
+int
+main (void)
+{
+  int res = foo (5);
+
+  if (res != 15) /* Dummy use of variable res.  */
+    return 1;
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/recpar.exp b/gdb/testsuite/gdb.base/recpar.exp
new file mode 100644
index 0000000..6dd466b
--- /dev/null
+++ b/gdb/testsuite/gdb.base/recpar.exp
@@ -0,0 +1,42 @@
+# Copyright (C) 2012 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+set testfile recpar
+set srcfile ${testfile}.c
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } {
+    return -1
+}
+
+if ![runto_main] {
+    untested ${testfile}.exp
+    return -1
+}
+
+gdb_test "break $srcfile:[gdb_get_line_number BREAK $srcfile] if n == 3" \
+         "Breakpoint $decimal at $hex: file .*recpar\\.c, line $decimal\\."
+
+gdb_test "continue" \
+         "Breakpoint .* foo \\(n=3\\) at .*$srcfile:$decimal.*"
+
+gdb_test "backtrace" \
+         "#0 +foo \\(n=3\\).*\r\n#1.* foo \\(n=4\\).*\r\n#2.* foo \\(n=5\\).*#3.* main \\(\\).*"
+
+gdb_test "frame 2" \
+         "#2 .* foo \\(n=5\\) .*"
+
+# In the currently selected frame, n=5, and thus foo::val should be 5
+# as well.
+gdb_test "print foo::val" \
+         " = 5"

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2012-01-11 10:59 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-30 21:54 [RFA] Have block_innermost_frame start from selected frame Paul Hilfinger
2011-12-31  8:58 ` Eli Zaretskii
2011-12-31 21:40   ` Paul Hilfinger
2012-01-09  7:17   ` Paul Hilfinger
2012-01-09 17:14     ` Eli Zaretskii
2012-01-09 19:59       ` Paul Hilfinger
2012-01-10  5:21     ` Joel Brobecker
2012-01-10 10:28       ` Eli Zaretskii
2012-01-10 10:40       ` Joel Brobecker
2012-01-11 10:59         ` [PATCH 1/3] Have block_innermost_frame start from selected frame and document Hilfinger
2012-01-11 15:54           ` [PATCH 2/3] Add testcase for locals identified with FUNCTION::VAR syntax Hilfinger
2012-01-11 10:59             ` [PATCH 3/3] Add test for use of "<block>::<variable>" syntax for locals in watch Hilfinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).