diff options
author | Jim Kingdon <jkingdon@engr.sgi.com> | 2000-02-11 06:34:58 +0000 |
---|---|---|
committer | Jim Kingdon <jkingdon@engr.sgi.com> | 2000-02-11 06:34:58 +0000 |
commit | f90b2b1da8e0f4412cc987415483c79232f905c8 (patch) | |
tree | 196a53b50d8ebb83f0ad672e5ed1767c799e46d9 /gdb/gnu-nat.c | |
parent | 63a027a3fb81e7cbc591be1635c82986402ced3c (diff) | |
download | gdb-f90b2b1da8e0f4412cc987415483c79232f905c8.zip gdb-f90b2b1da8e0f4412cc987415483c79232f905c8.tar.gz gdb-f90b2b1da8e0f4412cc987415483c79232f905c8.tar.bz2 |
2000-02-09 Mark Kettenis <kettenis@gnu.org>
* gnu-nat.c (proc_string): Make global.
(do_mach_notify_dead_name): Suppress dead name notifications if we
know that the task is dead.
1999-12-13 Mark Kettenis <kettenis@gnu.org>
* gnu-nat.c (inf_validate_task_sc): Get task info via proc server
instead of directly from the kernel. Add some hackery to make
sure that the info isn't influenced by suspension of the task in
the proc server itself.
Diffstat (limited to 'gdb/gnu-nat.c')
-rw-r--r-- | gdb/gnu-nat.c | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c index 5f609ed..b39335f 100644 --- a/gdb/gnu-nat.c +++ b/gdb/gnu-nat.c @@ -1,5 +1,5 @@ /* Interface GDB to the GNU Hurd. - Copyright (C) 1992, 1995, 1996, 1997, 1999 Free Software Foundation, Inc. + Copyright (C) 1992, 95, 96, 97, 1999, 2000 Free Software Foundation, Inc. This file is part of GDB. @@ -32,11 +32,6 @@ #include <limits.h> #include <sys/ptrace.h> -/* We include this because we don't need the access macros and they conflict - with gdb's definitions (ick). This is very non standard! */ -#define _SYS_WAIT_H /* Inhibit warning from <bits/waitflags.h>. */ -#include <bits/waitflags.h> - #include <mach.h> #include <mach/message.h> #include <mach/notify.h> @@ -794,32 +789,58 @@ inf_validate_procinfo (struct inf *inf) } } -/* Validates INF's task suspend count. If it's higher than we expect, verify - with the user before `stealing' the extra count. */ +/* Validates INF's task suspend count. If it's higher than we expect, + verify with the user before `stealing' the extra count. */ static void inf_validate_task_sc (struct inf *inf) { - struct task_basic_info info; - mach_msg_type_number_t info_len = TASK_BASIC_INFO_COUNT; - error_t err = - task_info (inf->task->port, TASK_BASIC_INFO, (task_info_t) & info, &info_len); + char *noise; + mach_msg_type_number_t noise_len = 0; + struct procinfo *pi; + mach_msg_type_number_t pi_len = 0; + int info_flags = PI_FETCH_TASKINFO; + int suspend_count = -1; + error_t err; + retry: + err = proc_getprocinfo (proc_server, inf->pid, &info_flags, + &pi, &pi_len, &noise, &noise_len); if (err) - inf->task->dead = 1; /* oh well */ - else if (inf->task->cur_sc < info.suspend_count) + { + inf->task->dead = 1; /* oh well */ + return; + } + + if (inf->task->cur_sc < pi->taskinfo.suspend_count && suspend_count == -1) + { + /* The proc server might have suspended the task while stopping + it. This happens when the task is handling a traced signal. + Refetch the suspend count. The proc server should be + finished stopping the task by now. */ + suspend_count = pi->taskinfo.suspend_count; + goto retry; + } + + suspend_count = pi->taskinfo.suspend_count; + + vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len); + if (noise_len > 0) + vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len); + + if (inf->task->cur_sc < suspend_count) { int abort; target_terminal_ours (); /* Allow I/O. */ - abort = - !query ("Pid %d has an additional task suspend count of %d; clear it? ", - inf->pid, info.suspend_count - inf->task->cur_sc); + abort = !query ("Pid %d has an additional task suspend count of %d;" + " clear it? ", inf->pid, + suspend_count - inf->task->cur_sc); target_terminal_inferior (); /* Give it back to the child. */ if (abort) error ("Additional task suspend count left untouched."); - inf->task->cur_sc = info.suspend_count; + inf->task->cur_sc = suspend_count; } } @@ -1665,6 +1686,10 @@ do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_port) proc_debug (thread, "is dead"); thread->port = MACH_PORT_NULL; } + + if (inf->task->dead) + /* Since the task is dead, its threads are dying with it. */ + inf->wait.suppress = 1; } mach_port_deallocate (mach_task_self (), dead_port); @@ -2413,7 +2438,7 @@ gnu_xfer_memory (memaddr, myaddr, len, write, target) } /* Return printable description of proc. */ -static char * +char * proc_string (struct proc *proc) { static char tid_str[80]; |