Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Joel Brobecker <brobecker@adacore.com>
To: Sergio Durigan Junior <sergiodj@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH] Forbid watchpoint on a constant value
Date: Sat, 29 May 2010 00:04:00 -0000	[thread overview]
Message-ID: <20100528231122.GO3019@adacore.com> (raw)
In-Reply-To: <201005211912.39680.sergiodj@redhat.com>

Hello,

Based on the feedback, it looks like most people would prefer an error
over a warning. So let's go with that.

Overall, this patch is OK. I just have several little comments...

> +/* This checks if each element of EXP is not a
> +   constant expression for a watchpoint.
> +
> +   Returns 1 if EXP is constant, 0 otherwise.  */

We usually use a more imperative style: "do this, do that", as opposed
to "this does this, this does that".  The negation seems a little weird
too.  It's no biggie, but I think that your line length is quite shorter
than usual, making the comment a little odd... Here's a suggestion as
a starting point:

/* Return non-zero iff EXP is an expression whose value can never change.  */

> +static int
> +watchpoint_exp_is_const (struct expression *exp)

Just a thought that crossed my mind: Can this parameter be declared as
a const?

> +	/* UNOP_IND is not in this list becase it can
> +	   be used in expressions like:
> +
> +	   (gdb) watch *0x12345678
> +	   */

Glad to see that you added a comment explaining why UNOP_IND has
been excluded here. Just a nit again about formatting, can you make
the first couple of lines longer?

        /* UNOP_IND is not in this list becase it can be used in expressions
           like:

	   (gdb) watch *0x12345678
	   */

I'm also going to suggest a few things, but they are probably a matter
of taste and style, so feel free to ignore if you don't really agree.
I'd probably make the comments a little more conceptual and less based
on actual examples.  That way, we know what you are trying to do.  For
instance:

        /* Unary, binary and ternary operators: We have to check their
           operands.  If they are constant, then so is the result of
           that operation.  For instance, if A and B are determined to be
           constants, then so is "A + B".

           UNOP_IND is one exception to the rule above, because the value
           of *ADDR is not necessarily a constant, even when ADDR is.  */

> +	/* If it's an OP_VAR_VALUE, then we must check if the `symbol'
> +	   element does not correspond to a function or to a constant
> +	   value.  If it does, then it is a constant address.  */

Same stylistic remark as at the beginning: The use of the negation here
makes things a little confusing.  How about:

  - Moving the comment inside the case, that way we don't have to say
    "if it's an OP_VAR_VALUE", it's just (obviously) implicit;
    (note: Perhaps we should do the same for the unary/b/t operators
    above too)

  - Write something like that:

       /* Check whether the associated symbol is a constant.
          We use the symbol class rather than the type because [...].
          We also have to be careful that function symbols are not
          always indicative of a constant, due to the fact that this
          expression might be calling that function.  */

    (PS: I don't know if the comment explaining why we exclude functions
    is totally accurate)...

> +	/* The default action is to return 0 because we are using
> +	   the optimistic approach here: if we don't know something,
> +	   then it is not a constant.  */
> +	default:

Capital 'I' after the colon...

>    exp_valid_block = innermost_block;
>    mark = value_mark ();
>    fetch_watchpoint_value (exp, &val, NULL, NULL);
> +
> +  /* Checking if the expression is not constant.  */
> +  if (watchpoint_exp_is_const (exp))
> +    {
> +      int len;
> +
> +      len = exp_end - exp_start;
> +      while (len > 0 && isspace (exp_start[len - 1]))
> +	len--;
> +      error (_("Cannot watch constant value %.*s."), len, exp_start);
> +    }

Can we move that block up a bit? You're being fancy by removing
leading spaces, so that means we have to wait until exp_end is
fully computed.  So how about moving it up to just before
"exp_valid_block = ..."?   That way, we don't end up fetching
the expression value if we are not going to create the watchpoint.

Also, one tiny little thing - should we quote the expression in
the error message? I think so...

        error (_("Cannot watch constant value `%.*s.'"), len, exp_start);

