Commit 2b1319c85c94b7defef2ac2191bb50d773c81db4

Authored by aurel32
1 parent 6f9c5ee7

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
gdbstub.c
... ... @@ -1996,6 +1996,18 @@ int gdbserver_start(int port)
1996 1996 gdb_accept();
1997 1997 return 0;
1998 1998 }
  1999 +
  2000 +/* Disable gdb stub for child processes. */
  2001 +void gdbserver_fork(CPUState *env)
  2002 +{
  2003 + GDBState *s = gdbserver_state;
  2004 + if (s->fd < 0)
  2005 + return;
  2006 + close(s->fd);
  2007 + s->fd = -1;
  2008 + cpu_breakpoint_remove_all(env, BP_GDB);
  2009 + cpu_watchpoint_remove_all(env, BP_GDB);
  2010 +}
1999 2011 #else
2000 2012 static int gdb_chr_can_receive(void *opaque)
2001 2013 {
... ...
gdbstub.h
... ... @@ -13,6 +13,7 @@ void gdb_set_stop_cpu(CPUState *env);
13 13 int gdb_handlesig (CPUState *, int);
14 14 void gdb_exit(CPUState *, int);
15 15 int gdbserver_start(int);
  16 +void gdbserver_fork(CPUState *);
16 17 #else
17 18 int gdbserver_start(const char *port);
18 19 #endif
... ...
linux-user/main.c
... ... @@ -162,6 +162,7 @@ void fork_end(int child)
162 162 pthread_cond_init(&exclusive_cond, NULL);
163 163 pthread_cond_init(&exclusive_resume, NULL);
164 164 pthread_mutex_init(&tb_lock, NULL);
  165 + gdbserver_fork(thread_env);
165 166 } else {
166 167 pthread_mutex_unlock(&exclusive_lock);
167 168 pthread_mutex_unlock(&tb_lock);
... ... @@ -254,6 +255,9 @@ void fork_start(void)
254 255  
255 256 void fork_end(int child)
256 257 {
  258 + if (child) {
  259 + gdbserver_fork(thread_env);
  260 + }
257 261 }
258 262 #endif
259 263  
... ...
linux-user/syscall.c
... ... @@ -2960,17 +2960,17 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2960 2960 return -EINVAL;
2961 2961 fork_start();
2962 2962 ret = fork();
2963   -#if defined(USE_NPTL)
2964   - /* There is a race condition here. The parent process could
2965   - theoretically read the TID in the child process before the child
2966   - tid is set. This would require using either ptrace
2967   - (not implemented) or having *_tidptr to point at a shared memory
2968   - mapping. We can't repeat the spinlock hack used above because
2969   - the child process gets its own copy of the lock. */
2970 2963 if (ret == 0) {
  2964 + /* Child Process. */
2971 2965 cpu_clone_regs(env, newsp);
2972 2966 fork_end(1);
2973   - /* Child Process. */
  2967 +#if defined(USE_NPTL)
  2968 + /* There is a race condition here. The parent process could
  2969 + theoretically read the TID in the child process before the child
  2970 + tid is set. This would require using either ptrace
  2971 + (not implemented) or having *_tidptr to point at a shared memory
  2972 + mapping. We can't repeat the spinlock hack used above because
  2973 + the child process gets its own copy of the lock. */
2974 2974 if (flags & CLONE_CHILD_SETTID)
2975 2975 put_user_u32(gettid(), child_tidptr);
2976 2976 if (flags & CLONE_PARENT_SETTID)
... ... @@ -2979,14 +2979,10 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
2979 2979 if (flags & CLONE_SETTLS)
2980 2980 cpu_set_tls (env, newtls);
2981 2981 /* TODO: Implement CLONE_CHILD_CLEARTID. */
  2982 +#endif
2982 2983 } else {
2983 2984 fork_end(0);
2984 2985 }
2985   -#else
2986   - if (ret == 0) {
2987   - cpu_clone_regs(env, newsp);
2988   - }
2989   -#endif
2990 2986 }
2991 2987 return ret;
2992 2988 }
... ...