User-mode GDB stub improvements - handle fork

Close gdbserver in child processes, so that only one stub tries to talk
to GDB at a time.  Updated from an earlier patch by Paul Brook.

Signed-off-by: Daniel Jacobowitz <dan@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6095 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aurel32 2008-12-18 22:44:04 +00:00
parent 6f9c5ee782
commit 2b1319c85c
4 changed files with 26 additions and 13 deletions

View File

@ -1996,6 +1996,18 @@ int gdbserver_start(int port)
gdb_accept();
return 0;
}
/* Disable gdb stub for child processes. */
void gdbserver_fork(CPUState *env)
{
GDBState *s = gdbserver_state;
if (s->fd < 0)
return;
close(s->fd);
s->fd = -1;
cpu_breakpoint_remove_all(env, BP_GDB);
cpu_watchpoint_remove_all(env, BP_GDB);
}
#else
static int gdb_chr_can_receive(void *opaque)
{

View File

@ -13,6 +13,7 @@ void gdb_set_stop_cpu(CPUState *env);
int gdb_handlesig (CPUState *, int);
void gdb_exit(CPUState *, int);
int gdbserver_start(int);
void gdbserver_fork(CPUState *);
#else
int gdbserver_start(const char *port);
#endif

View File

@ -162,6 +162,7 @@ void fork_end(int child)
pthread_cond_init(&exclusive_cond, NULL);
pthread_cond_init(&exclusive_resume, NULL);
pthread_mutex_init(&tb_lock, NULL);
gdbserver_fork(thread_env);
} else {
pthread_mutex_unlock(&exclusive_lock);
pthread_mutex_unlock(&tb_lock);
@ -254,6 +255,9 @@ void fork_start(void)
void fork_end(int child)
{
if (child) {
gdbserver_fork(thread_env);
}
}
#endif

View File

@ -2960,6 +2960,10 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
return -EINVAL;
fork_start();
ret = fork();
if (ret == 0) {
/* Child Process. */
cpu_clone_regs(env, newsp);
fork_end(1);
#if defined(USE_NPTL)
/* There is a race condition here. The parent process could
theoretically read the TID in the child process before the child
@ -2967,10 +2971,6 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
(not implemented) or having *_tidptr to point at a shared memory
mapping. We can't repeat the spinlock hack used above because
the child process gets its own copy of the lock. */
if (ret == 0) {
cpu_clone_regs(env, newsp);
fork_end(1);
/* Child Process. */
if (flags & CLONE_CHILD_SETTID)
put_user_u32(gettid(), child_tidptr);
if (flags & CLONE_PARENT_SETTID)
@ -2979,14 +2979,10 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
if (flags & CLONE_SETTLS)
cpu_set_tls (env, newtls);
/* TODO: Implement CLONE_CHILD_CLEARTID. */
#endif
} else {
fork_end(0);
}
#else
if (ret == 0) {
cpu_clone_regs(env, newsp);
}
#endif
}
return ret;
}