On 20:00 Thu 26 May     , Peter Maydell wrote:
> In two places in gdbstub.c we look at gdbserver_state.init to decide
> whether we're going to do a semihosting syscall via the gdb remote
> protocol:
>  * when setting up, if the user didn't explicitly select either
>    native semihosting or gdb semihosting, we autoselect, with the
>    intended behaviour "use gdb if gdb is connected"
>  * when the semihosting layer attempts to do a syscall via gdb, we
>    silently ignore it if the gdbstub wasn't actually set up
> 
> However, if the user's commandline sets up the gdbstub but tells QEMU
> to start rather than waiting for a GDB to connect (eg using '-s' but
> not '-S'), then we will have gdbserver_state.init true but no actual
> connection; an attempt to use gdb syscalls will then crash because we
> try to use gdbserver_state.c_cpu when it hasn't been set up:
> 
> #0  0x00007ffff6803ba8 in qemu_cpu_kick (cpu=0x0) at ../../softmmu/cpus.c:457
> #1  0x00007ffff6c03913 in gdb_do_syscallv (cb=0x7ffff6c19944 <common_semi_cb>,
>     fmt=0x7ffff7573b7e "", va=0x7ffff56294c0) at ../../gdbstub.c:2946
> #2  0x00007ffff6c19c3a in common_semi_gdb_syscall (cs=0x7ffff83fe060,
>     cb=0x7ffff6c19944 <common_semi_cb>, fmt=0x7ffff7573b75 "isatty,%x")
>     at ../../semihosting/arm-compat-semi.c:494
> #3  0x00007ffff6c1a064 in gdb_isattyfn (cs=0x7ffff83fe060, gf=0x7ffff86a3690)
>     at ../../semihosting/arm-compat-semi.c:636
> #4  0x00007ffff6c1b20f in do_common_semihosting (cs=0x7ffff83fe060)
>     at ../../semihosting/arm-compat-semi.c:967
> #5  0x00007ffff693a037 in handle_semihosting (cs=0x7ffff83fe060)
>     at ../../target/arm/helper.c:10316
> 
> You can probably also get into this state via some odd
> corner cases involving connecting a GDB and then telling it
> to detach from all the vCPUs.
> 
> Abstract out the test into a new gdb_attached() function
> which returns true only if there's actually a GDB connected
> to the debug stub and attached to at least one vCPU.
> 
> Reported-by: Liviu Ionescu <i...@livius.net>
> Signed-off-by: Peter Maydell <peter.mayd...@linaro.org>

Reviewed-by: Luc Michel <l...@lmichel.fr>

> ---
> Silently doing nothing in gdb_do_syscallv(), never calling the
> callback function, is kind of dodgy.  But it's what the code is doing
> already, and besides it's not clear what we should do if the user
> specifically says "semihosting calls via the gdb stub" and then
> doesn't connect gdb...
> ---
>  gdbstub.c | 14 +++++++++++---
>  1 file changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/gdbstub.c b/gdbstub.c
> index a3ff8702cef..88a34c8f522 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -443,6 +443,15 @@ static int get_char(void)
>  }
>  #endif
>  
> +/*
> + * Return true if there is a GDB currently connected to the stub
> + * and attached to a CPU
> + */
> +static bool gdb_attached(void)
> +{
> +    return gdbserver_state.init && gdbserver_state.c_cpu;
> +}
> +
>  static enum {
>      GDB_SYS_UNKNOWN,
>      GDB_SYS_ENABLED,
> @@ -464,8 +473,7 @@ int use_gdb_syscalls(void)
>      /* -semihosting-config target=auto */
>      /* On the first call check if gdb is connected and remember. */
>      if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
> -        gdb_syscall_mode = gdbserver_state.init ?
> -            GDB_SYS_ENABLED : GDB_SYS_DISABLED;
> +        gdb_syscall_mode = gdb_attached() ? GDB_SYS_ENABLED : 
> GDB_SYS_DISABLED;
>      }
>      return gdb_syscall_mode == GDB_SYS_ENABLED;
>  }
> @@ -2886,7 +2894,7 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const 
> char *fmt, va_list va)
>      target_ulong addr;
>      uint64_t i64;
>  
> -    if (!gdbserver_state.init) {
> +    if (!gdb_attached()) {
>          return;
>      }
>  
> -- 
> 2.25.1
> 
> 

-- 
+---------------------+--------------------------+
| Luc MICHEL          | TIMA Lab / SLS Team      |
|                     | Phone: +33 4 76 57 43 34 |
+---------------------+--------------------------+

Reply via email to