From: Simon Marchi <simark@simark.ca>
To: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>,
gdb-patches@sourceware.org
Subject: Re: [PATCH 2/3] gdb/breakpoint: set the condition exp after parsing the condition successfully
Date: Wed, 22 Jul 2020 09:21:37 -0400 [thread overview]
Message-ID: <341eb335-db50-82ce-4dc9-2b5d53765dd6@simark.ca> (raw)
In-Reply-To: <abbaf608231cfc4e65471f4efa115854dc455d52.1593438119.git.tankut.baris.aktemur@intel.com>
On 2020-06-29 9:48 a.m., Tankut Baris Aktemur via Gdb-patches wrote:
> In 'set_breakpoint_condition', GDB resets the condition expressions
> before parsing the condition input by the user. This leads to the
> problem of losing the condition expressions if the new condition
> does not parse successfully and is thus rejected.
>
> For instance:
>
> $ gdb ./test
> Reading symbols from ./test...
> (gdb) start
> Temporary breakpoint 1 at 0x114e: file test.c, line 4.
> Starting program: test
>
> Temporary breakpoint 1, main () at test.c:4
> 4 int a = 10;
> (gdb) break 5
> Breakpoint 2 at 0x555555555155: file test.c, line 5.
>
> Now define a condition that would evaluate to false. Next, attempt
> to overwrite that with an invalid condition:
>
> (gdb) cond 2 a == 999
> (gdb) cond 2 gibberish
> No symbol "gibberish" in current context.
> (gdb) info breakpoints
> Num Type Disp Enb Address What
> 2 breakpoint keep y 0x0000555555555155 in main at test.c:5
> stop only if a == 999
>
> It appears as if the bad condition is successfully rejected. But if we
> resume the program, we see that we hit the breakpoint although the condition
> would evaluate to false.
>
> (gdb) continue
> Continuing.
>
> Breakpoint 2, main () at test.c:5
> 5 a = a + 1; /* break-here */
>
> Fix the problem by not resetting the condition expressions before
> parsing the condition input.
>
> Suppose the fix is applied. A similar problem could occur if the
> condition is valid, but has "junk" at the end. In this case, parsing
> succeeds, but an error is raised immediately after. It is too late,
> though; the condition expression is already updated.
>
> For instance:
>
> $ gdb ./test
> Reading symbols from ./test...
> (gdb) start
> Temporary breakpoint 1 at 0x114e: file test.c, line 4.
> Starting program: test
>
> Temporary breakpoint 1, main () at test.c:4
> 4 int a = 10;
> (gdb) break 5
> Breakpoint 2 at 0x555555555155: file test.c, line 5.
> (gdb) cond 2 a == 999
> (gdb) cond 2 a == 10 if
> Junk at end of expression
> (gdb) info breakpoints
> Num Type Disp Enb Address What
> 2 breakpoint keep y 0x0000555555555155 in main at test.c:5
> stop only if a == 999
> (gdb) c
> Continuing.
>
> Breakpoint 2, main () at test.c:5
> 5 a = a + 1; /* break-here */
> (gdb)
>
> We should not have hit the breakpoint because the condition would
> evaluate to false.
>
> Fix this problem by updating the condition expression of the breakpoint
> after parsing the input successfully and checking that there is no
> remaining junk.
>
> gdb/ChangeLog:
> 2020-06-29 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
>
> * breakpoint.c (set_breakpoint_condition): Update the condition
> expressions after checking that the input condition string parses
> successfully and does not contain junk at the end.
>
> gdb/testsuite/ChangeLog:
> 2020-06-29 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
>
> * gdb.base/condbreak-bad.exp: Extend the test with scenarios
> that attempt to overwrite and existing condition with a condition
> that fails parsing and also with a condition that parses fine
> but contains junk at the end.
> ---
> gdb/breakpoint.c | 46 +++++++------
> gdb/testsuite/gdb.base/condbreak-bad.exp | 88 ++++++++++++++++++++++++
> 2 files changed, 112 insertions(+), 22 deletions(-)
>
> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
> index 1fc2d1b8966..abda470fe21 100644
> --- a/gdb/breakpoint.c
> +++ b/gdb/breakpoint.c
> @@ -834,30 +834,30 @@ void
> set_breakpoint_condition (struct breakpoint *b, const char *exp,
> int from_tty)
> {
> - if (is_watchpoint (b))
> - {
> - struct watchpoint *w = (struct watchpoint *) b;
> -
> - w->cond_exp.reset ();
> - }
> - else
> + if (*exp == 0)
> {
> - struct bp_location *loc;
> + xfree (b->cond_string);
> + b->cond_string = nullptr;
>
> - for (loc = b->loc; loc; loc = loc->next)
> + if (is_watchpoint (b))
> {
> - loc->cond.reset ();
> + struct watchpoint *w = (struct watchpoint *) b;
>
> - /* No need to free the condition agent expression
> - bytecode (if we have one). We will handle this
> - when we go through update_global_location_list. */
> + w->cond_exp.reset ();
> }
> - }
> + else
> + {
> + struct bp_location *loc;
>
> - if (*exp == 0)
> - {
> - xfree (b->cond_string);
> - b->cond_string = nullptr;
> + for (loc = b->loc; loc; loc = loc->next)
> + {
> + loc->cond.reset ();
> +
> + /* No need to free the condition agent expression
> + bytecode (if we have one). We will handle this
> + when we go through update_global_location_list. */
> + }
> + }
Since you touch this, might as well declare the `bp_location *loc` in the for loop
and use `loc != nullptr`.
Otherwise, this LGTM.
Simon
next prev parent reply other threads:[~2020-07-22 13:21 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-29 13:48 [PATCH 0/3] Prevent bad conditions from putting breakpoints into broken state Tankut Baris Aktemur
2020-06-29 13:48 ` [PATCH 1/3] gdb/breakpoint: do not update the condition string if parsing the condition fails Tankut Baris Aktemur
2020-07-22 13:12 ` Simon Marchi
2020-07-22 13:15 ` Simon Marchi
2020-06-29 13:48 ` [PATCH 2/3] gdb/breakpoint: set the condition exp after parsing the condition successfully Tankut Baris Aktemur
2020-07-22 13:21 ` Simon Marchi [this message]
2020-07-22 13:28 ` Simon Marchi
2020-07-22 15:29 ` Aktemur, Tankut Baris
2020-07-22 16:06 ` Simon Marchi
2020-07-23 7:11 ` Aktemur, Tankut Baris
2020-07-30 10:56 ` Aktemur, Tankut Baris
2020-07-30 15:15 ` Simon Marchi
2020-06-29 13:48 ` [PATCH 3/3] gdb/breakpoint: refactor 'set_breakpoint_condition' Tankut Baris Aktemur
2020-07-13 8:45 ` [PATCH 0/3] Prevent bad conditions from putting breakpoints into broken state Tankut Baris Aktemur
2020-07-21 9:08 ` Tankut Baris Aktemur
2020-07-22 18:24 ` Pedro Alves
2020-07-23 7:13 ` Aktemur, Tankut Baris
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=341eb335-db50-82ce-4dc9-2b5d53765dd6@simark.ca \
--to=simark@simark.ca \
--cc=gdb-patches@sourceware.org \
--cc=tankut.baris.aktemur@intel.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