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:
parent
6f9c5ee782
commit
2b1319c85c
12
gdbstub.c
12
gdbstub.c
@ -1996,6 +1996,18 @@ int gdbserver_start(int port)
|
|||||||
gdb_accept();
|
gdb_accept();
|
||||||
return 0;
|
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
|
#else
|
||||||
static int gdb_chr_can_receive(void *opaque)
|
static int gdb_chr_can_receive(void *opaque)
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,7 @@ void gdb_set_stop_cpu(CPUState *env);
|
|||||||
int gdb_handlesig (CPUState *, int);
|
int gdb_handlesig (CPUState *, int);
|
||||||
void gdb_exit(CPUState *, int);
|
void gdb_exit(CPUState *, int);
|
||||||
int gdbserver_start(int);
|
int gdbserver_start(int);
|
||||||
|
void gdbserver_fork(CPUState *);
|
||||||
#else
|
#else
|
||||||
int gdbserver_start(const char *port);
|
int gdbserver_start(const char *port);
|
||||||
#endif
|
#endif
|
||||||
|
@ -162,6 +162,7 @@ void fork_end(int child)
|
|||||||
pthread_cond_init(&exclusive_cond, NULL);
|
pthread_cond_init(&exclusive_cond, NULL);
|
||||||
pthread_cond_init(&exclusive_resume, NULL);
|
pthread_cond_init(&exclusive_resume, NULL);
|
||||||
pthread_mutex_init(&tb_lock, NULL);
|
pthread_mutex_init(&tb_lock, NULL);
|
||||||
|
gdbserver_fork(thread_env);
|
||||||
} else {
|
} else {
|
||||||
pthread_mutex_unlock(&exclusive_lock);
|
pthread_mutex_unlock(&exclusive_lock);
|
||||||
pthread_mutex_unlock(&tb_lock);
|
pthread_mutex_unlock(&tb_lock);
|
||||||
@ -254,6 +255,9 @@ void fork_start(void)
|
|||||||
|
|
||||||
void fork_end(int child)
|
void fork_end(int child)
|
||||||
{
|
{
|
||||||
|
if (child) {
|
||||||
|
gdbserver_fork(thread_env);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2960,17 +2960,17 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
fork_start();
|
fork_start();
|
||||||
ret = fork();
|
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) {
|
if (ret == 0) {
|
||||||
|
/* Child Process. */
|
||||||
cpu_clone_regs(env, newsp);
|
cpu_clone_regs(env, newsp);
|
||||||
fork_end(1);
|
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)
|
if (flags & CLONE_CHILD_SETTID)
|
||||||
put_user_u32(gettid(), child_tidptr);
|
put_user_u32(gettid(), child_tidptr);
|
||||||
if (flags & CLONE_PARENT_SETTID)
|
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)
|
if (flags & CLONE_SETTLS)
|
||||||
cpu_set_tls (env, newtls);
|
cpu_set_tls (env, newtls);
|
||||||
/* TODO: Implement CLONE_CHILD_CLEARTID. */
|
/* TODO: Implement CLONE_CHILD_CLEARTID. */
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
fork_end(0);
|
fork_end(0);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (ret == 0) {
|
|
||||||
cpu_clone_regs(env, newsp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user