public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <andrew.burgess@embecosm.com>
To: Natalia Saiapova <natalia.saiapova@intel.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH v2 2/6] gdb/infrun: in condition evaluation resume only current thread.
Date: Tue, 2 Mar 2021 11:15:25 +0000	[thread overview]
Message-ID: <20210302111525.GP265215@embecosm.com> (raw)
In-Reply-To: <20201009112719.629-3-natalia.saiapova@intel.com>

* Natalia Saiapova via Gdb-patches <gdb-patches@sourceware.org> [2020-10-09 13:27:14 +0200]:

> When stopped at a conditional BP, GDB evaluates the condition for the
> event thread in order to decide whether the thread should be stopped or
> resumed.  Thus, if the condition includes an inferior call, during
> the call not all threads have finalized state, some of them might
> still be shown as running.  While executing the proceed for the inferior
> call, GDB tries to resume all non-exited threads.  This leads to
> the following assertion, when GDB tries to resume a running thread:
> 
>     (gdb) b 43 if foo()
>     Breakpoint 1 at 0x119b: file main.c, line 43.
>     (gdb) run
>     Starting program: main
>     [Thread debugging using libthread_db enabled]
>     Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
>     [New Thread 0x7ffff77c4700 (LWP 21421)]
>     [New Thread 0x7ffff6fc3700 (LWP 21422)]
>     gdb/nat/x86-linux-dregs.c:146: internal-error: void x86_linux_update_debug_registers(lwp_info*): Assertion `lwp_is_stopped (lwp)' failed.
>     A problem internal to GDB has been detected,
>     further debugging may prove unreliable.
> 
>     This is a bug, please report it.  For instructions, see:
>     <https://www.gnu.org/software/gdb/bugs/>.
> 
> This patch changes the behavior, so if the current thread is in the
> middle of a condition evaluation, only the current thread is resumed.
> 
> gdb/ChangeLog:
> 2020-08-26  Natalia Saiapova  <natalia.saiapova@intel.com>
> 	    Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
> 
> 	* infrun.c (user_visible_resume_ptid): In BP condition
> 	evaluation, resume only the current thread

This patch is definitely going to need a test.

Maybe some of the tests you add in later patch(es) cover this case,
but ideally tests should be included in the patch that fixes the
issue.

The reason why bundling tests with the patch is good thing is that if
in the future I'm run into a problem with this patch then I can easily
(git blame) find this patch.  If the tests are included in the same
commit then I know that if I modify this code then these specific
tests must still work.

But, I hear you say, surely I run all tests when changing GDB?  Yes,
but as GDB changes it might be that the test you add now no longer
exercises this code, thus, removing, or changing, this code might no
longer cause the tests you add to fail.  At that point I'm stuck, this
code is basically untested.  If I have the tests included in this
commit then I can start to dig in to figure out why this code is no
longer needed for those tests to pass.

> 
> Co-authored-by: Natalia Saiapova <natalia.saiapova@intel.com>
> Co-authored-by: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
> 
> Signed-off-by: Natalia Saiapova <natalia.saiapova@intel.com>
> ---
>  gdb/infrun.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/gdb/infrun.c b/gdb/infrun.c
> index d552fb3adb2..91271c2ddbe 100644
> --- a/gdb/infrun.c
> +++ b/gdb/infrun.c
> @@ -2156,6 +2156,14 @@ user_visible_resume_ptid (int step)
>  	 mode.  */
>        resume_ptid = inferior_ptid;
>      }
> +  else if (inferior_ptid != null_ptid
> +	   && inferior_thread ()->control.in_cond_eval)
> +    {
> +      /* The inferior thread is evaluating a BP condition.  Other threads
> +	 might be stopped or running and we do not want to change their
> +	 state, thus, resume only the current thread.  */
> +      resume_ptid = inferior_ptid;
> +    }

I'm not sure about this.  We set threads going during an inferior call
so that any cross-thread interaction will not block.  At a minimum
this probably requires additional documentation.

I'd be interested to understand more about the different states that a
thread might be in here, and what conditions might put them into that
state.

If we assume a process with threads A, B, and C, then what happens is:

  1. Thread A bits conditional breakpoint, threads B & C are still
  running,

  2. GDB spots A has stopped and needs to execute the condition.

In this case we should only resume A as B & C are still running.  But,
we might also have:

  1. Thread A hits condition breakpoint, threads B & C are still
  running,

  2. Thread B hits condition breakpoint, thread C is still running,

  3. GDB spots A has stopped and needs to execute the condition.

In this case it's not clear what you would do... if you resume B to
evaluate A then you'll miss B's breakpoint hit.  But neither can you
evaluate B as that would require setting A running again.

Hmm, I think I've probably convinced myself that your approach might
be the only safe solution.

I think that I'd like to see the commit message expanded to give more
depth rather than just saying: "...some of them might still be shown
as running", I think you should say, what states a thread could be in
and why.  Also I think this probably is worth documenting in the
manual (that b/p conditions might be evaluated with some threads
stopped, even when running in all-stop mode).

Thanks,
Andrew

>    else if (!sched_multi && target_supports_multi_process ())
>      {
>        /* Resume all threads of the current process (and none of other
> -- 
> 2.17.1
> 
> Intel Deutschland GmbH
> Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
> Tel: +49 89 99 8853-0, www.intel.de
> Managing Directors: Christin Eisenschmid, Gary Kershaw
> Chairperson of the Supervisory Board: Nicole Lau
> Registered Office: Munich
> Commercial Register: Amtsgericht Muenchen HRB 186928
> 

  reply	other threads:[~2021-03-02 11:15 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20200831123519.16232-1-natalia.saiapova () intel ! com>
2020-10-09 11:27 ` [PATCH v2 0/6] Fix inferior calls from breakpoint condition Natalia Saiapova
2020-10-09 11:27   ` [PATCH v2 1/6] gdb: add in_cond_eval field to thread_control_state struct Natalia Saiapova
2021-03-02 10:43     ` Andrew Burgess
2020-10-09 11:27   ` [PATCH v2 2/6] gdb/infrun: in condition evaluation resume only current thread Natalia Saiapova
2021-03-02 11:15     ` Andrew Burgess [this message]
2020-10-09 11:27   ` [PATCH v2 3/6] gdb/infcall: in condition evaluation register target back after infcall Natalia Saiapova
2020-10-19  0:53     ` Kevin Buettner
2021-03-02 11:26     ` Andrew Burgess
2020-10-09 11:27   ` [PATCH v2 4/6] gdb/infrun: in condition evaluation wait only for the current inferior Natalia Saiapova
2020-10-19  1:44     ` Kevin Buettner
2020-10-26 12:11       ` Saiapova, Natalia
2021-03-02 12:17         ` Andrew Burgess
2020-10-09 11:27   ` [PATCH v2 5/6] gdb/infrun: in condition evaluation do not stop all threads Natalia Saiapova
2020-10-09 11:27   ` [PATCH v2 6/6] gdb/testsuite: add tests for inferior calls in breakpoint conditions Natalia Saiapova
2020-10-12  0:49   ` [PATCH v2 0/6] Fix inferior calls from breakpoint condition Kevin Buettner

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=20210302111525.GP265215@embecosm.com \
    --to=andrew.burgess@embecosm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=natalia.saiapova@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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).