39#include "bfd/mach-o.h"
43#include <sys/ptrace.h>
44#include <sys/signal.h>
50#include <sys/sysctl.h>
53#include <sys/syscall.h>
56#include <mach/mach_error.h>
57#include <mach/mach_vm.h>
58#include <mach/mach_init.h>
59#include <mach/vm_map.h>
61#include <mach/mach_port.h>
62#include <mach/thread_act.h>
67#include "gdbsupport/filestuff.h"
68#include "gdbsupport/gdb_unlinker.h"
69#include "gdbsupport/pathstuff.h"
70#include "gdbsupport/scoped_fd.h"
89#define PTRACE(CMD, PID, ADDR, SIG) \
90 darwin_ptrace(#CMD, CMD, (PID), (ADDR), (SIG))
95 mach_msg_header_t *hdr, integer_t
code);
128#define PAGE_TRUNC(x) ((x) & ~(mach_page_size - 1))
129#define PAGE_ROUND(x) PAGE_TRUNC((x) + mach_page_size - 1)
139static const unsigned char info_plist[]
141 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
142 "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
143 " \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
144 "<plist version=\"1.0\">\n"
146 " <key>CFBundleIdentifier</key>\n"
147 " <string>org.gnu.gdb</string>\n"
148 " <key>CFBundleName</key>\n"
149 " <string>gdb</string>\n"
150 " <key>CFBundleVersion</key>\n"
151 " <string>1.0</string>\n"
152 " <key>SecTaskAccess</key>\n"
154 " <string>allowed</string>\n"
155 " <string>debug</string>\n"
179 unsigned int line,
const char *
func)
181 if (ret == KERN_SUCCESS)
184 func = _(
"[UNKNOWN]");
186 warning (_(
"Mach error at \"%s:%u\" in function \"%s\": %s (0x%lx)"),
187 file, line,
func, mach_error_string (ret), (
unsigned long) ret);
193 static char unknown_exception_buf[32];
198 return "EXC_BAD_ACCESS";
199 case EXC_BAD_INSTRUCTION:
200 return "EXC_BAD_INSTRUCTION";
202 return "EXC_ARITHMETIC";
204 return "EXC_EMULATION";
206 return "EXC_SOFTWARE";
208 return "EXC_BREAKPOINT";
210 return "EXC_SYSCALL";
211 case EXC_MACH_SYSCALL:
212 return "EXC_MACH_SYSCALL";
214 return "EXC_RPC_ALERT";
218 snprintf (unknown_exception_buf, 32, _(
"unknown (%d)"), i);
219 return unknown_exception_buf;
234 int request,
int pid, caddr_t arg3,
int arg4)
240 if (ret == -1 && errno == 0)
244 name,
pid, (
unsigned long) arg3, arg4, ret,
245 (ret != 0) ? safe_strerror (errno) : _(
"no error"));
254 return (
int)(tl - tr);
261 thread_array_t thread_list;
262 unsigned int new_nbr;
263 unsigned int old_nbr;
264 unsigned int new_ix, old_ix;
266 std::vector<darwin_thread_t *> new_thread_vec;
268 if (darwin_inf ==
nullptr)
272 kret = task_threads (darwin_inf->
task, &thread_list, &new_nbr);
274 if (kret != KERN_SUCCESS)
281 old_nbr = darwin_inf->
threads.size ();
284 if (old_nbr == new_nbr)
288 for (i = 0; i < new_nbr; i++)
289 if (thread_list[i] != darwin_inf->
threads[i]->gdb_port)
294 for (i = 0; i < new_nbr; i++)
296 kret = mach_port_deallocate (mach_task_self (), thread_list[i]);
301 kret = vm_deallocate (
gdb_task, (vm_address_t) thread_list,
302 new_nbr *
sizeof (
int));
311 new_thread_vec.reserve (new_nbr);
313 for (new_ix = 0, old_ix = 0; new_ix < new_nbr || old_ix < old_nbr;)
315 thread_t new_id = (new_ix < new_nbr) ? thread_list[new_ix] : THREAD_NULL;
317 = (old_ix < old_nbr) ? darwin_inf->
threads[old_ix] : NULL;
321 (12, _(
" new_ix:%d/%d, old_ix:%d/%d, new_id:0x%x old_id:0x%x\n"),
322 new_ix, new_nbr, old_ix, old_nbr, new_id, old_id);
324 if (old_id == new_id)
327 new_thread_vec.push_back (old);
332 kret = mach_port_deallocate (
gdb_task, new_id);
337 if (new_ix < new_nbr && new_id == MACH_PORT_DEAD)
345 if (new_ix < new_nbr && (old_ix == old_nbr || new_id < old_id))
355 new_thread_vec.push_back (pti);
359 if (old_ix < old_nbr && (new_ix == new_nbr || new_id > old_id))
365 kret = mach_port_deallocate (
gdb_task, old_id);
370 gdb_assert_not_reached (
"unexpected thread case");
373 darwin_inf->
threads = std::move (new_thread_vec);
376 kret = vm_deallocate (
gdb_task, (vm_address_t) thread_list,
377 new_nbr *
sizeof (
int));
389 if (
priv !=
nullptr &&
priv->task == port)
416 if (t->gdb_port == thread)
430 if (
priv !=
nullptr && !
priv->suspended)
434 kret = task_suspend (
priv->task);
448 if (
priv !=
nullptr &&
priv->suspended)
452 kret = task_resume (
priv->task);
463 _(
"message header:\n"));
465 _(
" bits: 0x%x\n"), hdr->msgh_bits);
467 _(
" size: 0x%x\n"), hdr->msgh_size);
469 _(
" remote-port: 0x%x\n"), hdr->msgh_remote_port);
471 _(
" local-port: 0x%x\n"), hdr->msgh_local_port);
473 _(
" reserved: 0x%x\n"), hdr->msgh_reserved);
475 _(
" id: 0x%x\n"), hdr->msgh_id);
479 const unsigned char *data;
480 const unsigned int *ldata;
484 data = (
unsigned char *)(hdr + 1);
485 size = hdr->msgh_size -
sizeof (mach_msg_header_t);
487 if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
489 mach_msg_body_t *bod = (mach_msg_body_t*)data;
490 mach_msg_port_descriptor_t *desc =
491 (mach_msg_port_descriptor_t *)(bod + 1);
495 _(
"body: descriptor_count=%u\n"),
496 bod->msgh_descriptor_count);
497 data +=
sizeof (mach_msg_body_t);
498 size -=
sizeof (mach_msg_body_t);
499 for (k = 0; k < bod->msgh_descriptor_count; k++)
500 switch (desc[k].
type)
502 case MACH_MSG_PORT_DESCRIPTOR:
505 _(
" descr %d: type=%u (port) name=0x%x, dispo=%d\n"),
506 k, desc[k].
type, desc[k].
name, desc[k].disposition);
510 _(
" descr %d: type=%u\n"),
514 data += bod->msgh_descriptor_count
515 *
sizeof (mach_msg_port_descriptor_t);
516 size -= bod->msgh_descriptor_count
517 *
sizeof (mach_msg_port_descriptor_t);
518 ndr = (NDR_record_t *)(desc + bod->msgh_descriptor_count);
521 _(
"NDR: mig=%02x if=%02x encod=%02x "
522 "int=%02x char=%02x float=%02x\n"),
523 ndr->mig_vers, ndr->if_vers, ndr->mig_encoding,
524 ndr->int_rep, ndr->char_rep, ndr->float_rep);
525 data +=
sizeof (NDR_record_t);
526 size -=
sizeof (NDR_record_t);
530 ldata = (
const unsigned int *)data;
531 for (i = 0; i <
size /
sizeof (
unsigned int); i++)
548 kret = pid_for_task (task_port, &task_pid);
549 if (kret != KERN_SUCCESS)
566 kret = mach_port_request_notification (
gdb_task,
priv->task,
567 MACH_NOTIFY_DEAD_NAME, 0,
569 MACH_MSG_TYPE_MAKE_SEND_ONCE,
571 if (kret != KERN_INVALID_ARGUMENT)
577 priv->task = task_port;
590 if (ndr->mig_vers != NDR_PROTOCOL_2_0
591 || ndr->if_vers != NDR_PROTOCOL_2_0
592 || ndr->mig_encoding != NDR_record.mig_encoding
593 || ndr->int_rep != NDR_record.int_rep
594 || ndr->char_rep != NDR_record.char_rep
595 || ndr->float_rep != NDR_record.float_rep)
607 mach_msg_body_t *bod = (mach_msg_body_t*)(hdr + 1);
608 mach_msg_port_descriptor_t *desc = (mach_msg_port_descriptor_t *)(bod + 1);
623 if (!(hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX))
627 if (hdr->msgh_size < (sizeof (*hdr) +
sizeof (*bod) + 2 *
sizeof (*desc)
628 +
sizeof (*ndr) + 2 *
sizeof (integer_t))
629 || bod->msgh_descriptor_count != 2
630 || desc[0].type != MACH_MSG_PORT_DESCRIPTOR
631 || desc[0].disposition != MACH_MSG_TYPE_MOVE_SEND
632 || desc[1].type != MACH_MSG_PORT_DESCRIPTOR
633 || desc[1].disposition != MACH_MSG_TYPE_MOVE_SEND)
637 ndr = (NDR_record_t *)(desc + 2);
642 data = (integer_t *)(ndr + 1);
644 task_port = desc[1].name;
645 thread_port = desc[0].name;
651 if (
inf == NULL && data[0] == EXC_SOFTWARE && data[1] == 2
652 && data[2] == EXC_SOFT_SIGNAL && data[3] == SIGTRAP)
662 kret = mach_port_deallocate (mach_task_self (), task_port);
670 kret = mach_port_deallocate (mach_task_self (), task_port);
679 mig_reply_error_t reply;
682 (4, _(
"darwin_decode_exception_message: unknown task 0x%x\n"),
686 kret = mach_port_deallocate (mach_task_self (), thread_port);
691 kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
692 reply.Head.msgh_size, 0,
693 MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
707 kret = mach_port_deallocate (mach_task_self (), thread_port);
720 thread->
event.header = *hdr;
721 thread->
event.thread_port = thread_port;
722 thread->
event.task_port = task_port;
723 thread->
event.ex_type = data[0];
724 thread->
event.data_count = data[1];
726 if (hdr->msgh_size < (sizeof (*hdr) +
sizeof (*bod) + 2 *
sizeof (*desc)
727 +
sizeof (*ndr) + 2 *
sizeof (integer_t)
728 + data[1] *
sizeof (integer_t)))
730 for (i = 0; i < data[1]; i++)
731 thread->
event.ex_data[i] = data[2 + i];
743 NDR_record_t *ndr = (NDR_record_t *)(hdr + 1);
744 integer_t *data = (integer_t *)(ndr + 1);
749 if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
753 if (hdr->msgh_size < (sizeof (*hdr) +
sizeof (*ndr) +
sizeof (integer_t)))
770 if (hdr->msgh_local_port !=
priv->notify_port)
781 mach_msg_header_t *rh = &reply->Head;
783 rh->msgh_bits = MACH_MSGH_BITS (MACH_MSGH_BITS_REMOTE (hdr->msgh_bits), 0);
784 rh->msgh_remote_port = hdr->msgh_remote_port;
785 rh->msgh_size = (mach_msg_size_t)
sizeof (mig_reply_error_t);
786 rh->msgh_local_port = MACH_PORT_NULL;
787 rh->msgh_id = hdr->msgh_id + 100;
789 reply->NDR = NDR_record;
790 reply->RetCode =
code;
797 mig_reply_error_t reply;
802 kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
803 reply.Head.msgh_size, 0,
804 MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
808 priv->pending_messages--;
819 DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS;
827 int step,
int nsignal)
830 (3, _(
"darwin_resume_thread: state=%d, thread=0x%x, step=%d nsignal=%d\n"),
836 if (thread->
event.ex_type == EXC_SOFTWARE
837 && thread->
event.ex_data[0] == EXC_SOFT_SIGNAL)
841 (caddr_t) (uintptr_t) thread->
gdb_port, nsignal);
856 inferior_debug (4, _(
"darwin_set_sstep (thread=0x%x, enable=%d)\n"),
869 kern_return_t kret = thread_resume (thread->
gdb_port);
898 switch (thread->msg_state)
905 kern_return_t kret = thread_suspend (thread->gdb_port);
920 (2, _(
"darwin_resume: ptid=%s, step=%d, signal=%d\n"),
921 ptid.to_string ().c_str (), step, signal);
923 if (signal == GDB_SIGNAL_0)
926 nsignal = gdb_signal_to_host (signal);
933 if (ptid == minus_one_ptid)
946 long tid = ptid.tid ();
981 if (hdr->msgh_id == 2401)
991 warning (_(
"darwin_wait: ill-formatted message (id=0x%x)\n"),
995 return minus_one_ptid;
1000 return minus_one_ptid;
1015 switch (thread->
event.ex_type)
1017 case EXC_BAD_ACCESS:
1018 status->set_stopped (GDB_EXC_BAD_ACCESS);
1020 case EXC_BAD_INSTRUCTION:
1021 status->set_stopped (GDB_EXC_BAD_INSTRUCTION);
1023 case EXC_ARITHMETIC:
1024 status->set_stopped (GDB_EXC_ARITHMETIC);
1027 status->set_stopped (GDB_EXC_EMULATION);
1030 if (thread->
event.ex_data[0] == EXC_SOFT_SIGNAL)
1033 (gdb_signal_from_host (thread->
event.ex_data[1]));
1035 thread->
event.ex_data[1],
1036 gdb_signal_to_name (
status->sig ()));
1049 status->set_stopped (GDB_EXC_SOFTWARE);
1051 case EXC_BREAKPOINT:
1055 status->set_stopped (GDB_SIGNAL_TRAP);
1058 status->set_stopped (GDB_SIGNAL_UNKNOWN);
1064 else if (hdr->msgh_id == 0x48)
1075 (_(
"darwin_wait: ill-formatted message (id=0x%x, res=%d)\n"),
1082 if (res < 0 ||
inf == NULL)
1085 return minus_one_ptid;
1097 res_pid = wait4 (
inf->
pid, &wstatus, 0, NULL);
1098 if (res_pid < 0 || res_pid != inf->
pid)
1100 warning (_(
"wait4: res=%d: %s\n"),
1101 res_pid, safe_strerror (errno));
1103 return minus_one_ptid;
1105 if (WIFEXITED (wstatus))
1107 status->set_exited (WEXITSTATUS (wstatus));
1111 else if (WIFSTOPPED (wstatus))
1116 inferior_debug (4, _(
"darwin_wait: pid %d received WIFSTOPPED\n"),
1118 return minus_one_ptid;
1120 else if (WIFSIGNALED (wstatus))
1123 (gdb_signal_from_host (WTERMSIG (wstatus)));
1124 inferior_debug (4, _(
"darwin_wait: pid=%d received signal %d\n"),
1130 warning (_(
"Unexpected wait status after MACH_NOTIFY_DEAD_NAME "
1131 "notification: 0x%x"), wstatus);
1132 return minus_one_ptid;
1135 return ptid_t (
inf->
pid);
1141 return ptid_t (
inf->
pid, 0, 0);
1147 warning (_(
"darwin: got unknown message, id: 0x%x"), hdr->msgh_id);
1149 return minus_one_ptid;
1171 (
unsigned long) ptid.tid ());
1188 mach_msg_header_t hdr;
1191 mach_msg_header_t *hdr = &msgin.hdr;
1196 (2, _(
"darwin_wait: waiting for a message ptid=%s\n"),
1197 ptid.to_string ().c_str ());
1207 status->set_stopped (GDB_SIGNAL_TRAP);
1218 kret = mach_msg (&msgin.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0,
1223 if (kret == MACH_RCV_INTERRUPTED)
1226 return minus_one_ptid;
1229 if (kret != MACH_MSG_SUCCESS)
1233 return minus_one_ptid;
1242 if (res == minus_one_ptid)
1264 kret = mach_msg (&msgin.hdr,
1265 MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0,
1268 if (kret == MACH_RCV_TIMED_OUT)
1270 if (kret != MACH_MSG_SUCCESS)
1273 (5, _(
"darwin_wait: mach_msg(pending) ret=0x%x\n"), kret);
1284 if (
inf != NULL && thread != NULL
1285 && thread->
event.ex_type == EXC_BREAKPOINT)
1296 (3, _(
"darwin_wait: thread 0x%x hit a non-gdb breakpoint\n"),
1300 inferior_debug (3, _(
"darwin_wait: unhandled pending message\n"));
1307 target_wait_flags options)
1332 kern_return_t kret = mach_port_deallocate (
gdb_task, t->gdb_port);
1336 priv->threads.clear ();
1351 kret = mach_port_move_member (
gdb_task,
1356 kret = mach_port_request_notification (
gdb_task, priv->
task,
1357 MACH_NOTIFY_DEAD_NAME, 0,
1359 MACH_MSG_TYPE_MAKE_SEND_ONCE,
1365 if (kret == KERN_SUCCESS)
1367 kret = mach_port_deallocate (
gdb_task, prev);
1407 gdb_assert (
inf != NULL);
1418 warning (_(
"cannot kill: %s"), safe_strerror (errno));
1425 && wstatus.
sig () == GDB_SIGNAL_STOP)
1435 inf->exception_info.count =
1436 sizeof (
inf->exception_info.ports) /
sizeof (
inf->exception_info.ports[0]);
1438 kret = task_get_exception_ports
1439 (
inf->
task, EXC_MASK_ALL,
inf->exception_info.masks,
1440 &
inf->exception_info.count,
inf->exception_info.ports,
1441 inf->exception_info.behaviors,
inf->exception_info.flavors);
1451 for (i = 0; i <
inf->exception_info.count; i++)
1453 kret = task_set_exception_ports
1454 (
inf->
task,
inf->exception_info.masks[i],
inf->exception_info.ports[i],
1455 inf->exception_info.behaviors[i],
inf->exception_info.flavors[i]);
1456 if (kret != KERN_SUCCESS)
1460 return KERN_SUCCESS;
1471 for (i = 0; i <
inf->exception_info.count; i++)
1473 kret = mach_port_deallocate (
gdb_task,
inf->exception_info.ports[i]);
1476 inf->exception_info.count = 0;
1484 exception_mask_t mask;
1487 if (kret != KERN_SUCCESS)
1488 error (_(
"Unable to save exception ports, task_get_exception_ports"
1494 mask = EXC_MASK_ALL;
1496 mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
1498 EXCEPTION_DEFAULT, THREAD_STATE_NONE);
1499 if (kret != KERN_SUCCESS)
1500 error (_(
"Unable to set exception ports, task_set_exception_ports"
1518 gdb_assert (
inf != NULL);
1544 thread->signaled = 1;
1550 else if (errno != ESRCH)
1551 warning (_(
"Failed to kill inferior: kill (%d, 9) returned [%s]"),
1552 inf->
pid, safe_strerror (errno));
1562 mach_port_t prev_not;
1564 kret = mach_port_request_notification (
gdb_task, priv->
task,
1565 MACH_NOTIFY_DEAD_NAME, 0,
1567 MACH_MSG_TYPE_MAKE_SEND_ONCE,
1569 if (kret != KERN_SUCCESS)
1570 error (_(
"Termination notification request failed, "
1571 "mach_port_request_notification\n"
1574 if (prev_not != MACH_PORT_NULL)
1580A task termination request was registered before the debugger registered\n\
1581its own. This is unexpected, but should otherwise not have any actual\n\
1582impact on the debugging session."));
1592 inf->priv.reset (priv);
1597 if (kret != KERN_SUCCESS)
1601 if (!
inf->attach_flag)
1608 (_(
"Unable to find Mach task port for process-id %d: %s (0x%lx).\n"
1609 " (please check gdb is codesigned - see taskgated(8))"),
1610 inf->
pid, mach_error_string (kret), (
unsigned long) kret);
1619 kret = mach_port_allocate (
gdb_task, MACH_PORT_RIGHT_RECEIVE,
1621 if (kret != KERN_SUCCESS)
1622 error (_(
"Unable to create exception port, mach_port_allocate "
1628 MACH_MSG_TYPE_MAKE_SEND);
1629 if (kret != KERN_SUCCESS)
1630 error (_(
"Unable to create exception port, mach_port_insert_right "
1635 kret = mach_port_allocate (
gdb_task, MACH_PORT_RIGHT_PORT_SET,
1637 if (kret != KERN_SUCCESS)
1638 error (_(
"Unable to create port set, mach_port_allocate "
1644 if (kret != KERN_SUCCESS)
1645 error (_(
"Unable to move exception port into new port set, "
1646 "mach_port_move_member\n"
1652 kret = mach_port_allocate (
gdb_task, MACH_PORT_RIGHT_RECEIVE,
1654 if (kret != KERN_SUCCESS)
1655 error (_(
"Unable to create notification port, mach_port_allocate "
1659 kret = mach_port_move_member (
gdb_task,
1661 if (kret != KERN_SUCCESS)
1662 error (_(
"Unable to move notification port into new port set, "
1663 "mach_port_move_member\n"
1671 catch (
const gdb_exception &ex)
1680 if (!
inf->target_is_pushed (darwin_ops))
1681 inf->push_target (darwin_ops);
1697 gdb_assert_not_reached (
"did not find gdb thread for darwin thread");
1707 gdb_assert (!priv->
threads.empty ());
1740 if (setegid (getgid ()) < 0)
1748 if (
PTRACE (PT_SIGEXC, 0, 0, 0) < 0)
1760 error (_(
"unable to create a pipe: %s"), safe_strerror (errno));
1789 posix_spawnattr_t attr;
1793 res = posix_spawnattr_init (&attr);
1797 (
gdb_stderr,
"Cannot initialize attribute for posix_spawn\n");
1802 ps_flags = POSIX_SPAWN_SETEXEC;
1806#ifndef _POSIX_SPAWN_DISABLE_ASLR
1807#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
1810 res = posix_spawnattr_setflags (&attr, ps_flags);
1817 posix_spawnp (NULL, argv[0], NULL, &attr, argv, env);
1827 size_t sz =
sizeof (str);
1830 ret = sysctlbyname (
"kern.osrelease", str, &sz, NULL, 0);
1831 if (ret == 0 && sz <
sizeof (str))
1833 unsigned long ver = strtoul (str, NULL, 10);
1846 scoped_fd from_fd = gdb_open_cloexec (shell, O_RDONLY, 0);
1847 if (from_fd.get () < 0)
1848 error (_(
"Could not open shell (%s) for reading: %s"),
1849 shell, safe_strerror (errno));
1851 std::string new_dir =
ldirname (new_name.c_str ());
1852 if (!mkdir_recursive (new_dir.c_str ()))
1853 error (_(
"Could not make cache directory \"%s\": %s"),
1854 new_dir.c_str (), safe_strerror (errno));
1856 gdb::char_vector temp_name = make_temp_filename (new_name);
1857 scoped_fd to_fd = gdb_mkostemp_cloexec (&temp_name[0]);
1858 gdb::unlinker unlink_file_on_error (temp_name.data ());
1860 if (to_fd.get () < 0)
1861 error (_(
"Could not open temporary file \"%s\" for writing: %s"),
1862 temp_name.data (), safe_strerror (errno));
1864 if (fcopyfile (from_fd.get (), to_fd.get (),
nullptr,
1865 COPYFILE_STAT | COPYFILE_DATA) != 0)
1866 error (_(
"Could not copy shell to cache as \"%s\": %s"),
1867 temp_name.data (), safe_strerror (errno));
1871 if (rename (temp_name.data (), new_name.c_str ()) != 0)
1872 error (_(
"Could not rename shell cache file to \"%s\": %s"),
1873 new_name.c_str (), safe_strerror (errno));
1875 unlink_file_on_error.keep ();
1898 const char *shell = get_shell ();
1899 if (!IS_ABSOLUTE_PATH (shell))
1901 warning (_(
"This version of macOS has System Integrity Protection.\n\
1902Normally gdb would try to work around this by caching a copy of your shell,\n\
1903but because your shell (%s) is not an absolute path, this is being skipped."),
1909 if (stat (shell, &sb) < 0)
1911 warning (_(
"This version of macOS has System Integrity Protection.\n\
1912Normally gdb would try to work around this by caching a copy of your shell,\n\
1913but because gdb could not stat your shell (%s), this is being skipped.\n\
1915 shell, safe_strerror (errno));
1919 if ((sb.st_flags & SF_RESTRICTED) == 0)
1923 std::string new_name = get_standard_cache_dir ();
1926 new_name.append (shell);
1929 if (stat (new_name.c_str (), &sb) != 0 || !S_ISREG (sb.st_mode))
1935 catch (
const gdb_exception_error &ex)
1937 warning (_(
"This version of macOS has System Integrity Protection.\n\
1938Because `startup-with-shell' is enabled, gdb tried to work around SIP by\n\
1939caching a copy of your shell. However, this failed:\n\
1941If you correct the problem, gdb will automatically try again the next time\n\
1942you \"run\". To prevent these attempts, you can use:\n\
1943 set startup-with-shell off"),
1948 gdb_printf (_(
"Note: this version of macOS has System Integrity Protection.\n\
1949Because `startup-with-shell' is enabled, gdb has worked around this by\n\
1950caching a copy of your shell. The shell used by \"run\" is now:\n\
1956 static std::string saved_shell = std::move (new_name);
1966 const std::string &allargs,
1967 char **env,
int from_tty)
1969 gdb::optional<scoped_restore_tmpl<bool>> restore_startup_with_shell;
1976 warning (_(
"startup-with-shell is now temporarily disabled"));
1977 restore_startup_with_shell.emplace (&startup_with_shell, 0);
1983 [the_target] (
int pid)
2015 kret = thread_suspend (thread->
gdb_port);
2029 if (
pid == getpid ())
2030 error (_(
"I refuse to debug myself!"));
2035 error (_(
"Can't attach to process %d: %s (%d)"),
2036 pid, safe_strerror (errno), errno);
2040 inf->attach_flag =
true;
2086 warning (_(
"Unable to detach from process-id %d: %s (%d)"),
2087 inf->
pid, safe_strerror (errno), errno);
2104 long tid = ptid.tid ();
2107 return string_printf (_(
"Thread 0x%lx of process %u"),
2127 gdb_byte *rdaddr,
const gdb_byte *wraddr,
2131 mach_vm_size_t res_length = 0;
2133 inferior_debug (8, _(
"darwin_read_write_inferior(task=0x%x, %s, len=%s)\n"),
2134 task, core_addr_to_string (addr), pulongest (length));
2139 mach_vm_size_t count;
2143 gdb_assert (wraddr == NULL);
2145 kret = mach_vm_read_overwrite (task, addr, length,
2146 (mach_vm_address_t) rdaddr, &count);
2147 if (kret != KERN_SUCCESS)
2150 (1, _(
"darwin_read_write_inferior: mach_vm_read failed at %s: %s"),
2151 core_addr_to_string (addr), mach_error_string (kret));
2158 gdb_assert (wraddr != NULL);
2163 mach_vm_address_t region_address = (mach_vm_address_t) (addr - offset);
2164 mach_vm_size_t aligned_length =
2165 (mach_vm_size_t)
PAGE_ROUND (offset + length);
2166 vm_region_submap_short_info_data_64_t info;
2167 mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
2168 natural_t region_depth = 1000;
2169 mach_vm_address_t region_start = region_address;
2170 mach_vm_size_t region_length;
2171 mach_vm_size_t write_length;
2174 kret = mach_vm_region_recurse
2175 (task, ®ion_start, ®ion_length, ®ion_depth,
2176 (vm_region_recurse_info_t) &info, &count);
2178 if (kret != KERN_SUCCESS)
2181 "mach_vm_region_recurse failed at %s: %s\n"),
2182 core_addr_to_string (region_address),
2183 mach_error_string (kret));
2188 (9, _(
"darwin_read_write_inferior: "
2189 "mach_vm_region_recurse addr=%s, start=%s, len=%s\n"),
2190 core_addr_to_string (region_address),
2191 core_addr_to_string (region_start),
2192 core_addr_to_string (region_length));
2195 if (region_start > region_address)
2197 warning (_(
"No memory at %s (vs %s+0x%x). Nothing written"),
2198 core_addr_to_string (region_address),
2199 core_addr_to_string (region_start),
2200 (
unsigned)region_length);
2205 region_length -= (region_address - region_start);
2206 if (region_length > aligned_length)
2207 region_length = aligned_length;
2210 if (!(info.protection & VM_PROT_WRITE))
2212 vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;
2214 kret = mach_vm_protect (task, region_address, region_length,
2216 if (kret != KERN_SUCCESS)
2218 prot |= VM_PROT_COPY;
2219 kret = mach_vm_protect (task, region_address, region_length,
2222 if (kret != KERN_SUCCESS)
2224 warning (_(
"darwin_read_write_inferior: "
2225 "mach_vm_protect failed at %s "
2226 "(len=0x%lx, prot=0x%x): %s"),
2227 core_addr_to_string (region_address),
2228 (
unsigned long) region_length, (
unsigned) prot,
2229 mach_error_string (kret));
2234 if (offset + length > region_length)
2235 write_length = region_length - offset;
2237 write_length = length;
2240 kret = mach_vm_write (task, addr, (vm_offset_t) wraddr, write_length);
2241 if (kret != KERN_SUCCESS)
2243 warning (_(
"darwin_read_write_inferior: mach_vm_write failed: %s"),
2244 mach_error_string (kret));
2249 if (!(info.protection & VM_PROT_WRITE))
2251 kret = mach_vm_protect (task, region_address, region_length,
2252 FALSE, info.protection);
2253 if (kret != KERN_SUCCESS)
2255 warning (_(
"darwin_read_write_inferior: "
2256 "mach_vm_protect restore failed at %s "
2258 core_addr_to_string (region_address),
2259 (
unsigned long) region_length,
2260 mach_error_string (kret));
2264 addr += write_length;
2265 wraddr += write_length;
2266 res_length += write_length;
2267 length -= write_length;
2277#ifdef TASK_DYLD_INFO_COUNT
2280darwin_read_dyld_info (task_t task, CORE_ADDR addr, gdb_byte *rdaddr,
2281 ULONGEST length, ULONGEST *xfered_len)
2283 struct task_dyld_info task_dyld_info;
2284 mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
2287 if (addr != 0 || length >
sizeof (mach_vm_address_t))
2290 kret = task_info (task, TASK_DYLD_INFO,
2291 (task_info_t) &task_dyld_info, &count);
2293 if (kret != KERN_SUCCESS)
2297 task_dyld_info.all_image_info_addr);
2298 *xfered_len = (ULONGEST) length;
2307 gdb_byte *readbuf,
const gdb_byte *writebuf,
2308 ULONGEST offset, ULONGEST len,
2309 ULONGEST *xfered_len)
2315 (8, _(
"darwin_xfer_partial(%s, %s, rbuf=%s, wbuf=%s) pid=%u\n"),
2316 core_addr_to_string (offset), pulongest (len),
2317 host_address_to_string (readbuf), host_address_to_string (writebuf),
2325 readbuf, writebuf, len);
2332 *xfered_len = (ULONGEST) l;
2336#ifdef TASK_DYLD_INFO_COUNT
2338 if (writebuf != NULL || readbuf == NULL)
2343 return darwin_read_dyld_info (priv->
task, offset, readbuf, len,
2360 exception_mask_t mask;
2364 mask = EXC_MASK_ALL;
2368 mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
2371 EXCEPTION_DEFAULT, THREAD_STATE_NONE);
2379 static char path[PATH_MAX];
2382 res = proc_pidinfo (
pid, PROC_PIDPATHINFO, 0, path, PATH_MAX);
2395 mach_port_name_array_t names;
2396 mach_msg_type_number_t names_count;
2397 mach_port_type_array_t types;
2398 mach_msg_type_number_t types_count;
2404 if (t->inf_port == lwp)
2411 kret = mach_port_names (priv->
task, &names, &names_count, &types,
2414 if (kret != KERN_SUCCESS)
2420 for (
int i = 0; i < names_count; i++)
2422 mach_port_t local_name;
2423 mach_msg_type_name_t local_type;
2427 kret = mach_port_extract_right (priv->
task, names[i],
2428 MACH_MSG_TYPE_COPY_SEND,
2429 &local_name, &local_type);
2430 if (kret != KERN_SUCCESS)
2432 mach_port_deallocate (
gdb_task, local_name);
2436 if (t->gdb_port == local_name)
2438 t->inf_port = names[i];
2439 if (names[i] == lwp)
2445 vm_deallocate (
gdb_task, (vm_address_t) names,
2446 names_count *
sizeof (mach_port_t));
2471 if (kret != KERN_SUCCESS)
2478 (
unsigned long) mach_task_self (), getpid ());
2482Set if printing inferior communication debugging statements."), _(
"\
2483Show if printing inferior communication debugging statements."), NULL,
2489Set if mach exceptions are caught."), _(
"\
2490Show if mach exceptions are caught."), _(
"\
2491When this mode is on, all low level exceptions are reported before being\n\
2492reported by the kernel."),
long __attribute__((__aligned__(4)))
int breakpoint_inserted_here_p(const address_space *aspace, CORE_ADDR pc)
void resume(ptid_t, int, enum gdb_signal) override
ptid_t get_ada_task_ptid(long lwp, ULONGEST thread) override
void init_thread_list(inferior *inf)
void detach(inferior *, int) override
ptid_t wait_1(ptid_t, struct target_waitstatus *)
const char * pid_to_exec_file(int pid) override
void stop_inferior(inferior *inf)
int cancel_breakpoint(ptid_t ptid)
void mourn_inferior() override
bool thread_alive(ptid_t ptid) override
enum target_xfer_status xfer_partial(enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) override
bool supports_multi_process() override
ptid_t wait(ptid_t, struct target_waitstatus *, target_wait_flags) override
ptid_t decode_message(mach_msg_header_t *hdr, darwin_thread_t **pthread, inferior **pinf, target_waitstatus *status)
void check_new_threads(inferior *inf)
int decode_exception_message(mach_msg_header_t *hdr, inferior **pinf, darwin_thread_t **pthread)
void attach(const char *, int) override
std::string pid_to_str(ptid_t) override
void interrupt() override
void create_inferior(const char *exec_file, const std::string &allargs, char **env, int from_tty) override
void mourn_inferior() override
std::unique_ptr< private_inferior > priv
const std::string & args() const
const address_space * aspace() const
struct cmd_list_element * showlist
struct cmd_list_element * setlist
struct cmd_list_element * showdebuglist
struct cmd_list_element * setdebuglist
set_show_commands add_setshow_boolean_cmd(const char *name, enum command_class theclass, bool *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
set_show_commands add_setshow_zuinteger_cmd(const char *name, enum command_class theclass, unsigned int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
static struct inferior * darwin_find_new_inferior(task_t task_port, thread_t thread_port)
static void darwin_setup_exceptions(struct inferior *inf)
static void darwin_reply_to_all_pending_messages(struct inferior *inf)
#define PTRACE(CMD, PID, ADDR, SIG)
mach_port_t darwin_host_self
static int darwin_ptrace(const char *name, int request, int pid, caddr_t arg3, int arg4)
static bool maybe_cache_shell()
static void inferior_debug(int level, const char *fmt,...) ATTRIBUTE_PRINTF(2
static struct inferior * darwin_inf_fake_stop
#define _POSIX_SPAWN_DISABLE_ASLR
static vm_size_t mach_page_size
static const char * copied_shell
static int cmp_thread_t(const void *l, const void *r)
static struct inferior * darwin_find_inferior_by_task(task_t port)
static void set_enable_mach_exceptions(const char *args, int from_tty, struct cmd_list_element *c)
static void darwin_resume_inferior_threads(struct inferior *inf, int step, int nsignal)
static int darwin_pthread_kill(darwin_thread_t *thread, int nsignal)
static void darwin_deallocate_threads(struct inferior *inf)
mach_port_t darwin_ex_port
static void darwin_deallocate_exception_ports(darwin_inferior *inf)
static void darwin_send_reply(struct inferior *inf, darwin_thread_t *thread)
static void darwin_resume_thread(struct inferior *inf, darwin_thread_t *thread, int step, int nsignal)
void mach_check_error(kern_return_t ret, const char *file, unsigned int line, const char *func)
static void darwin_ptrace_me(void)
void _initialize_darwin_nat()
static void darwin_suspend_inferior(struct inferior *inf)
static const char * unparse_exception_type(unsigned int i)
static darwin_thread_t * darwin_find_thread(struct inferior *inf, thread_t thread)
static void copy_shell_to_cache(const char *shell, const std::string &new_name)
static struct inferior * darwin_find_inferior_by_pid(int pid)
static void darwin_pre_ptrace(void)
static void darwin_execvp(const char *file, char *const argv[], char *const env[])
static bool enable_mach_exceptions
static struct thread_info * thread_info_from_private_thread_info(darwin_thread_info *pti)
static void darwin_setup_fake_stop_event(struct inferior *inf)
static void darwin_resume_inferior(struct inferior *inf)
mach_port_t darwin_port_set
static int darwin_check_message_ndr(NDR_record_t *ndr)
static kern_return_t darwin_restore_exception_ports(darwin_inferior *inf)
static void darwin_setup_request_notification(struct inferior *inf)
static bool may_have_sip()
static void darwin_dump_message(mach_msg_header_t *hdr, int disp_body)
static kern_return_t darwin_save_exception_ports(darwin_inferior *inf)
static void darwin_suspend_inferior_threads(struct inferior *inf)
static unsigned int darwin_debug_flag
static void darwin_encode_reply(mig_reply_error_t *reply, mach_msg_header_t *hdr, integer_t code)
static int darwin_read_write_inferior(task_t task, CORE_ADDR addr, gdb_byte *rdaddr, const gdb_byte *wraddr, ULONGEST length)
static void darwin_attach_pid(struct inferior *inf)
static int darwin_decode_notify_message(mach_msg_header_t *hdr, struct inferior **pinf)
mach_port_t darwin_ex_port
static darwin_inferior * get_darwin_inferior(inferior *inf)
void darwin_set_sstep(thread_t thread, int enable)
#define MACH_CHECK_ERROR(ret)
mach_port_t darwin_port_set
void darwin_check_osabi(darwin_inferior *inf, thread_t thread)
static darwin_thread_info * get_darwin_thread_info(class thread_info *thread)
static void store_unsigned_integer(gdb_byte *addr, int len, enum bfd_endian byte_order, ULONGEST val)
ssize_t read(int fd, void *buf, size_t count)
ptid_t gdb_startup_inferior(pid_t pid, int num_traps)
void trace_start_error_with_name(const char *string)
void trace_start_error(const char *fmt,...)
pid_t fork_inferior(const char *exec_file_arg, const std::string &allargs, char **env, void(*traceme_fun)(), gdb::function_view< void(int)> init_trace_fun, void(*pre_trace_fun)(), const char *shell_file_arg, void(*exec_fun)(const char *file, char *const *argv, char *const *env))
#define START_INFERIOR_TRAPS_EXPECTED
static void ATTRIBUTE_PRINTF(1, 0)
#define ptrace(request, pid, addr, data)
CORE_ADDR gdbarch_decr_pc_after_break(struct gdbarch *gdbarch)
all_matching_threads_range all_threads(process_stratum_target *proc_target=nullptr, ptid_t filter_ptid=minus_one_ptid)
thread_info * find_thread_ptid(inferior *inf, ptid_t ptid)
void delete_thread(struct thread_info *thread)
void switch_to_thread(struct thread_info *thr)
struct thread_info * add_thread_with_info(process_stratum_target *targ, ptid_t ptid, private_thread_info *)
void switch_to_no_thread()
void init_thread_list(void)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int int rusage_t pid_t pid
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int status
void inferior_appeared(struct inferior *inf, int pid)
void exit_inferior(inferior *inf)
struct inferior * find_inferior_ptid(process_stratum_target *targ, ptid_t ptid)
struct inferior * current_inferior(void)
all_inferiors_range all_inferiors(process_stratum_target *proc_target=nullptr)
CORE_ADDR regcache_read_pc(struct regcache *regcache)
void regcache_write_pc(struct regcache *regcache, CORE_ADDR pc)
struct regcache * get_thread_regcache(process_stratum_target *target, ptid_t ptid)
void(* func)(remote_target *remote, char *)
std::vector< darwin_thread_t * > threads
unsigned int pending_messages
enum darwin_msg_state msg_state
target_waitkind kind() const
void target_announce_detach(int from_tty)
target_ops * get_native_target()
void target_announce_attach(int from_tty, int pid)
std::string normal_pid_to_str(ptid_t ptid)
void target_mourn_inferior(ptid_t ptid)
@ TARGET_OBJECT_DARWIN_DYLD_INFO
std::string ldirname(const char *filename)
void gdb_vprintf(struct ui_file *stream, const char *format, va_list args)
void gdb_printf(struct ui_file *stream, const char *format,...)
int parse_pid_to_attach(const char *args)
@ TARGET_WAITKIND_STOPPED