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,17 +2960,17 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
return -EINVAL;
fork_start();
ret = fork();
#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
tid is set. This would require using either ptrace
(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) {
/* Child Process. */
cpu_clone_regs(env, newsp);
fork_end(1);
/* Child Process. */
#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
tid is set. This would require using either ptrace
(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 (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;
}