Message ID | 4F3D4D4D.7050607@codesourcery.com |
---|---|
State | New |
Headers | show |
On 02/16/2012 01:08 PM, Peter Maydell wrote: > On 16 February 2012 18:39, Meador Inge <meadori@codesourcery.com> wrote: >> On 02/15/2012 02:14 PM, Peter Maydell wrote: >>> I think the right way to deal with both the problem you were seeing >>> and this related issue is simply not to try to send the syscall >>> request until we have really stopped the CPU. That is, when not >>> in CONFIG_USER_ONLY we should send the syscall request from >>> gdb_vm_state_change(). >> >> I agree. I am doing some more testing and will send an official v2 patch >> later, but just to make sure I am on the right track something like (this >> worked in the basic testing I have done so far and avoids the pitfall pointed >> out above): > > That looks roughly OK, but: > * shouldn't gdb_syscall_buf[] be in GDBState ? > * I don't think the "are we stopping to do a syscall?" flag should be > implemented as an RSState enum -- that enum is for the > parsing-incoming-packet > state machine I cleaned up these bits. v2 patch coming up soon. > Bonus extra semihosting bug: if you start with "-gdb none" rather than "-s" then > we segfault, because gdbserver_start() creates a GDBState with a NULL s->chr > but use_gdb_syscalls() only looks at whether gdbserver_state is non-NULL, not > whether s->state is RS_INACTIVE, so the first gdb_do_syscall() ends up > dereferencing that NULL pointer. (Watch out when fixing this that you don't > break semihosting in linux-user mode, because at the moment linux-user mode > doesn't set up s->state at all so it's always RS_INACTIVE... We may also > want to declare that mixing all of gdb, semihosting and fork() in a linux-user > guest is not supported ;-)) I will take a look at that one as a separate patch :-)
diff --git a/gdbstub.c b/gdbstub.c index 7d470b6..66c3760 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -347,6 +347,7 @@ static int get_char(GDBState *s) #endif static gdb_syscall_complete_cb gdb_current_syscall_cb; +static char gdb_syscall_buf[256]; static enum { GDB_SYS_UNKNOWN, @@ -2396,7 +2397,12 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state) const char *type; int ret; - if (running || s->state == RS_INACTIVE || s->state == RS_SYSCALL) { + if (running || s->state == RS_INACTIVE) { + return; + } + if (s->state == RS_SYSCALL) { + put_packet(s, gdb_syscall_buf); + s->state = RS_IDLE; return; }