qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: Roque Arcudia Hernandez <roqueh@google.com>
Cc: richard.henderson@linaro.org,  pbonzini@redhat.com,
	 philmd@linaro.org, slongfield@google.com,  komlodi@google.com,
	 qemu-devel@nongnu.org
Subject: Re: [PATCH 2/2] gdbstub: Apply breakpoints only to the selected PID
Date: Mon, 07 Oct 2024 11:15:42 +0100	[thread overview]
Message-ID: <87set8w75d.fsf@draig.linaro.org> (raw)
In-Reply-To: <20240906225451.1039718-3-roqueh@google.com> (Roque Arcudia Hernandez's message of "Fri, 6 Sep 2024 15:54:51 -0700")

Roque Arcudia Hernandez <roqueh@google.com> writes:

> In the context of using the remote gdb with multiple
> processes/inferiors (multi cluster machine) a given breakpoint will
> target an specific inferior. Current implementation of
> tcg_insert_breakpoint and tcg_remove_breakpoint apply a given
> breakpoint to all the cpus available in the system.

OK I can see this needs fixing.

> Only the CPUs associated with the selected process ID should insert
> or remove the breakpoint. It is important to apply it to all the CPUs
> in the process ID regardless of the particular thread selected by the
> 'Hg' packet because even in the case of a thread specific breakpoint.
> A breakpoint on a specific thread is treated as a conditional break
> similar to a 'break if'. This can be read in the code and comments of
> function bpstat_check_breakpoint_conditions in the file
> gdb/breakpoint.c
>
> /* For breakpoints that are currently marked as telling gdb to stop,
>    check conditions (condition proper, frame, thread and ignore count)
>    of breakpoint referred to by BS.  If we should not stop for this
>    breakpoint, set BS->stop to 0.  */
>
> static void
> bpstat_check_breakpoint_conditions (bpstat *bs, thread_info *thread)
>
> The patch needs to expose the currently private function
> gdb_get_cpu_pid to the TCG and also expose the value of
> gdbserver_state.multiprocess. The PID filtering will only be
> applicable to multiprocess gdb because the PIDs are only defined in
> that context.

I don't like exposing those private functions, especially as the PID
terminology is confusing. Could we not keep all the logic in the gdbstub
itself so the tests become something like:

    case GDB_BREAKPOINT_SW:
    case GDB_BREAKPOINT_HW:
        CPU_FOREACH(cpu) {
            if (gdb_cpu_in_source_group(cs, cpu)) {
                err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
                if (err) {
                    break;
                }
            }
        }
        return err;

?

Ilya has also posted a large series for non-stop mode on *-user guests
which is on my review queue which I would want to check doesn't conflict
with this:

  Message-ID: <20240923162208.90745-1-iii@linux.ibm.com>
  Date: Mon, 23 Sep 2024 18:12:55 +0200
  Subject: [PATCH 00/18] Stop all qemu-cpu threads on a breakpoint
  From: Ilya Leoshkevich <iii@linux.ibm.com>

>
> Google-Bug-Id: 355027002
> Signed-off-by: Roque Arcudia Hernandez <roqueh@google.com>
> ---
>  accel/tcg/tcg-accel-ops.c | 15 +++++++++++++++
>  gdbstub/gdbstub.c         |  7 ++++++-
>  include/exec/gdbstub.h    | 15 +++++++++++++++
>  3 files changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/accel/tcg/tcg-accel-ops.c b/accel/tcg/tcg-accel-ops.c
> index 3c19e68a79..557091c15e 100644
> --- a/accel/tcg/tcg-accel-ops.c
> +++ b/accel/tcg/tcg-accel-ops.c
> @@ -33,6 +33,7 @@
>  #include "qemu/guest-random.h"
>  #include "qemu/timer.h"
>  #include "exec/exec-all.h"
> +#include "exec/gdbstub.h"
>  #include "exec/hwaddr.h"
>  #include "exec/tb-flush.h"
>  #include "gdbstub/enums.h"
> @@ -132,11 +133,15 @@ static int tcg_insert_breakpoint(CPUState *cs, int type, vaddr addr, vaddr len)
>  {
>      CPUState *cpu;
>      int err = 0;
> +    bool match_pid = gdb_is_multiprocess();
>  
>      switch (type) {
>      case GDB_BREAKPOINT_SW:
>      case GDB_BREAKPOINT_HW:
>          CPU_FOREACH(cpu) {
> +            if (match_pid && gdb_get_cpu_pid(cpu) != gdb_get_cpu_pid(cs)) {
> +                continue;
> +            }
>              err = cpu_breakpoint_insert(cpu, addr, BP_GDB, NULL);
>              if (err) {
>                  break;
> @@ -147,6 +152,9 @@ static int tcg_insert_breakpoint(CPUState *cs, int type, vaddr addr, vaddr len)
>      case GDB_WATCHPOINT_READ:
>      case GDB_WATCHPOINT_ACCESS:
>          CPU_FOREACH(cpu) {
> +            if (match_pid && gdb_get_cpu_pid(cpu) != gdb_get_cpu_pid(cs)) {
> +                continue;
> +            }
>              err = cpu_watchpoint_insert(cpu, addr, len,
>                                          xlat_gdb_type(cpu, type), NULL);
>              if (err) {
> @@ -163,11 +171,15 @@ static int tcg_remove_breakpoint(CPUState *cs, int type, vaddr addr, vaddr len)
>  {
>      CPUState *cpu;
>      int err = 0;
> +    bool match_pid = gdb_is_multiprocess();
>  
>      switch (type) {
>      case GDB_BREAKPOINT_SW:
>      case GDB_BREAKPOINT_HW:
>          CPU_FOREACH(cpu) {
> +            if (match_pid && gdb_get_cpu_pid(cpu) != gdb_get_cpu_pid(cs)) {
> +                continue;
> +            }
>              err = cpu_breakpoint_remove(cpu, addr, BP_GDB);
>              if (err) {
>                  break;
> @@ -178,6 +190,9 @@ static int tcg_remove_breakpoint(CPUState *cs, int type, vaddr addr, vaddr len)
>      case GDB_WATCHPOINT_READ:
>      case GDB_WATCHPOINT_ACCESS:
>          CPU_FOREACH(cpu) {
> +            if (match_pid && gdb_get_cpu_pid(cpu) != gdb_get_cpu_pid(cs)) {
> +                continue;
> +            }
>              err = cpu_watchpoint_remove(cpu, addr, len,
>                                          xlat_gdb_type(cpu, type));
>              if (err) {
> diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c
> index 98574eba68..628e599692 100644
> --- a/gdbstub/gdbstub.c
> +++ b/gdbstub/gdbstub.c
> @@ -199,7 +199,12 @@ void gdb_memtox(GString *buf, const char *mem, int len)
>      }
>  }
>  
> -static uint32_t gdb_get_cpu_pid(CPUState *cpu)
> +bool gdb_is_multiprocess(void)
> +{
> +    return gdbserver_state.multiprocess;
> +}
> +
> +uint32_t gdb_get_cpu_pid(CPUState *cpu)
>  {
>  #ifdef CONFIG_USER_ONLY
>      return getpid();
> diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
> index d73f424f56..a7c95d215b 100644
> --- a/include/exec/gdbstub.h
> +++ b/include/exec/gdbstub.h
> @@ -138,6 +138,21 @@ GArray *gdb_get_register_list(CPUState *cpu);
>  
>  void gdb_set_stop_cpu(CPUState *cpu);
>  
> +/**
> + * gdb_get_cpu_pid() - Get the PID assigned to a CPU
> + * @cpu - the CPU to query
> + *
> + * Return: The PID associated with the cpu
> + */
> +uint32_t gdb_get_cpu_pid(CPUState *cpu);
> +
> +/**
> + * gdb_is_multiprocess() - Tells if the gdb server supports multiple processes
> + *
> + * Return: True if supported
> + */
> +bool gdb_is_multiprocess(void);
> +
>  /* in gdbstub-xml.c, generated by scripts/feature_to_c.py */
>  extern const GDBFeature gdb_static_features[];

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro


  reply	other threads:[~2024-10-07 10:16 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-06 22:54 [PATCH 0/2] Fix for multi-process gdbstub breakpoints Roque Arcudia Hernandez
2024-09-06 22:54 ` [PATCH 1/2] gdbstub: Fix wrong CPUState pointer in breakpoint functions Roque Arcudia Hernandez
2024-10-04 20:46   ` Alex Bennée
2024-10-17 15:34     ` Roque Arcudia Hernandez
2024-10-07 20:06   ` Philippe Mathieu-Daudé
2024-10-16 17:00     ` Roque Arcudia Hernandez
2024-09-06 22:54 ` [PATCH 2/2] gdbstub: Apply breakpoints only to the selected PID Roque Arcudia Hernandez
2024-10-07 10:15   ` Alex Bennée [this message]
2024-10-17 15:36     ` Roque Arcudia Hernandez
  -- strict thread matches above, loose matches on Subject: below --
2025-05-08 22:45 [PATCH 0/2] Fix for multi-process gdbstub breakpoints Nabih Estefan
2025-05-08 22:45 ` [PATCH 2/2] gdbstub: Apply breakpoints only to the selected PID Nabih Estefan

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=87set8w75d.fsf@draig.linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=komlodi@google.com \
    --cc=pbonzini@redhat.com \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=roqueh@google.com \
    --cc=slongfield@google.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 NNTP newsgroup(s).