diff options
author | Daniel Jacobowitz <drow@false.org> | 2004-10-16 17:42:00 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2004-10-16 17:42:00 +0000 |
commit | fd5008162e2dc522e4fea16de38a355f7e1a43be (patch) | |
tree | 5df2b32d3dbdef7b9996bdbf0b9a408e481774ea /gdb/gdbserver/linux-low.c | |
parent | f6de3c42a31e268abe5f03ea860742829db2f677 (diff) | |
download | gdb-fd5008162e2dc522e4fea16de38a355f7e1a43be.zip gdb-fd5008162e2dc522e4fea16de38a355f7e1a43be.tar.gz gdb-fd5008162e2dc522e4fea16de38a355f7e1a43be.tar.bz2 |
* linux-i386-low.c (ps_get_thread_area): New.
* linux-x86-64-low.c (ps_get_thread_area): New.
* linux-low.c: Include <sys/syscall.h>.
(linux_kill_one_process): Don't kill the first thread here.
(linux_kill): Kill the first thread here.
(kill_lwp): New function.
(send_sigstop, linux_send_signal): Use it.
* proc-service.c: Clean up #ifdefs.
(fpregset_info): Delete.
(ps_lgetregs): Update and enable implementation.
(ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Remove disabled
implementations.
* remote-utils.c (struct sym_cache, symbol_cache): New.
(input_interrupt): Print a clearer message.
(async_io_enabled): New variable.
(enable_async_io, disable_async_io): Use it. Update comments.
(look_up_one_symbol): Use the symbol cache.
* thread-db.c (thread_db_look_up_symbols): New function.
(thread_db_init): Update comments. Call thread_db_look_up_symbols.
Diffstat (limited to 'gdb/gdbserver/linux-low.c')
-rw-r--r-- | gdb/gdbserver/linux-low.c | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 5733180..9c41fbb 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -35,6 +35,7 @@ #include <stdlib.h> #include <unistd.h> #include <errno.h> +#include <sys/syscall.h> /* ``all_threads'' is keyed by the LWP ID - it should be the thread ID instead, however. This requires changing the ID in place when we go from !using_threads @@ -223,6 +224,13 @@ linux_kill_one_process (struct inferior_list_entry *entry) struct process_info *process = get_thread_process (thread); int wstat; + /* We avoid killing the first thread here, because of a Linux kernel (at + least 2.6.0-test7 through 2.6.8-rc4) bug; if we kill the parent before + the children get a chance to be reaped, it will remain a zombie + forever. */ + if (entry == all_threads.head) + return; + do { ptrace (PTRACE_KILL, pid_of (process), 0, 0); @@ -235,7 +243,21 @@ linux_kill_one_process (struct inferior_list_entry *entry) static void linux_kill (void) { + struct thread_info *thread = (struct thread_info *) all_threads.head; + struct process_info *process = get_thread_process (thread); + int wstat; + for_each_inferior (&all_threads, linux_kill_one_process); + + /* See the comment in linux_kill_one_process. We did not kill the first + thread in the list, so do so now. */ + do + { + ptrace (PTRACE_KILL, pid_of (process), 0, 0); + + /* Make sure it died. The loop is most likely unnecessary. */ + wstat = linux_wait_for_event (thread); + } while (WIFSTOPPED (wstat)); } static void @@ -709,6 +731,30 @@ retry: return ((unsigned char) WSTOPSIG (w)); } +/* Send a signal to an LWP. For LinuxThreads, kill is enough; however, if + thread groups are in use, we need to use tkill. */ + +static int +kill_lwp (int lwpid, int signo) +{ + static int tkill_failed; + + errno = 0; + +#ifdef SYS_tkill + if (!tkill_failed) + { + int ret = syscall (SYS_tkill, lwpid, signo); + if (errno != ENOSYS) + return ret; + errno = 0; + tkill_failed = 1; + } +#endif + + return kill (lwpid, signo); +} + static void send_sigstop (struct inferior_list_entry *entry) { @@ -728,7 +774,7 @@ send_sigstop (struct inferior_list_entry *entry) if (debug_threads) fprintf (stderr, "Sending sigstop to process %d\n", process->head.id); - kill (process->head.id, SIGSTOP); + kill_lwp (process->head.id, SIGSTOP); process->sigstop_sent = 1; } @@ -1388,10 +1434,10 @@ linux_send_signal (int signum) struct process_info *process; process = get_thread_process (current_inferior); - kill (process->lwpid, signum); + kill_lwp (process->lwpid, signum); } else - kill (signal_pid, signum); + kill_lwp (signal_pid, signum); } /* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET |