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))
356 new_thread_vec.push_back (pti);
360 if (old_ix < old_nbr && (new_ix == new_nbr || new_id > old_id))
366 kret = mach_port_deallocate (
gdb_task, old_id);
371 gdb_assert_not_reached (
"unexpected thread case");
374 darwin_inf->
threads = std::move (new_thread_vec);
377 kret = vm_deallocate (
gdb_task, (vm_address_t) thread_list,
378 new_nbr *
sizeof (
int));
390 if (
priv !=
nullptr &&
priv->task == port)
417 if (t->gdb_port == thread)
431 if (
priv !=
nullptr && !
priv->suspended)
435 kret = task_suspend (
priv->task);
449 if (
priv !=
nullptr &&
priv->suspended)
453 kret = task_resume (
priv->task);
464 _(
"message header:\n"));
466 _(
" bits: 0x%x\n"), hdr->msgh_bits);
468 _(
" size: 0x%x\n"), hdr->msgh_size);
470 _(
" remote-port: 0x%x\n"), hdr->msgh_remote_port);
472 _(
" local-port: 0x%x\n"), hdr->msgh_local_port);
474 _(
" reserved: 0x%x\n"), hdr->msgh_reserved);
476 _(
" id: 0x%x\n"), hdr->msgh_id);
480 const unsigned char *data;
481 const unsigned int *ldata;
485 data = (
unsigned char *)(hdr + 1);
486 size = hdr->msgh_size -
sizeof (mach_msg_header_t);
488 if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
490 mach_msg_body_t *bod = (mach_msg_body_t*)data;
491 mach_msg_port_descriptor_t *desc =
492 (mach_msg_port_descriptor_t *)(bod + 1);
496 _(
"body: descriptor_count=%u\n"),
497 bod->msgh_descriptor_count);
498 data +=
sizeof (mach_msg_body_t);
499 size -=
sizeof (mach_msg_body_t);
500 for (k = 0; k < bod->msgh_descriptor_count; k++)
501 switch (desc[k].
type)
503 case MACH_MSG_PORT_DESCRIPTOR:
506 _(
" descr %d: type=%u (port) name=0x%x, dispo=%d\n"),
507 k, desc[k].
type, desc[k].
name, desc[k].disposition);
511 _(
" descr %d: type=%u\n"),
515 data += bod->msgh_descriptor_count
516 *
sizeof (mach_msg_port_descriptor_t);
517 size -= bod->msgh_descriptor_count
518 *
sizeof (mach_msg_port_descriptor_t);
519 ndr = (NDR_record_t *)(desc + bod->msgh_descriptor_count);
522 _(
"NDR: mig=%02x if=%02x encod=%02x "
523 "int=%02x char=%02x float=%02x\n"),
524 ndr->mig_vers, ndr->if_vers, ndr->mig_encoding,
525 ndr->int_rep, ndr->char_rep, ndr->float_rep);
526 data +=
sizeof (NDR_record_t);
527 size -=
sizeof (NDR_record_t);
531 ldata = (
const unsigned int *)data;
532 for (i = 0; i <
size /
sizeof (
unsigned int); i++)
549 kret = pid_for_task (task_port, &task_pid);
550 if (kret != KERN_SUCCESS)
567 kret = mach_port_request_notification (
gdb_task,
priv->task,
568 MACH_NOTIFY_DEAD_NAME, 0,
570 MACH_MSG_TYPE_MAKE_SEND_ONCE,
572 if (kret != KERN_INVALID_ARGUMENT)
578 priv->task = task_port;
591 if (ndr->mig_vers != NDR_PROTOCOL_2_0
592 || ndr->if_vers != NDR_PROTOCOL_2_0
593 || ndr->mig_encoding != NDR_record.mig_encoding
594 || ndr->int_rep != NDR_record.int_rep
595 || ndr->char_rep != NDR_record.char_rep
596 || ndr->float_rep != NDR_record.float_rep)
608 mach_msg_body_t *bod = (mach_msg_body_t*)(hdr + 1);
609 mach_msg_port_descriptor_t *desc = (mach_msg_port_descriptor_t *)(bod + 1);
624 if (!(hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX))
628 if (hdr->msgh_size < (sizeof (*hdr) +
sizeof (*bod) + 2 *
sizeof (*desc)
629 +
sizeof (*ndr) + 2 *
sizeof (integer_t))
630 || bod->msgh_descriptor_count != 2
631 || desc[0].type != MACH_MSG_PORT_DESCRIPTOR
632 || desc[0].disposition != MACH_MSG_TYPE_MOVE_SEND
633 || desc[1].type != MACH_MSG_PORT_DESCRIPTOR
634 || desc[1].disposition != MACH_MSG_TYPE_MOVE_SEND)
638 ndr = (NDR_record_t *)(desc + 2);
643 data = (integer_t *)(ndr + 1);
645 task_port = desc[1].name;
646 thread_port = desc[0].name;
652 if (
inf == NULL && data[0] == EXC_SOFTWARE && data[1] == 2
653 && data[2] == EXC_SOFT_SIGNAL && data[3] == SIGTRAP)
663 kret = mach_port_deallocate (mach_task_self (), task_port);
671 kret = mach_port_deallocate (mach_task_self (), task_port);
680 mig_reply_error_t reply;
683 (4, _(
"darwin_decode_exception_message: unknown task 0x%x\n"),
687 kret = mach_port_deallocate (mach_task_self (), thread_port);
692 kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
693 reply.Head.msgh_size, 0,
694 MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
708 kret = mach_port_deallocate (mach_task_self (), thread_port);
721 thread->
event.header = *hdr;
722 thread->
event.thread_port = thread_port;
723 thread->
event.task_port = task_port;
724 thread->
event.ex_type = data[0];
725 thread->
event.data_count = data[1];
727 if (hdr->msgh_size < (sizeof (*hdr) +
sizeof (*bod) + 2 *
sizeof (*desc)
728 +
sizeof (*ndr) + 2 *
sizeof (integer_t)
729 + data[1] *
sizeof (integer_t)))
731 for (i = 0; i < data[1]; i++)
732 thread->
event.ex_data[i] = data[2 + i];
744 NDR_record_t *ndr = (NDR_record_t *)(hdr + 1);
745 integer_t *data = (integer_t *)(ndr + 1);
750 if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
754 if (hdr->msgh_size < (sizeof (*hdr) +
sizeof (*ndr) +
sizeof (integer_t)))
771 if (hdr->msgh_local_port !=
priv->notify_port)
782 mach_msg_header_t *rh = &reply->Head;
784 rh->msgh_bits = MACH_MSGH_BITS (MACH_MSGH_BITS_REMOTE (hdr->msgh_bits), 0);
785 rh->msgh_remote_port = hdr->msgh_remote_port;
786 rh->msgh_size = (mach_msg_size_t)
sizeof (mig_reply_error_t);
787 rh->msgh_local_port = MACH_PORT_NULL;
788 rh->msgh_id = hdr->msgh_id + 100;
790 reply->NDR = NDR_record;
791 reply->RetCode =
code;
798 mig_reply_error_t reply;
803 kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
804 reply.Head.msgh_size, 0,
805 MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
809 priv->pending_messages--;
820 DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS;
828 int step,
int nsignal)
831 (3, _(
"darwin_resume_thread: state=%d, thread=0x%x, step=%d nsignal=%d\n"),
837 if (thread->
event.ex_type == EXC_SOFTWARE
838 && thread->
event.ex_data[0] == EXC_SOFT_SIGNAL)
842 (caddr_t) (uintptr_t) thread->
gdb_port, nsignal);
857 inferior_debug (4, _(
"darwin_set_sstep (thread=0x%x, enable=%d)\n"),
870 kern_return_t kret = thread_resume (thread->
gdb_port);
899 switch (thread->msg_state)
906 kern_return_t kret = thread_suspend (thread->gdb_port);
921 (2, _(
"darwin_resume: ptid=%s, step=%d, signal=%d\n"),
922 ptid.to_string ().c_str (), step, signal);
924 if (signal == GDB_SIGNAL_0)
927 nsignal = gdb_signal_to_host (signal);
934 if (ptid == minus_one_ptid)
947 long tid = ptid.tid ();
982 if (hdr->msgh_id == 2401)
992 warning (_(
"darwin_wait: ill-formatted message (id=0x%x)\n"),
996 return minus_one_ptid;
1001 return minus_one_ptid;
1016 switch (thread->
event.ex_type)
1018 case EXC_BAD_ACCESS:
1019 status->set_stopped (GDB_EXC_BAD_ACCESS);
1021 case EXC_BAD_INSTRUCTION:
1022 status->set_stopped (GDB_EXC_BAD_INSTRUCTION);
1024 case EXC_ARITHMETIC:
1025 status->set_stopped (GDB_EXC_ARITHMETIC);
1028 status->set_stopped (GDB_EXC_EMULATION);
1031 if (thread->
event.ex_data[0] == EXC_SOFT_SIGNAL)
1034 (gdb_signal_from_host (thread->
event.ex_data[1]));
1036 thread->
event.ex_data[1],
1037 gdb_signal_to_name (
status->sig ()));
1050 status->set_stopped (GDB_EXC_SOFTWARE);
1052 case EXC_BREAKPOINT:
1056 status->set_stopped (GDB_SIGNAL_TRAP);
1059 status->set_stopped (GDB_SIGNAL_UNKNOWN);
1065 else if (hdr->msgh_id == 0x48)
1076 (_(
"darwin_wait: ill-formatted message (id=0x%x, res=%d)\n"),
1083 if (res < 0 ||
inf == NULL)
1086 return minus_one_ptid;
1098 res_pid = wait4 (
inf->
pid, &wstatus, 0, NULL);
1099 if (res_pid < 0 || res_pid != inf->
pid)
1101 warning (_(
"wait4: res=%d: %s\n"),
1102 res_pid, safe_strerror (errno));
1104 return minus_one_ptid;
1106 if (WIFEXITED (wstatus))
1108 status->set_exited (WEXITSTATUS (wstatus));
1112 else if (WIFSTOPPED (wstatus))
1117 inferior_debug (4, _(
"darwin_wait: pid %d received WIFSTOPPED\n"),
1119 return minus_one_ptid;
1121 else if (WIFSIGNALED (wstatus))
1124 (gdb_signal_from_host (WTERMSIG (wstatus)));
1125 inferior_debug (4, _(
"darwin_wait: pid=%d received signal %d\n"),
1131 warning (_(
"Unexpected wait status after MACH_NOTIFY_DEAD_NAME "
1132 "notification: 0x%x"), wstatus);
1133 return minus_one_ptid;
1136 return ptid_t (
inf->
pid);
1142 return ptid_t (
inf->
pid, 0, 0);
1148 warning (_(
"darwin: got unknown message, id: 0x%x"), hdr->msgh_id);
1150 return minus_one_ptid;
1172 (
unsigned long) ptid.tid ());
1189 mach_msg_header_t hdr;
1192 mach_msg_header_t *hdr = &msgin.hdr;
1197 (2, _(
"darwin_wait: waiting for a message ptid=%s\n"),
1198 ptid.to_string ().c_str ());
1208 status->set_stopped (GDB_SIGNAL_TRAP);
1219 kret = mach_msg (&msgin.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0,
1224 if (kret == MACH_RCV_INTERRUPTED)
1227 return minus_one_ptid;
1230 if (kret != MACH_MSG_SUCCESS)
1234 return minus_one_ptid;
1243 if (res == minus_one_ptid)
1265 kret = mach_msg (&msgin.hdr,
1266 MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0,
1269 if (kret == MACH_RCV_TIMED_OUT)
1271 if (kret != MACH_MSG_SUCCESS)
1274 (5, _(
"darwin_wait: mach_msg(pending) ret=0x%x\n"), kret);
1285 if (
inf != NULL && thread != NULL
1286 && thread->
event.ex_type == EXC_BREAKPOINT)
1297 (3, _(
"darwin_wait: thread 0x%x hit a non-gdb breakpoint\n"),
1301 inferior_debug (3, _(
"darwin_wait: unhandled pending message\n"));
1308 target_wait_flags options)
1333 kern_return_t kret = mach_port_deallocate (
gdb_task, t->gdb_port);
1337 priv->threads.clear ();
1352 kret = mach_port_move_member (
gdb_task,
1357 kret = mach_port_request_notification (
gdb_task, priv->
task,
1358 MACH_NOTIFY_DEAD_NAME, 0,
1360 MACH_MSG_TYPE_MAKE_SEND_ONCE,
1366 if (kret == KERN_SUCCESS)
1368 kret = mach_port_deallocate (
gdb_task, prev);
1408 gdb_assert (
inf != NULL);
1419 warning (_(
"cannot kill: %s"), safe_strerror (errno));
1426 && wstatus.
sig () == GDB_SIGNAL_STOP)
1436 inf->exception_info.count =
1437 sizeof (
inf->exception_info.ports) /
sizeof (
inf->exception_info.ports[0]);
1439 kret = task_get_exception_ports
1440 (
inf->
task, EXC_MASK_ALL,
inf->exception_info.masks,
1441 &
inf->exception_info.count,
inf->exception_info.ports,
1442 inf->exception_info.behaviors,
inf->exception_info.flavors);
1452 for (i = 0; i <
inf->exception_info.count; i++)
1454 kret = task_set_exception_ports
1455 (
inf->
task,
inf->exception_info.masks[i],
inf->exception_info.ports[i],
1456 inf->exception_info.behaviors[i],
inf->exception_info.flavors[i]);
1457 if (kret != KERN_SUCCESS)
1461 return KERN_SUCCESS;
1472 for (i = 0; i <
inf->exception_info.count; i++)
1474 kret = mach_port_deallocate (
gdb_task,
inf->exception_info.ports[i]);
1477 inf->exception_info.count = 0;
1485 exception_mask_t mask;
1488 if (kret != KERN_SUCCESS)
1489 error (_(
"Unable to save exception ports, task_get_exception_ports"
1495 mask = EXC_MASK_ALL;
1497 mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
1499 EXCEPTION_DEFAULT, THREAD_STATE_NONE);
1500 if (kret != KERN_SUCCESS)
1501 error (_(
"Unable to set exception ports, task_set_exception_ports"
1519 gdb_assert (
inf != NULL);
1545 thread->signaled = 1;
1551 else if (errno != ESRCH)
1552 warning (_(
"Failed to kill inferior: kill (%d, 9) returned [%s]"),
1553 inf->
pid, safe_strerror (errno));
1563 mach_port_t prev_not;
1565 kret = mach_port_request_notification (
gdb_task, priv->
task,
1566 MACH_NOTIFY_DEAD_NAME, 0,
1568 MACH_MSG_TYPE_MAKE_SEND_ONCE,
1570 if (kret != KERN_SUCCESS)
1571 error (_(
"Termination notification request failed, "
1572 "mach_port_request_notification\n"
1575 if (prev_not != MACH_PORT_NULL)
1581A task termination request was registered before the debugger registered\n\
1582its own. This is unexpected, but should otherwise not have any actual\n\
1583impact on the debugging session."));
1593 inf->priv.reset (priv);
1598 if (kret != KERN_SUCCESS)
1602 if (!
inf->attach_flag)
1609 (_(
"Unable to find Mach task port for process-id %d: %s (0x%lx).\n"
1610 " (please check gdb is codesigned - see taskgated(8))"),
1611 inf->
pid, mach_error_string (kret), (
unsigned long) kret);
1620 kret = mach_port_allocate (
gdb_task, MACH_PORT_RIGHT_RECEIVE,
1622 if (kret != KERN_SUCCESS)
1623 error (_(
"Unable to create exception port, mach_port_allocate "
1629 MACH_MSG_TYPE_MAKE_SEND);
1630 if (kret != KERN_SUCCESS)
1631 error (_(
"Unable to create exception port, mach_port_insert_right "
1636 kret = mach_port_allocate (
gdb_task, MACH_PORT_RIGHT_PORT_SET,
1638 if (kret != KERN_SUCCESS)
1639 error (_(
"Unable to create port set, mach_port_allocate "
1645 if (kret != KERN_SUCCESS)
1646 error (_(
"Unable to move exception port into new port set, "
1647 "mach_port_move_member\n"
1653 kret = mach_port_allocate (
gdb_task, MACH_PORT_RIGHT_RECEIVE,
1655 if (kret != KERN_SUCCESS)
1656 error (_(
"Unable to create notification port, mach_port_allocate "
1660 kret = mach_port_move_member (
gdb_task,
1662 if (kret != KERN_SUCCESS)
1663 error (_(
"Unable to move notification port into new port set, "
1664 "mach_port_move_member\n"
1672 catch (
const gdb_exception &ex)
1681 if (!
inf->target_is_pushed (darwin_ops))
1682 inf->push_target (darwin_ops);
1698 gdb_assert_not_reached (
"did not find gdb thread for darwin thread");
1708 gdb_assert (!priv->
threads.empty ());
1741 if (setegid (getgid ()) < 0)
1749 if (
PTRACE (PT_SIGEXC, 0, 0, 0) < 0)
1761 error (_(
"unable to create a pipe: %s"), safe_strerror (errno));
1790 posix_spawnattr_t attr;
1794 res = posix_spawnattr_init (&attr);
1798 (
gdb_stderr,
"Cannot initialize attribute for posix_spawn\n");
1803 ps_flags = POSIX_SPAWN_SETEXEC;
1807#ifndef _POSIX_SPAWN_DISABLE_ASLR
1808#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
1811 res = posix_spawnattr_setflags (&attr, ps_flags);
1818 posix_spawnp (NULL, argv[0], NULL, &attr, argv, env);
1828 size_t sz =
sizeof (str);
1831 ret = sysctlbyname (
"kern.osrelease", str, &sz, NULL, 0);
1832 if (ret == 0 && sz <
sizeof (str))
1834 unsigned long ver = strtoul (str, NULL, 10);
1847 scoped_fd from_fd = gdb_open_cloexec (shell, O_RDONLY, 0);
1848 if (from_fd.get () < 0)
1849 error (_(
"Could not open shell (%s) for reading: %s"),
1850 shell, safe_strerror (errno));
1852 std::string new_dir =
ldirname (new_name.c_str ());
1853 if (!mkdir_recursive (new_dir.c_str ()))
1854 error (_(
"Could not make cache directory \"%s\": %s"),
1855 new_dir.c_str (), safe_strerror (errno));
1857 gdb::char_vector temp_name = make_temp_filename (new_name);
1858 scoped_fd to_fd = gdb_mkostemp_cloexec (&temp_name[0]);
1859 gdb::unlinker unlink_file_on_error (temp_name.data ());
1861 if (to_fd.get () < 0)
1862 error (_(
"Could not open temporary file \"%s\" for writing: %s"),
1863 temp_name.data (), safe_strerror (errno));
1865 if (fcopyfile (from_fd.get (), to_fd.get (),
nullptr,
1866 COPYFILE_STAT | COPYFILE_DATA) != 0)
1867 error (_(
"Could not copy shell to cache as \"%s\": %s"),
1868 temp_name.data (), safe_strerror (errno));
1872 if (rename (temp_name.data (), new_name.c_str ()) != 0)
1873 error (_(
"Could not rename shell cache file to \"%s\": %s"),
1874 new_name.c_str (), safe_strerror (errno));
1876 unlink_file_on_error.keep ();
1899 const char *shell = get_shell ();
1900 if (!IS_ABSOLUTE_PATH (shell))
1902 warning (_(
"This version of macOS has System Integrity Protection.\n\
1903Normally gdb would try to work around this by caching a copy of your shell,\n\
1904but because your shell (%s) is not an absolute path, this is being skipped."),
1910 if (stat (shell, &sb) < 0)
1912 warning (_(
"This version of macOS has System Integrity Protection.\n\
1913Normally gdb would try to work around this by caching a copy of your shell,\n\
1914but because gdb could not stat your shell (%s), this is being skipped.\n\
1916 shell, safe_strerror (errno));
1920 if ((sb.st_flags & SF_RESTRICTED) == 0)
1924 std::string new_name = get_standard_cache_dir ();
1927 new_name.append (shell);
1930 if (stat (new_name.c_str (), &sb) != 0 || !S_ISREG (sb.st_mode))
1936 catch (
const gdb_exception_error &ex)
1938 warning (_(
"This version of macOS has System Integrity Protection.\n\
1939Because `startup-with-shell' is enabled, gdb tried to work around SIP by\n\
1940caching a copy of your shell. However, this failed:\n\
1942If you correct the problem, gdb will automatically try again the next time\n\
1943you \"run\". To prevent these attempts, you can use:\n\
1944 set startup-with-shell off"),
1949 gdb_printf (_(
"Note: this version of macOS has System Integrity Protection.\n\
1950Because `startup-with-shell' is enabled, gdb has worked around this by\n\
1951caching a copy of your shell. The shell used by \"run\" is now:\n\
1957 static std::string saved_shell = std::move (new_name);
1967 const std::string &allargs,
1968 char **env,
int from_tty)
1970 gdb::optional<scoped_restore_tmpl<bool>> restore_startup_with_shell;
1977 warning (_(
"startup-with-shell is now temporarily disabled"));
1978 restore_startup_with_shell.emplace (&startup_with_shell, 0);
1984 [the_target] (
int pid)
2016 kret = thread_suspend (thread->
gdb_port);
2030 if (
pid == getpid ())
2031 error (_(
"I refuse to debug myself!"));
2036 error (_(
"Can't attach to process %d: %s (%d)"),
2037 pid, safe_strerror (errno), errno);
2041 inf->attach_flag =
true;
2087 warning (_(
"Unable to detach from process-id %d: %s (%d)"),
2088 inf->
pid, safe_strerror (errno), errno);
2105 long tid = ptid.tid ();
2108 return string_printf (_(
"Thread 0x%lx of process %u"),
2128 gdb_byte *rdaddr,
const gdb_byte *wraddr,
2132 mach_vm_size_t res_length = 0;
2134 inferior_debug (8, _(
"darwin_read_write_inferior(task=0x%x, %s, len=%s)\n"),
2135 task, core_addr_to_string (addr), pulongest (length));
2140 mach_vm_size_t count;
2144 gdb_assert (wraddr == NULL);
2146 kret = mach_vm_read_overwrite (task, addr, length,
2147 (mach_vm_address_t) rdaddr, &count);
2148 if (kret != KERN_SUCCESS)
2151 (1, _(
"darwin_read_write_inferior: mach_vm_read failed at %s: %s"),
2152 core_addr_to_string (addr), mach_error_string (kret));
2159 gdb_assert (wraddr != NULL);
2164 mach_vm_address_t region_address = (mach_vm_address_t) (addr - offset);
2165 mach_vm_size_t aligned_length =
2166 (mach_vm_size_t)
PAGE_ROUND (offset + length);
2167 vm_region_submap_short_info_data_64_t info;
2168 mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
2169 natural_t region_depth = 1000;
2170 mach_vm_address_t region_start = region_address;
2171 mach_vm_size_t region_length;
2172 mach_vm_size_t write_length;
2175 kret = mach_vm_region_recurse
2176 (task, ®ion_start, ®ion_length, ®ion_depth,
2177 (vm_region_recurse_info_t) &info, &count);
2179 if (kret != KERN_SUCCESS)
2182 "mach_vm_region_recurse failed at %s: %s\n"),
2183 core_addr_to_string (region_address),
2184 mach_error_string (kret));
2189 (9, _(
"darwin_read_write_inferior: "
2190 "mach_vm_region_recurse addr=%s, start=%s, len=%s\n"),
2191 core_addr_to_string (region_address),
2192 core_addr_to_string (region_start),
2193 core_addr_to_string (region_length));
2196 if (region_start > region_address)
2198 warning (_(
"No memory at %s (vs %s+0x%x). Nothing written"),
2199 core_addr_to_string (region_address),
2200 core_addr_to_string (region_start),
2201 (
unsigned)region_length);
2206 region_length -= (region_address - region_start);
2207 if (region_length > aligned_length)
2208 region_length = aligned_length;
2211 if (!(info.protection & VM_PROT_WRITE))
2213 vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;
2215 kret = mach_vm_protect (task, region_address, region_length,
2217 if (kret != KERN_SUCCESS)
2219 prot |= VM_PROT_COPY;
2220 kret = mach_vm_protect (task, region_address, region_length,
2223 if (kret != KERN_SUCCESS)
2225 warning (_(
"darwin_read_write_inferior: "
2226 "mach_vm_protect failed at %s "
2227 "(len=0x%lx, prot=0x%x): %s"),
2228 core_addr_to_string (region_address),
2229 (
unsigned long) region_length, (
unsigned) prot,
2230 mach_error_string (kret));
2235 if (offset + length > region_length)
2236 write_length = region_length - offset;
2238 write_length = length;
2241 kret = mach_vm_write (task, addr, (vm_offset_t) wraddr, write_length);
2242 if (kret != KERN_SUCCESS)
2244 warning (_(
"darwin_read_write_inferior: mach_vm_write failed: %s"),
2245 mach_error_string (kret));
2250 if (!(info.protection & VM_PROT_WRITE))
2252 kret = mach_vm_protect (task, region_address, region_length,
2253 FALSE, info.protection);
2254 if (kret != KERN_SUCCESS)
2256 warning (_(
"darwin_read_write_inferior: "
2257 "mach_vm_protect restore failed at %s "
2259 core_addr_to_string (region_address),
2260 (
unsigned long) region_length,
2261 mach_error_string (kret));
2265 addr += write_length;
2266 wraddr += write_length;
2267 res_length += write_length;
2268 length -= write_length;
2278#ifdef TASK_DYLD_INFO_COUNT
2281darwin_read_dyld_info (task_t task, CORE_ADDR addr, gdb_byte *rdaddr,
2282 ULONGEST length, ULONGEST *xfered_len)
2284 struct task_dyld_info task_dyld_info;
2285 mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
2288 if (addr != 0 || length >
sizeof (mach_vm_address_t))
2291 kret = task_info (task, TASK_DYLD_INFO,
2292 (task_info_t) &task_dyld_info, &count);
2294 if (kret != KERN_SUCCESS)
2298 task_dyld_info.all_image_info_addr);
2299 *xfered_len = (ULONGEST) length;
2308 gdb_byte *readbuf,
const gdb_byte *writebuf,
2309 ULONGEST offset, ULONGEST len,
2310 ULONGEST *xfered_len)
2316 (8, _(
"darwin_xfer_partial(%s, %s, rbuf=%s, wbuf=%s) pid=%u\n"),
2317 core_addr_to_string (offset), pulongest (len),
2318 host_address_to_string (readbuf), host_address_to_string (writebuf),
2326 readbuf, writebuf, len);
2333 *xfered_len = (ULONGEST) l;
2337#ifdef TASK_DYLD_INFO_COUNT
2339 if (writebuf != NULL || readbuf == NULL)
2344 return darwin_read_dyld_info (priv->
task, offset, readbuf, len,
2361 exception_mask_t mask;
2365 mask = EXC_MASK_ALL;
2369 mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
2372 EXCEPTION_DEFAULT, THREAD_STATE_NONE);
2380 static char path[PATH_MAX];
2383 res = proc_pidinfo (
pid, PROC_PIDPATHINFO, 0, path, PATH_MAX);
2396 mach_port_name_array_t names;
2397 mach_msg_type_number_t names_count;
2398 mach_port_type_array_t types;
2399 mach_msg_type_number_t types_count;
2405 if (t->inf_port == lwp)
2412 kret = mach_port_names (priv->
task, &names, &names_count, &types,
2415 if (kret != KERN_SUCCESS)
2421 for (
int i = 0; i < names_count; i++)
2423 mach_port_t local_name;
2424 mach_msg_type_name_t local_type;
2428 kret = mach_port_extract_right (priv->
task, names[i],
2429 MACH_MSG_TYPE_COPY_SEND,
2430 &local_name, &local_type);
2431 if (kret != KERN_SUCCESS)
2433 mach_port_deallocate (
gdb_task, local_name);
2437 if (t->gdb_port == local_name)
2439 t->inf_port = names[i];
2440 if (names[i] == lwp)
2446 vm_deallocate (
gdb_task, (vm_address_t) names,
2447 names_count *
sizeof (mach_port_t));
2472 if (kret != KERN_SUCCESS)
2479 (
unsigned long) mach_task_self (), getpid ());
2483Set if printing inferior communication debugging statements."), _(
"\
2484Show if printing inferior communication debugging statements."), NULL,
2490Set if mach exceptions are caught."), _(
"\
2491Show if mach exceptions are caught."), _(
"\
2492When this mode is on, all low level exceptions are reported before being\n\
2493reported 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
thread_info * find_thread(ptid_t ptid)
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)
void delete_thread(thread_info *thread)
void switch_to_thread(struct thread_info *thr)
std::unique_ptr< private_thread_info > private_thread_info_up
struct thread_info * add_thread_with_info(process_stratum_target *targ, ptid_t ptid, private_thread_info_up)
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)
struct inferior * find_inferior_ptid(process_stratum_target *targ, ptid_t ptid)
struct inferior * current_inferior(void)
void exit_inferior(struct inferior *inf)
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