Hi Luc, On 9/1/18 9:46 AM, Luc Michel wrote: > 'D' packets are used by GDB to detach from a process. In multiprocess > mode, the PID to detach from is sent in the request. > > Signed-off-by: Luc Michel <luc.mic...@greensocs.com> > --- > gdbstub.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++------- > 1 file changed, 48 insertions(+), 7 deletions(-) > > diff --git a/gdbstub.c b/gdbstub.c > index 4ccd1153ce..af8864e251 100644 > --- a/gdbstub.c > +++ b/gdbstub.c > @@ -1025,24 +1025,39 @@ static int gdb_breakpoint_remove(target_ulong addr, > target_ulong len, int type) > default: > return -ENOSYS; > } > } > > +static inline void gdb_cpu_breakpoint_remove_all(CPUState *cpu) > +{ > + cpu_breakpoint_remove_all(cpu, BP_GDB); > +#ifndef CONFIG_USER_ONLY > + cpu_watchpoint_remove_all(cpu, BP_GDB); > +#endif > +} > + > +static void gdb_process_breakpoint_remove_all(const GDBState *s, GDBProcess > *p) > +{ > + CPUState *cpu = get_first_cpu_in_process(s, p); > + > + while (cpu) { > + gdb_cpu_breakpoint_remove_all(cpu); > + cpu = gdb_next_cpu_in_process(s, cpu); > + } > +} > + > static void gdb_breakpoint_remove_all(void) > { > CPUState *cpu; > > if (kvm_enabled()) { > kvm_remove_all_breakpoints(gdbserver_state->c_cpu); > return; > } > > CPU_FOREACH(cpu) { > - cpu_breakpoint_remove_all(cpu, BP_GDB); > -#ifndef CONFIG_USER_ONLY > - cpu_watchpoint_remove_all(cpu, BP_GDB); > -#endif > + gdb_cpu_breakpoint_remove_all(cpu); > } > } > > static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) > { > @@ -1318,13 +1333,39 @@ static int gdb_handle_packet(GDBState *s, const char > *line_buf) > /* Kill the target */ > error_report("QEMU: Terminated via GDBstub"); > exit(0); > case 'D': > /* Detach packet */ > - gdb_breakpoint_remove_all(); > - gdb_syscall_mode = GDB_SYS_DISABLED; > - gdb_continue(s); > + pid = 1; > + > + if (s->multiprocess) { > + unsigned long lpid; > + if (*p != ';') { > + put_packet(s, "E22"); > + break; > + } > + qemu_strtoul(p + 1, &p, 16, &lpid);
You forgot to check for EINVAL/ERANGE. The rest is OK, so once fixed: Reviewed-by: Philippe Mathieu-Daudé <f4...@amsat.org> > + pid = lpid; > + } > + > + process = gdb_get_process(s, pid); > + gdb_process_breakpoint_remove_all(s, process); > + process->attached = false; > + > + if (pid == gdb_get_cpu_pid(s, s->c_cpu)) { > + s->c_cpu = gdb_first_cpu(s); > + } > + > + if (pid == gdb_get_cpu_pid(s, s->g_cpu)) { > + s->g_cpu = gdb_first_cpu(s); > + } > + > + if (s->c_cpu == NULL) { > + /* No more process attached */ > + gdb_syscall_mode = GDB_SYS_DISABLED; > + gdb_continue(s); > + } > put_packet(s, "OK"); > break; > case 's': > if (*p != '\0') { > addr = strtoull(p, (char **)&p, 16); >