/* Darwin support for GDB, the GNU debugger.
- Copyright (C) 2008-2020 Free Software Foundation, Inc.
+ Copyright (C) 2008-2021 Free Software Foundation, Inc.
Contributed by AdaCore.
void
mach_check_error (kern_return_t ret, const char *file,
- unsigned int line, const char *func)
+ unsigned int line, const char *func)
{
if (ret == KERN_SUCCESS)
return;
ret = 0;
inferior_debug (4, _("ptrace (%s, %d, 0x%lx, %d): %d (%s)\n"),
- name, pid, (unsigned long) arg3, arg4, ret,
- (ret != 0) ? safe_strerror (errno) : _("no error"));
+ name, pid, (unsigned long) arg3, arg4, ret,
+ (ret != 0) ? safe_strerror (errno) : _("no error"));
return ret;
}
MACH_CHECK_ERROR (kret);
}
-static int
-find_inferior_task_it (struct inferior *inf, void *port_ptr)
-{
- darwin_inferior *priv = get_darwin_inferior (inf);
-
- return priv != nullptr && priv->task == *(task_t *)port_ptr;
-}
-
-static int
-find_inferior_pid_it (struct inferior *inf, void *pid_ptr)
-{
- return inf->pid == *(int *)pid_ptr;
-}
-
/* Return an inferior by task port. */
static struct inferior *
darwin_find_inferior_by_task (task_t port)
{
- return iterate_over_inferiors (&find_inferior_task_it, &port);
+ for (inferior *inf : all_inferiors ())
+ {
+ darwin_inferior *priv = get_darwin_inferior (inf);
+
+ if (priv != nullptr && priv->task == port)
+ return inf;
+ }
+ return nullptr;
}
/* Return an inferior by pid port. */
static struct inferior *
darwin_find_inferior_by_pid (int pid)
{
- return iterate_over_inferiors (&find_inferior_pid_it, &pid);
+ for (inferior *inf : all_inferiors ())
+ {
+ if (inf->pid == pid)
+ return inf;
+ }
+ return nullptr;
}
/* Return a thread by port. */
}
}
-/* Iterator functions. */
-
-static int
-darwin_resume_inferior_it (struct inferior *inf, void *arg)
-{
- darwin_resume_inferior (inf);
- return 0;
-}
-
static void
darwin_dump_message (mach_msg_header_t *hdr, int disp_body)
{
darwin_resume_thread (inf, thread, step, nsignal);
}
-struct resume_inferior_threads_param
-{
- int step;
- int nsignal;
-};
-
-static int
-darwin_resume_inferior_threads_it (struct inferior *inf, void *param)
-{
- int step = ((struct resume_inferior_threads_param *)param)->step;
- int nsignal = ((struct resume_inferior_threads_param *)param)->nsignal;
-
- darwin_resume_inferior_threads (inf, step, nsignal);
-
- return 0;
-}
-
/* Suspend all threads of INF. */
static void
void
darwin_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
{
- struct target_waitstatus status;
-
int nsignal;
inferior_debug
/* minus_one_ptid is RESUME_ALL. */
if (ptid == minus_one_ptid)
{
- struct resume_inferior_threads_param param;
-
- param.nsignal = nsignal;
- param.step = step;
-
/* Resume threads. */
- iterate_over_inferiors (darwin_resume_inferior_threads_it, ¶m);
+ for (inferior *inf : all_inferiors ())
+ darwin_resume_inferior_threads (inf, step, nsignal);
+
/* Resume tasks. */
- iterate_over_inferiors (darwin_resume_inferior_it, NULL);
+ for (inferior *inf : all_inferiors ())
+ darwin_resume_inferior (inf);
}
else
{
darwin_suspend_inferior (inf);
if (tid == 0)
- darwin_resume_inferior_threads (inf, step, nsignal);
+ darwin_resume_inferior_threads (inf, step, nsignal);
else
- {
- darwin_thread_t *thread;
+ {
+ darwin_thread_t *thread;
- /* Suspend threads of the task. */
- darwin_suspend_inferior_threads (inf);
+ /* Suspend threads of the task. */
+ darwin_suspend_inferior_threads (inf);
- /* Resume the selected thread. */
- thread = darwin_find_thread (inf, tid);
- gdb_assert (thread);
- darwin_resume_thread (inf, thread, step, nsignal);
- }
+ /* Resume the selected thread. */
+ thread = darwin_find_thread (inf, tid);
+ gdb_assert (thread);
+ darwin_resume_thread (inf, thread, step, nsignal);
+ }
/* Resume the task. */
darwin_resume_inferior (inf);
/* Looks necessary on Leopard and harmless... */
wait4 (inf->pid, &wstatus, 0, NULL);
- inferior_ptid = ptid_t (inf->pid, 0, 0);
- return inferior_ptid;
+ return ptid_t (inf->pid);
}
else
{
mach_msg_header_t *hdr = &msgin.hdr;
ptid_t res;
darwin_thread_t *thread;
- struct inferior *inf;
inferior_debug
(2, _("darwin_wait: waiting for a message pid=%d thread=%lx\n"),
/* Handle fake stop events at first. */
if (darwin_inf_fake_stop != NULL)
{
- inf = darwin_inf_fake_stop;
+ inferior *inf = darwin_inf_fake_stop;
darwin_inf_fake_stop = NULL;
darwin_inferior *priv = get_darwin_inferior (inf);
if (darwin_debug_flag > 10)
darwin_dump_message (hdr, darwin_debug_flag > 11);
+ inferior *inf;
res = decode_message (hdr, &thread, &inf, status);
if (res == minus_one_ptid)
continue;
if (darwin_debug_flag > 10)
darwin_dump_message (hdr, darwin_debug_flag > 11);
+ inferior *inf;
ptid2 = decode_message (hdr, &thread, &inf, &status2);
if (inf != NULL && thread != NULL
ptid_t
darwin_nat_target::wait (ptid_t ptid, struct target_waitstatus *status,
- int options)
+ target_wait_flags options)
{
return wait_1 (ptid, status);
}
/* Wait until the process is really stopped. */
while (1)
{
- ptid = wait_1 (inferior_ptid, &wstatus);
+ ptid = wait_1 (ptid_t (inf->pid), &wstatus);
if (wstatus.kind == TARGET_WAITKIND_STOPPED
&& wstatus.value.sig == GDB_SIGNAL_STOP)
break;
for (i = 0; i < inf->exception_info.count; i++)
{
kret = task_set_exception_ports
- (inf->task, inf->exception_info.masks[i], inf->exception_info.ports[i],
+ (inf->task, inf->exception_info.masks[i], inf->exception_info.ports[i],
inf->exception_info.behaviors[i], inf->exception_info.flavors[i]);
if (kret != KERN_SUCCESS)
- return kret;
+ return kret;
}
return KERN_SUCCESS;
if (res == 0)
{
/* On MacOS version Sierra, the darwin_restore_exception_ports call
- does not work as expected.
- When the kill function is called, the SIGKILL signal is received
- by gdb whereas it should have been received by the kernel since
- the exception ports have been restored.
- This behavior is not the expected one thus gdb does not reply to
- the received SIGKILL message. This situation leads to a "busy"
- resource from the kernel point of view and the inferior is never
- released, causing it to remain as a zombie process, even after
+ does not work as expected.
+ When the kill function is called, the SIGKILL signal is received
+ by gdb whereas it should have been received by the kernel since
+ the exception ports have been restored.
+ This behavior is not the expected one thus gdb does not reply to
+ the received SIGKILL message. This situation leads to a "busy"
+ resource from the kernel point of view and the inferior is never
+ released, causing it to remain as a zombie process, even after
GDB exits.
- To work around this, we mark all the threads of the inferior as
- signaled thus darwin_decode_message function knows that the kill
- signal was sent by gdb and will take the appropriate action
- (cancel signal and reply to the signal message). */
+ To work around this, we mark all the threads of the inferior as
+ signaled thus darwin_decode_message function knows that the kill
+ signal was sent by gdb and will take the appropriate action
+ (cancel signal and reply to the signal message). */
for (darwin_thread_t *thread : priv->threads)
- thread->signaled = 1;
+ thread->signaled = 1;
darwin_resume_inferior (inf);
- ptid = wait_1 (inferior_ptid, &wstatus);
+ ptid = wait_1 (ptid_t (inf->pid), &wstatus);
}
else if (errno != ESRCH)
warning (_("Failed to kill inferior: kill (%d, 9) returned [%s]"),
inf->pid, safe_strerror (errno));
- target_mourn_inferior (inferior_ptid);
+ target_mourn_inferior (ptid_t (inf->pid));
}
static void
catch (const gdb_exception &ex)
{
exit_inferior (inf);
- inferior_ptid = null_ptid;
+ switch_to_no_thread ();
throw;
}
target_ops *darwin_ops = get_native_target ();
- if (!target_is_pushed (darwin_ops))
- push_target (darwin_ops);
+ if (!inf->target_is_pushed (darwin_ops))
+ inf->push_target (darwin_ops);
}
/* Get the thread_info object corresponding to this darwin_thread_info. */
struct thread_info *first_thread
= thread_info_from_private_thread_info (first_pti);
- inferior_ptid = first_thread->ptid;
+ switch_to_thread (first_thread);
}
/* The child must synchronize with gdb: gdb must set the exception port
if (res != 0)
{
fprintf_unfiltered
- (gdb_stderr, "Cannot initialize attribute for posix_spawn\n");
+ (gdb_stderr, "Cannot initialize attribute for posix_spawn\n");
return;
}
{
unsigned long ver = strtoul (str, NULL, 10);
if (ver >= 16)
- return true;
+ return true;
}
return false;
}
if (pid == 0 || ::kill (pid, 0) < 0)
error (_("Can't attach to process %d: %s (%d)"),
- pid, safe_strerror (errno), errno);
+ pid, safe_strerror (errno), errno);
- inferior_ptid = ptid_t (pid);
inf = current_inferior ();
inferior_appeared (inf, pid);
inf->attach_flag = 1;
#ifdef TASK_DYLD_INFO_COUNT
case TARGET_OBJECT_DARWIN_DYLD_INFO:
if (writebuf != NULL || readbuf == NULL)
- {
- /* Support only read. */
- return TARGET_XFER_E_IO;
- }
+ {
+ /* Support only read. */
+ return TARGET_XFER_E_IO;
+ }
return darwin_read_dyld_info (priv->task, offset, readbuf, len,
xfered_len);
#endif
}
vm_deallocate (gdb_task, (vm_address_t) names,
- names_count * sizeof (mach_port_t));
+ names_count * sizeof (mach_port_t));
if (res)
- return ptid_t (inferior_ptid.pid (), 0, res);
+ return ptid_t (current_inferior ()->pid, 0, res);
else
return null_ptid;
}