> +proc test_constant_watchpoint {} {
> +    global gdb_prompt
       ^^^^^^^^^^^^^^^^^
       unused

> +	gdb_test "watch 5" "Cannot watch constant value 5." "number is constant"
> +	gdb_test "watch marker1" "Cannot watch constant value marker1." \
> +		 "marker1 is constant"
> +	gdb_test "watch count + 6" ".*atchpoint \[0-9\]+: count \\+ 6"
> +	gdb_test "set \$expr_breakpoint_number = \$bpnum" ""

Can you use the new "gdb_test_no_output" function for all tests where
the output is expected to be empty? gdb_test_no_output actually verifies
that the output is empty, whereas gdb_test does not (the test above
pretty-much passes no matter what happens).  

> +	gdb_test_multiple "next" "next over global_ptr_ptr init" {
> +	    -re ".*atchpoint \[0-9\]+: \\*\\*global_ptr_ptr\r\n\r\nOld value = .*\r\nNew value = 7 .*\r\n.*$gdb_prompt $" {
> +		# We can not test for <unknown> here because NULL may be readable.
> +		# This test does rely on *NULL != 7.
> +		pass "next over global_ptr_ptr init"
> +	    }
> +	}
> +	gdb_test_multiple "next" "next over global_ptr_ptr buffer set" {
> +	    -re ".*atchpoint \[0-9\]+: \\*\\*global_ptr_ptr\r\n\r\nOld value = 7 .*\r\nNew value = 9 .*\r\n.*$gdb_prompt $" {
> +		pass "next over global_ptr_ptr buffer set"
> +	    }
> +	}
> +	gdb_test_multiple "next" "next over global_ptr_ptr pointer advance" {
> +	    -re ".*atchpoint \[0-9\]+: \\*\\*global_ptr_ptr\r\n\r\nOld value = 9 .*\r\nNew value = 5 .*\r\n.*$gdb_prompt $" {
> +		pass "next over global_ptr_ptr pointer advance"
> +	    }
> +	}

I'm wondering why you are using gdb_test_multiple in these cases, rather
than just gdb_test?

> +    # See above.
> +    if [istarget "mips-idt-*"] then {
> +	gdb_exit
> +	gdb_start
> +	gdb_reinitialize_dir $srcdir/$subdir
> +	gdb_load $binfile
> +	initialize

The "gdb_exit ... gdb_load" part of the above can be simplified by
using: clean_restart.  I should probably add that to the wiki (we have
a cookbook on how to write testcases).

> +   The purpose of this test is to see if GDB can still watch the
> +   variable `x' even when we compile the program using -O2
> +   optimization.  */

There is no variable 'x' in this code, so I think we should expand on
where this variable is defined (inside which function, from which file,
etc).

> +if {![istarget *-*-linux*]
> +    && ![istarget *-*-gnu*]
> +    && ![istarget *-*-elf*]
> +    && ![istarget *-*-openbsd*]
> +    && ![istarget arm-*-eabi*]
> +    && ![istarget powerpc-*-eabi*]} {
> +    return 0  
> +}

We need to add a comment explaining why... Is it because we need
a specific assembler/linker?

-- 
Joel


  reply	other threads:[~2010-05-28 23:11 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-18 17:36 Sergio Durigan Junior
2010-05-18 17:49 ` Eli Zaretskii
2010-05-18 19:24   ` Sergio Durigan Junior
2010-05-18 23:08 ` Jan Kratochvil
2010-05-18 23:50   ` Sergio Durigan Junior
2010-05-19 20:26     ` Jan Kratochvil
2010-05-20  6:21       ` Sergio Durigan Junior
2010-05-20 15:50         ` Jan Kratochvil
2010-05-20 16:24           ` Sergio Durigan Junior
2010-05-20 17:03             ` Jan Kratochvil
2010-05-20 17:06               ` Sergio Durigan Junior
2010-05-27 21:54             ` Tom Tromey
2010-05-20 23:23 ` Joel Brobecker
2010-05-20 23:31   ` Sergio Durigan Junior
2010-05-20 23:55     ` Joel Brobecker
2010-05-21  0:09       ` Sergio Durigan Junior
2010-05-21  7:05         ` Eli Zaretskii
2010-05-21  8:44   ` Jan Kratochvil
2010-05-21 21:43     ` Sergio Durigan Junior
2010-05-21 22:20       ` Sergio Durigan Junior
2010-05-29  0:04         ` Joel Brobecker [this message]
2010-06-04 13:54           ` Jan Kratochvil
2010-06-04 16:49             ` Tom Tromey
2010-06-05  5:35           ` Sergio Durigan Junior
2010-06-05 14:38             ` Jan Kratochvil
2010-06-06  0:20               ` Sergio Durigan Junior
2010-06-15 17:30             ` Tom Tromey
2010-06-16 18:33               ` Sergio Durigan Junior
2010-06-16 18:36                 ` Jan Kratochvil
2010-05-28  5:12     ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100528231122.GO3019@adacore.com \
    --to=brobecker@adacore.com \
    --cc=gdb-patches@sourceware.org \
    --cc=sergiodj@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox