39 #include "bfd/mach-o.h" 41 #include <sys/ptrace.h> 42 #include <sys/signal.h> 44 #include <sys/types.h> 48 #include <sys/sysctl.h> 51 #include <sys/syscall.h> 54 #include <mach/mach_error.h> 55 #include <mach/mach_vm.h> 56 #include <mach/mach_init.h> 57 #include <mach/vm_map.h> 58 #include <mach/task.h> 59 #include <mach/mach_port.h> 60 #include <mach/thread_act.h> 61 #include <mach/port.h> 83 #define PTRACE(CMD, PID, ADDR, SIG) \ 84 darwin_ptrace(#CMD, CMD, (PID), (ADDR), (SIG)) 89 enum gdb_signal signal);
91 enum gdb_signal signal);
106 const char *exec_file,
108 char **env,
int from_tty);
117 mach_msg_header_t *hdr, integer_t
code);
149 #define PAGE_TRUNC(x) ((x) & ~(mach_page_size - 1)) 150 #define PAGE_ROUND(x) PAGE_TRUNC((x) + mach_page_size - 1) 160 static const unsigned char info_plist[]
162 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 163 "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\"" 164 " \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" 165 "<plist version=\"1.0\">\n" 167 " <key>CFBundleIdentifier</key>\n" 168 " <string>org.gnu.gdb</string>\n" 169 " <key>CFBundleName</key>\n" 170 " <string>gdb</string>\n" 171 " <key>CFBundleVersion</key>\n" 172 " <string>1.0</string>\n" 173 " <key>SecTaskAccess</key>\n" 175 " <string>allowed</string>\n" 176 " <string>debug</string>\n" 200 unsigned int line,
const char *
func)
202 if (ret == KERN_SUCCESS)
205 func =
_(
"[UNKNOWN]");
207 warning (
_(
"Mach error at \"%s:%u\" in function \"%s\": %s (0x%lx)"),
208 file, line,
func, mach_error_string (ret), (
unsigned long) ret);
214 static char unknown_exception_buf[32];
219 return "EXC_BAD_ACCESS";
220 case EXC_BAD_INSTRUCTION:
221 return "EXC_BAD_INSTRUCTION";
223 return "EXC_ARITHMETIC";
225 return "EXC_EMULATION";
227 return "EXC_SOFTWARE";
229 return "EXC_BREAKPOINT";
231 return "EXC_SYSCALL";
232 case EXC_MACH_SYSCALL:
233 return "EXC_MACH_SYSCALL";
235 return "EXC_RPC_ALERT";
239 snprintf (unknown_exception_buf, 32,
_(
"unknown (%d)"), i);
240 return unknown_exception_buf;
255 int request,
int pid, caddr_t arg3,
int arg4)
261 if (ret == -1 && errno == 0)
265 name,
pid, (
unsigned long) arg3, arg4, ret,
275 return (
int)(tl - tr);
283 unsigned int new_nbr;
284 unsigned int old_nbr;
285 unsigned int new_ix, old_ix;
287 std::vector<darwin_thread_t *> new_thread_vec;
292 if (kret != KERN_SUCCESS)
299 old_nbr = darwin_inf->
threads.size ();
302 if (old_nbr == new_nbr)
306 for (i = 0; i < new_nbr; i++)
312 for (i = 0; i < new_nbr; i++)
314 kret = mach_port_deallocate (mach_task_self (),
thread_list[i]);
320 new_nbr *
sizeof (
int));
329 new_thread_vec.reserve (new_nbr);
331 for (new_ix = 0, old_ix = 0; new_ix < new_nbr || old_ix < old_nbr;)
335 = (old_ix < old_nbr) ? darwin_inf->
threads[old_ix] : NULL;
339 (12,
_(
" new_ix:%d/%d, old_ix:%d/%d, new_id:0x%x old_id:0x%x\n"),
340 new_ix, new_nbr, old_ix, old_nbr, new_id, old_id);
342 if (old_id == new_id)
345 new_thread_vec.push_back (old);
350 kret = mach_port_deallocate (
gdb_task, new_id);
355 if (new_ix < new_nbr && new_id == MACH_PORT_DEAD)
363 if (new_ix < new_nbr && (old_ix == old_nbr || new_id < old_id))
373 new_thread_vec.push_back (pti);
377 if (old_ix < old_nbr && (new_ix == new_nbr || new_id > old_id))
381 kret = mach_port_deallocate (
gdb_task, old_id);
389 darwin_inf->
threads = std::move (new_thread_vec);
393 new_nbr *
sizeof (
int));
402 return priv->task == *(task_t *)port_ptr;
408 return inf->
pid == *(
int *)pid_ptr;
447 if (!
priv->suspended)
451 kret = task_suspend (
priv->task);
469 kret = task_resume (
priv->task);
506 const unsigned char *data;
507 const unsigned int *ldata;
511 data = (
unsigned char *)(hdr + 1);
512 size = hdr->msgh_size -
sizeof (mach_msg_header_t);
514 if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
516 mach_msg_body_t *bod = (mach_msg_body_t*)data;
517 mach_msg_port_descriptor_t *desc =
518 (mach_msg_port_descriptor_t *)(bod + 1);
522 bod->msgh_descriptor_count);
523 data +=
sizeof (mach_msg_body_t);
524 size -=
sizeof (mach_msg_body_t);
525 for (k = 0; k < bod->msgh_descriptor_count; k++)
526 switch (desc[k].
type)
528 case MACH_MSG_PORT_DESCRIPTOR:
530 (
_(
" descr %d: type=%u (port) name=0x%x, dispo=%d\n"),
531 k, desc[k].
type, desc[k].
name, desc[k].disposition);
538 data += bod->msgh_descriptor_count
539 *
sizeof (mach_msg_port_descriptor_t);
540 size -= bod->msgh_descriptor_count
541 *
sizeof (mach_msg_port_descriptor_t);
542 ndr = (NDR_record_t *)(desc + bod->msgh_descriptor_count);
544 (
_(
"NDR: mig=%02x if=%02x encod=%02x " 545 "int=%02x char=%02x float=%02x\n"),
546 ndr->mig_vers, ndr->if_vers, ndr->mig_encoding,
547 ndr->int_rep, ndr->char_rep, ndr->float_rep);
548 data +=
sizeof (NDR_record_t);
549 size -=
sizeof (NDR_record_t);
553 ldata = (
const unsigned int *)data;
554 for (i = 0; i <
size /
sizeof (
unsigned int); i++)
571 kret = pid_for_task (task_port, &task_pid);
572 if (kret != KERN_SUCCESS)
589 kret = mach_port_request_notification (
gdb_task,
priv->task,
590 MACH_NOTIFY_DEAD_NAME, 0,
592 MACH_MSG_TYPE_MAKE_SEND_ONCE,
594 if (kret != KERN_INVALID_ARGUMENT)
600 priv->task = task_port;
613 if (ndr->mig_vers != NDR_PROTOCOL_2_0
614 || ndr->if_vers != NDR_PROTOCOL_2_0
615 || ndr->mig_encoding != NDR_record.mig_encoding
616 || ndr->int_rep != NDR_record.int_rep
617 || ndr->char_rep != NDR_record.char_rep
618 || ndr->float_rep != NDR_record.float_rep)
630 mach_msg_body_t *bod = (mach_msg_body_t*)(hdr + 1);
631 mach_msg_port_descriptor_t *desc = (mach_msg_port_descriptor_t *)(bod + 1);
646 if (!(hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX))
650 if (hdr->msgh_size < (sizeof (*hdr) +
sizeof (*bod) + 2 *
sizeof (*desc)
651 +
sizeof (*ndr) + 2 *
sizeof (integer_t))
652 || bod->msgh_descriptor_count != 2
653 || desc[0].type != MACH_MSG_PORT_DESCRIPTOR
654 || desc[0].disposition != MACH_MSG_TYPE_MOVE_SEND
655 || desc[1].type != MACH_MSG_PORT_DESCRIPTOR
656 || desc[1].disposition != MACH_MSG_TYPE_MOVE_SEND)
660 ndr = (NDR_record_t *)(desc + 2);
665 data = (integer_t *)(ndr + 1);
667 task_port = desc[1].name;
668 thread_port = desc[0].name;
674 if (
inf == NULL && data[0] == EXC_SOFTWARE && data[1] == 2
675 && data[2] == EXC_SOFT_SIGNAL && data[3] == SIGTRAP)
685 kret = mach_port_deallocate (mach_task_self (), task_port);
693 kret = mach_port_deallocate (mach_task_self (), task_port);
703 mig_reply_error_t reply;
706 (4,
_(
"darwin_decode_exception_message: unknown task 0x%x\n"),
710 kret = mach_port_deallocate (mach_task_self (), thread_port);
715 kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
716 reply.Head.msgh_size, 0,
717 MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
731 kret = mach_port_deallocate (mach_task_self (), thread_port);
750 if (hdr->msgh_size < (sizeof (*hdr) +
sizeof (*bod) + 2 *
sizeof (*desc)
751 +
sizeof (*ndr) + 2 *
sizeof (integer_t)
752 + data[1] *
sizeof (integer_t)))
754 for (i = 0; i < data[1]; i++)
767 NDR_record_t *ndr = (NDR_record_t *)(hdr + 1);
768 integer_t *data = (integer_t *)(ndr + 1);
777 if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
781 if (hdr->msgh_size < (sizeof (*hdr) +
sizeof (*ndr) +
sizeof (integer_t)))
797 if (
inf != NULL && hdr->msgh_local_port !=
priv->notify_port)
807 mach_msg_header_t *rh = &reply->Head;
809 rh->msgh_bits = MACH_MSGH_BITS (MACH_MSGH_BITS_REMOTE (hdr->msgh_bits), 0);
810 rh->msgh_remote_port = hdr->msgh_remote_port;
811 rh->msgh_size = (mach_msg_size_t)
sizeof (mig_reply_error_t);
812 rh->msgh_local_port = MACH_PORT_NULL;
813 rh->msgh_id = hdr->msgh_id + 100;
815 reply->NDR = NDR_record;
816 reply->RetCode =
code;
823 mig_reply_error_t reply;
828 kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
829 reply.Head.msgh_size, 0,
830 MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
834 priv->pending_messages--;
839 int step,
int nsignal)
845 (3,
_(
"darwin_resume_thread: state=%d, thread=0x%x, step=%d nsignal=%d\n"),
856 (caddr_t) (uintptr_t) thread->
gdb_port, nsignal);
884 kret = thread_resume (thread->
gdb_port);
936 kern_return_t kret = thread_suspend (thread->
gdb_port);
957 (2,
_(
"darwin_resume: pid=%d, tid=0x%lx, step=%d, signal=%d\n"),
960 if (signal == GDB_SIGNAL_0)
1012 enum gdb_signal signal)
1027 if (hdr->msgh_id == 2401)
1038 (
_(
"darwin_wait: ill-formatted message (id=0x%x)\n"), hdr->msgh_id);
1053 priv->pending_messages++;
1064 case EXC_BAD_ACCESS:
1065 status->value.sig = GDB_EXC_BAD_ACCESS;
1067 case EXC_BAD_INSTRUCTION:
1068 status->value.sig = GDB_EXC_BAD_INSTRUCTION;
1070 case EXC_ARITHMETIC:
1071 status->value.sig = GDB_EXC_ARITHMETIC;
1074 status->value.sig = GDB_EXC_EMULATION;
1096 status->value.sig = GDB_EXC_SOFTWARE;
1098 case EXC_BREAKPOINT:
1102 status->value.sig = GDB_SIGNAL_TRAP;
1105 status->value.sig = GDB_SIGNAL_UNKNOWN;
1111 else if (hdr->msgh_id == 0x48)
1122 (
_(
"darwin_wait: ill-formatted message (id=0x%x, res=%d)\n"),
1129 if (res < 0 ||
inf == NULL)
1139 if (!
priv->no_ptrace)
1144 res = wait4 (
inf->
pid, &wstatus, 0, NULL);
1145 if (res < 0 || res != inf->
pid)
1167 wait4 (
inf->
pid, &wstatus, 0, NULL);
1176 status->value.integer = 0;
1183 warning (
_(
"darwin: got unknown message, id: 0x%x"), hdr->msgh_id);
1224 mach_msg_header_t hdr;
1227 mach_msg_header_t *hdr = &msgin.hdr;
1233 (2,
_(
"darwin_wait: waiting for a message pid=%d thread=%lx\n"),
1245 status->value.sig = GDB_SIGNAL_TRAP;
1246 thread =
priv->threads[0];
1256 kret = mach_msg (&msgin.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0,
1261 if (kret == MACH_RCV_INTERRUPTED)
1267 if (kret != MACH_MSG_SUCCESS)
1297 kret = mach_msg (&msgin.hdr,
1298 MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0,
1301 if (kret == MACH_RCV_TIMED_OUT)
1303 if (kret != MACH_MSG_SUCCESS)
1306 (5,
_(
"darwin_wait: mach_msg(pending) ret=0x%x\n"), kret);
1316 if (
inf != NULL && thread != NULL
1328 (3,
_(
"darwin_wait: thread 0x%x hit a non-gdb breakpoint\n"),
1368 priv->threads.clear ();
1384 kret = mach_port_move_member (
gdb_task,
1385 priv->notify_port, MACH_PORT_NULL);
1389 kret = mach_port_request_notification (
gdb_task,
priv->task,
1390 MACH_NOTIFY_DEAD_NAME, 0,
1392 MACH_MSG_TYPE_MAKE_SEND_ONCE,
1396 priv->task, prev,
priv->notify_port);
1398 if (kret == KERN_SUCCESS)
1400 kret = mach_port_deallocate (
gdb_task, prev);
1405 kret = mach_port_destroy (
gdb_task,
priv->notify_port);
1451 res = kill (
inf->
pid, SIGSTOP);
1460 && wstatus.
value.
sig == GDB_SIGNAL_STOP)
1465 static kern_return_t
1470 inf->exception_info.count =
1471 sizeof (
inf->exception_info.ports) /
sizeof (
inf->exception_info.ports[0]);
1473 kret = task_get_exception_ports
1474 (
inf->
task, EXC_MASK_ALL,
inf->exception_info.masks,
1475 &
inf->exception_info.count,
inf->exception_info.ports,
1476 inf->exception_info.behaviors,
inf->exception_info.flavors);
1480 static kern_return_t
1486 for (i = 0; i <
inf->exception_info.count; i++)
1488 kret = task_set_exception_ports
1489 (
inf->
task,
inf->exception_info.masks[i],
inf->exception_info.ports[i],
1490 inf->exception_info.behaviors[i],
inf->exception_info.flavors[i]);
1491 if (kret != KERN_SUCCESS)
1495 return KERN_SUCCESS;
1506 for (i = 0; i <
inf->exception_info.count; i++)
1508 kret = mach_port_deallocate (
gdb_task,
inf->exception_info.ports[i]);
1511 inf->exception_info.count = 0;
1520 exception_mask_t mask;
1523 if (kret != KERN_SUCCESS)
1524 error (
_(
"Unable to save exception ports, task_get_exception_ports" 1530 mask = EXC_MASK_ALL;
1532 mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
1534 EXCEPTION_DEFAULT, THREAD_STATE_NONE);
1535 if (kret != KERN_SUCCESS)
1536 error (
_(
"Unable to set exception ports, task_set_exception_ports" 1562 res = kill (
inf->
pid, 9);
1570 else if (errno != ESRCH)
1571 warning (
_(
"Failed to kill inferior: kill (%d, 9) returned [%s]"),
1582 mach_port_t prev_not;
1584 kret = mach_port_request_notification (
gdb_task, priv->
task,
1585 MACH_NOTIFY_DEAD_NAME, 0,
1587 MACH_MSG_TYPE_MAKE_SEND_ONCE,
1589 if (kret != KERN_SUCCESS)
1590 error (
_(
"Termination notification request failed, " 1591 "mach_port_request_notification\n" 1594 if (prev_not != MACH_PORT_NULL)
1600 A task termination request was registered before the debugger registered\n\ 1601 its own. This is unexpected, but should otherwise not have any actual\n\ 1602 impact on the debugging session."));
1610 mach_port_t prev_port;
1612 mach_port_t prev_not;
1613 exception_mask_t mask;
1616 inf->priv.reset (priv);
1619 if (kret != KERN_SUCCESS)
1623 if (!
inf->attach_flag)
1629 error (
_(
"Unable to find Mach task port for process-id %d: %s (0x%lx).\n" 1630 " (please check gdb is codesigned - see taskgated(8))"),
1631 inf->
pid, mach_error_string (kret), (
unsigned long) kret);
1640 kret = mach_port_allocate (
gdb_task, MACH_PORT_RIGHT_RECEIVE,
1642 if (kret != KERN_SUCCESS)
1643 error (
_(
"Unable to create exception port, mach_port_allocate " 1648 MACH_MSG_TYPE_MAKE_SEND);
1649 if (kret != KERN_SUCCESS)
1650 error (
_(
"Unable to create exception port, mach_port_insert_right " 1655 kret = mach_port_allocate (
gdb_task, MACH_PORT_RIGHT_PORT_SET,
1657 if (kret != KERN_SUCCESS)
1658 error (
_(
"Unable to create port set, mach_port_allocate " 1663 if (kret != KERN_SUCCESS)
1664 error (
_(
"Unable to move exception port into new port set, " 1665 "mach_port_move_member\n" 1671 kret = mach_port_allocate (
gdb_task, MACH_PORT_RIGHT_RECEIVE,
1673 if (kret != KERN_SUCCESS)
1674 error (
_(
"Unable to create notification port, mach_port_allocate " 1678 kret = mach_port_move_member (
gdb_task,
1680 if (kret != KERN_SUCCESS)
1681 error (
_(
"Unable to move notification port into new port set, " 1682 "mach_port_move_member\n" 1754 if (setegid (getgid ()) < 0)
1762 if (
PTRACE (PT_SIGEXC, 0, 0, 0) < 0)
1786 mach_port_t prev_port;
1807 posix_spawnattr_t attr;
1811 res = posix_spawnattr_init (&attr);
1815 (
gdb_stderr,
"Cannot initialize attribute for posix_spawn\n");
1820 ps_flags = POSIX_SPAWN_SETEXEC;
1824 #ifndef _POSIX_SPAWN_DISABLE_ASLR 1825 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100 1828 res = posix_spawnattr_setflags (&attr, ps_flags);
1835 posix_spawnp (NULL,
argv[0], NULL, &attr,
argv, env);
1840 const char *exec_file,
1842 char **env,
int from_tty)
1873 thread =
priv->threads[0];
1874 kret = thread_suspend (thread->
gdb_port);
1892 if (
pid == getpid ())
1893 error (
_(
"I refuse to debug myself!"));
1909 if (
pid == 0 || kill (
pid, 0) < 0)
1910 error (
_(
"Can't attach to process %d: %s (%d)"),
1916 inf->attach_flag = 1;
1930 priv->no_ptrace = 1;
1953 if (!
priv->no_ptrace)
1959 if (!
priv->no_ptrace)
1972 if (
priv->no_ptrace)
1986 static char buf[80];
1991 snprintf (buf,
sizeof (buf),
_(
"Thread 0x%lx of process %u"),
2017 mach_vm_size_t res_length = 0;
2019 mach_msg_type_number_t copy_count;
2020 mach_vm_size_t remaining_length;
2021 mach_vm_address_t region_address;
2022 mach_vm_size_t region_length;
2024 inferior_debug (8,
_(
"darwin_read_write_inferior(task=0x%x, %s, len=%s)\n"),
2030 mach_vm_size_t count;
2036 kret = mach_vm_read_overwrite (task, addr, length,
2037 (mach_vm_address_t) rdaddr, &count);
2038 if (kret != KERN_SUCCESS)
2041 (1,
_(
"darwin_read_write_inferior: mach_vm_read failed at %s: %s"),
2054 mach_vm_address_t region_address = (mach_vm_address_t) (addr -
offset);
2055 mach_vm_size_t aligned_length =
2057 vm_region_submap_short_info_data_64_t info;
2058 mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
2059 natural_t region_depth = 1000;
2060 mach_vm_address_t region_start = region_address;
2061 mach_vm_size_t region_length;
2062 mach_vm_size_t write_length;
2065 kret = mach_vm_region_recurse
2066 (task, ®ion_start, ®ion_length, ®ion_depth,
2067 (vm_region_recurse_info_t) &info, &count);
2069 if (kret != KERN_SUCCESS)
2072 "mach_vm_region_recurse failed at %s: %s\n"),
2074 mach_error_string (kret));
2079 (9,
_(
"darwin_read_write_inferior: " 2080 "mach_vm_region_recurse addr=%s, start=%s, len=%s\n"),
2086 if (region_start > region_address)
2088 warning (
_(
"No memory at %s (vs %s+0x%x). Nothing written"),
2091 (
unsigned)region_length);
2096 region_length -= (region_address - region_start);
2097 if (region_length > aligned_length)
2098 region_length = aligned_length;
2101 if (!(info.protection & VM_PROT_WRITE))
2103 vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;
2105 kret = mach_vm_protect (task, region_address, region_length,
2107 if (kret != KERN_SUCCESS)
2109 prot |= VM_PROT_COPY;
2110 kret = mach_vm_protect (task, region_address, region_length,
2113 if (kret != KERN_SUCCESS)
2115 warning (
_(
"darwin_read_write_inferior: " 2116 "mach_vm_protect failed at %s " 2117 "(len=0x%lx, prot=0x%x): %s"),
2119 (
unsigned long) region_length, (
unsigned) prot,
2120 mach_error_string (kret));
2125 if (
offset + length > region_length)
2126 write_length = region_length -
offset;
2128 write_length = length;
2131 kret = mach_vm_write (task, addr, (vm_offset_t) wraddr, write_length);
2132 if (kret != KERN_SUCCESS)
2134 warning (
_(
"darwin_read_write_inferior: mach_vm_write failed: %s"),
2135 mach_error_string (kret));
2140 if (!(info.protection & VM_PROT_WRITE))
2142 kret = mach_vm_protect (task, region_address, region_length,
2143 FALSE, info.protection);
2144 if (kret != KERN_SUCCESS)
2146 warning (
_(
"darwin_read_write_inferior: " 2147 "mach_vm_protect restore failed at %s " 2150 (
unsigned long) region_length,
2151 mach_error_string (kret));
2155 addr += write_length;
2156 wraddr += write_length;
2157 res_length += write_length;
2158 length -= write_length;
2168 #ifdef TASK_DYLD_INFO_COUNT 2174 struct task_dyld_info task_dyld_info;
2175 mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
2176 int sz = TASK_DYLD_INFO_COUNT *
sizeof (natural_t);
2179 if (addr != 0 || length >
sizeof (mach_vm_address_t))
2182 kret = task_info (task, TASK_DYLD_INFO,
2183 (task_info_t) &task_dyld_info, &count);
2185 if (kret != KERN_SUCCESS)
2189 task_dyld_info.all_image_info_addr);
2207 (8,
_(
"darwin_xfer_partial(%s, %s, rbuf=%s, wbuf=%s) pid=%u\n"),
2217 readbuf, writebuf, len);
2228 #ifdef TASK_DYLD_INFO_COUNT 2230 if (writebuf != NULL || readbuf == NULL)
2235 return darwin_read_dyld_info (
priv->task,
offset, readbuf, len,
2252 exception_mask_t mask;
2256 mask = EXC_MASK_ALL;
2260 mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
2263 EXCEPTION_DEFAULT, THREAD_STATE_NONE);
2271 static char path[PATH_MAX];
2274 res = proc_pidinfo (
pid, PROC_PIDPATHINFO, 0, path, PATH_MAX);
2287 mach_port_name_array_t names;
2288 mach_msg_type_number_t names_count;
2289 mach_port_type_array_t types;
2290 mach_msg_type_number_t types_count;
2303 kret = mach_port_names (
priv->task, &names, &names_count, &types,
2306 if (kret != KERN_SUCCESS)
2312 for (
int i = 0; i < names_count; i++)
2314 mach_port_t local_name;
2315 mach_msg_type_name_t local_type;
2319 kret = mach_port_extract_right (
priv->task, names[i],
2320 MACH_MSG_TYPE_COPY_SEND,
2321 &local_name, &local_type);
2322 if (kret != KERN_SUCCESS)
2324 mach_port_deallocate (
gdb_task, local_name);
2331 if (names[i] ==
lwp)
2337 vm_deallocate (
gdb_task, (vm_address_t) names,
2338 names_count *
sizeof (mach_port_t));
2362 if (kret != KERN_SUCCESS)
2393 (
unsigned long) mach_task_self (), getpid ());
2397 Set if printing inferior communication debugging statements."),
_(
"\ 2398 Show if printing inferior communication debugging statements."), NULL,
2404 Set if mach exceptions are caught."),
_(
"\ 2405 Show if mach exceptions are caught."),
_(
"\ 2406 When this mode is on, all low level exceptions are reported before being\n\ 2407 reported by the kernel."),
static void darwin_setup_request_notification(struct inferior *inf)
static ptid_t darwin_decode_message(mach_msg_header_t *hdr, darwin_thread_t **pthread, struct inferior **pinf, struct target_waitstatus *status)
void add_target(struct target_ops *t)
static struct target_ops * darwin_ops
ssize_t read(int fd, void *buf, size_t count)
static void darwin_dump_message(mach_msg_header_t *hdr, int disp_body)
int breakpoint_inserted_here_p(const address_space *aspace, CORE_ADDR pc)
static void darwin_create_inferior(struct target_ops *ops, const char *exec_file, const std::string &allargs, char **env, int from_tty)
static constexpr ptid_t tid
static void darwin_resume_to(struct target_ops *ops, ptid_t ptid, int step, enum gdb_signal signal)
static struct inferior * darwin_inf_fake_stop
#define PTRACE(CMD, PID, ADDR, SIG)
static void darwin_resume_inferior_threads(struct inferior *inf, int step, int nsignal)
void target_announce_detach(int from_tty)
struct darwin_exception_msg event
static enum target_xfer_status darwin_xfer_partial(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
static int darwin_suspend_inferior_it(struct inferior *inf, void *arg)
int ptid_get_pid(const ptid_t &ptid)
struct regcache * get_thread_regcache(ptid_t ptid)
void delete_thread(ptid_t)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int int rusage_t pid_t pid
static darwin_thread_t * darwin_find_thread(struct inferior *inf, thread_t thread)
static int darwin_read_write_inferior(task_t task, CORE_ADDR addr, gdb_byte *rdaddr, const gdb_byte *wraddr, ULONGEST length)
void warning(const char *fmt,...)
void darwin_set_sstep(thread_t thread, int enable)
void push_target(struct target_ops *t)
enum darwin_msg_state msg_state
char * get_exec_file(int err)
static void darwin_reply_to_all_pending_messages(struct inferior *inf)
struct thread_info * add_thread_with_info(ptid_t ptid, struct private_thread_info *)
const char *(* to_pid_to_str)(struct target_ops *, ptid_t) TARGET_DEFAULT_FUNC(default_pid_to_str)
union target_waitstatus::@174 value
static void darwin_interrupt(struct target_ops *self, ptid_t)
static int darwin_supports_multi_process(struct target_ops *self)
static struct inferior * darwin_find_inferior_by_task(task_t port)
static void darwin_resume_inferior(struct inferior *inf)
static void darwin_execvp(const char *file, char *const argv[], char *const env[])
static int find_inferior_task_it(struct inferior *inf, void *port_ptr)
struct inferior * find_inferior_ptid(ptid_t ptid)
static kern_return_t darwin_save_exception_ports(darwin_inferior *inf)
struct inferior * iterate_over_inferiors(int(*callback)(struct inferior *, void *), void *data)
static void darwin_pre_ptrace(void)
static void darwin_resume(ptid_t ptid, int step, enum gdb_signal signal)
void regcache_write_pc(struct regcache *regcache, CORE_ADDR pc)
static void darwin_stop_inferior(struct inferior *inf)
static ptid_t darwin_get_ada_task_ptid(struct target_ops *self, long lwp, long thread)
static ptid_t darwin_wait(ptid_t ptid, struct target_waitstatus *status)
mach_port_t darwin_ex_port
#define MACH_CHECK_ERROR(ret)
#define host_address_to_string(ADDR)
ptid_t ptid_build(int pid, long lwp, long tid)
void(* to_files_info)(struct target_ops *) TARGET_DEFAULT_IGNORE()
static int darwin_check_message_ndr(NDR_record_t *ndr)
static void darwin_setup_fake_stop_event(struct inferior *inf)
void 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_const_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
const char * normal_pid_to_str(ptid_t ptid)
struct cmd_list_element * setlist
static void darwin_encode_reply(mig_reply_error_t *reply, mach_msg_header_t *hdr, integer_t code)
CORE_ADDR gdbarch_decr_pc_after_break(struct gdbarch *gdbarch)
static struct thread_info * thread_info_from_private_thread_info(darwin_thread_info *pti)
void unmark_fd_no_cloexec(int fd)
static int find_inferior_pid_it(struct inferior *inf, void *pid_ptr)
static struct inferior * darwin_find_inferior_by_pid(int pid)
void _initialize_darwin_inferior(void)
static void darwin_deallocate_exception_ports(darwin_inferior *inf)
mach_port_t darwin_host_self
static void darwin_init_thread_list(struct inferior *inf)
long ptid_get_tid(const ptid_t &ptid)
static int darwin_thread_alive(struct target_ops *ops, ptid_t tpid)
static int enable_mach_exceptions
void fprintf_unfiltered(struct ui_file *stream, const char *format,...)
void(* to_resume)(struct target_ops *, ptid_t, int TARGET_DEBUG_PRINTER(target_debug_print_step), enum gdb_signal) TARGET_DEFAULT_NORETURN(noprocess())
mach_msg_type_number_t data_count
struct cmd_list_element * showlist
#define gdb_assert_not_reached(message)
static void darwin_detach(struct target_ops *ops, const char *args, int from_tty)
ptid_t pid_to_ptid(int pid)
std::vector< darwin_thread_t * > threads
char * pulongest(ULONGEST u)
static char * darwin_pid_to_exec_file(struct target_ops *self, int pid)
int gdb_signal_to_host(enum gdb_signal)
static darwin_inferior * get_darwin_inferior(inferior *inf)
enum gdb_signal gdb_signal_from_host(int)
unsigned char single_step
static void darwin_deallocate_threads(struct inferior *inf)
static kern_return_t darwin_restore_exception_ports(darwin_inferior *inf)
void trace_start_error(const char *fmt,...)
void target_mourn_inferior(ptid_t ptid)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int status
static int darwin_resume_inferior_it(struct inferior *inf, void *arg)
static int darwin_decode_exception_message(mach_msg_header_t *hdr, struct inferior **pinf, darwin_thread_t **pthread)
const char * gdb_signal_to_name(enum gdb_signal)
enum target_xfer_status(* to_xfer_partial)(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) TARGET_DEFAULT_RETURN(TARGET_XFER_E_IO)
void printf_unfiltered(const char *format,...)
struct cmd_list_element * setdebuglist
static const unsigned char info_plist [] __attribute__((section("__TEXT,__info_plist"), used))
void(* to_detach)(struct target_ops *ops, const char *, int) TARGET_DEFAULT_IGNORE()
void inf_child_mourn_inferior(struct target_ops *ops)
ptid_t gdb_startup_inferior(pid_t pid, int num_traps)
static darwin_thread_info * get_darwin_thread_info(class thread_info *thread)
static int cancel_breakpoint(ptid_t ptid)
const address_space * aspace() const
char *(* to_pid_to_exec_file)(struct target_ops *, int pid) TARGET_DEFAULT_RETURN(NULL)
int target_is_pushed(struct target_ops *t)
static void darwin_ptrace_me(void)
static void inferior_debug(int level, const char *fmt,...) ATTRIBUTE_PRINTF(2
static void darwin_setup_exceptions(struct inferior *inf)
static int darwin_ptrace(const char *name, int request, int pid, caddr_t arg3, int arg4)
void vprintf_unfiltered(const char *format, va_list args)
static void darwin_suspend_inferior_threads(struct inferior *inf)
static void darwin_files_info(struct target_ops *ops)
void mach_check_error(kern_return_t ret, const char *file, unsigned int line, const char *func)
struct target_ops * inf_child_target(void)
static void darwin_attach_pid(struct inferior *inf)
void(* to_mourn_inferior)(struct target_ops *) TARGET_DEFAULT_FUNC(default_mourn_inferior)
void trace_start_error_with_name(const char *string)
mach_port_t darwin_port_set
static const char * unparse_exception_type(unsigned int i)
std::unique_ptr< private_thread_info > priv
std::unique_ptr< private_inferior > priv
static void darwin_mourn_inferior(struct target_ops *ops)
pid_t fork_inferior(const char *exec_file_arg, const std::string &allargs, char **env, void(*traceme_fun)(), void(*init_trace_fun)(int), void(*pre_trace_fun)(), const char *shell_file_arg, void(*exec_fun)(const char *file, char *const *argv, char *const *env))
static int darwin_resume_inferior_threads_it(struct inferior *inf, void *param)
static int darwin_decode_notify_message(mach_msg_header_t *hdr, struct inferior **pinf)
enum target_waitkind kind
void(* to_kill)(struct target_ops *) TARGET_DEFAULT_NORETURN(noprocess())
CORE_ADDR regcache_read_pc(struct regcache *regcache)
char * safe_strerror(int)
const char * target_pid_to_str(ptid_t ptid)
static vm_size_t mach_page_size
void add_setshow_boolean_cmd(const char *name, enum command_class theclass, int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_const_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
static constexpr ptid_t lwp
int parse_pid_to_attach(const char *args)
static void darwin_check_new_threads(struct inferior *inf)
static void set_enable_mach_exceptions(const char *args, int from_tty, struct cmd_list_element *c)
struct thread_info * thread_list
int ptid_equal(const ptid_t &ptid1, const ptid_t &ptid2)
#define START_INFERIOR_TRAPS_EXPECTED
struct inferior * current_inferior(void)
static void darwin_ptrace_him(int pid)
unsigned long long ULONGEST
static void darwin_send_reply(struct inferior *inf, darwin_thread_t *thread)
void darwin_check_osabi(darwin_inferior *inf, thread_t thread)
const char * core_addr_to_string(const CORE_ADDR addr)
void(* to_interrupt)(struct target_ops *, ptid_t) TARGET_DEFAULT_IGNORE()
struct cmd_list_element * showdebuglist
static const char * darwin_pid_to_str(struct target_ops *ops, ptid_t tpid)
static void darwin_resume_thread(struct inferior *inf, darwin_thread_t *thread, int step, int nsignal)
static ptid_t darwin_wait_to(struct target_ops *ops, ptid_t ptid, struct target_waitstatus *status, int options)
void(* to_create_inferior)(struct target_ops *, const char *, const std::string &, char **, int)
#define _POSIX_SPAWN_DISABLE_ASLR
int(* to_thread_alive)(struct target_ops *, ptid_t ptid) TARGET_DEFAULT_RETURN(0)
static void darwin_kill_inferior(struct target_ops *ops)
void(* to_attach)(struct target_ops *ops, const char *, int)
void mark_fd_no_cloexec(int fd)
static unsigned int darwin_debug_flag
void gdb_flush(struct ui_file *file)
static void darwin_suspend_inferior(struct inferior *inf)
ptid_t(* to_wait)(struct target_ops *, ptid_t, struct target_waitstatus *, int TARGET_DEBUG_PRINTER(target_debug_print_options)) TARGET_DEFAULT_FUNC(default_target_wait)
ptid_t(* to_get_ada_task_ptid)(struct target_ops *, long lwp, long thread) TARGET_DEFAULT_FUNC(default_get_ada_task_ptid)
void error(const char *fmt,...)
void darwin_complete_target(struct target_ops *target)
static struct inferior * darwin_find_new_inferior(task_t task_port, thread_t thread_port)
static int cmp_thread_t(const void *l, const void *r)
void inferior_appeared(struct inferior *inf, int pid)
void(* to_load)(struct target_ops *, const char *, int) TARGET_DEFAULT_NORETURN(tcomplain())
int(* to_supports_multi_process)(struct target_ops *) TARGET_DEFAULT_RETURN(0)
static void store_unsigned_integer(gdb_byte *addr, int len, enum bfd_endian byte_order, ULONGEST val)
static void darwin_attach(struct target_ops *ops, const char *args, int from_tty)