1 /* Darwin support for GDB, the GNU debugger.
2 Copyright (C) 2008-2016 Free Software Foundation, Inc.
4 Contributed by AdaCore.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
31 #include "gdbthread.h"
33 #include "event-top.h"
36 #include "inf-child.h"
38 #include "arch-utils.h"
40 #include "bfd/mach-o.h"
42 #include <sys/ptrace.h>
43 #include <sys/signal.h>
45 #include <sys/types.h>
49 #include <sys/sysctl.h>
52 #include <sys/syscall.h>
55 #include <mach/mach_error.h>
56 #include <mach/mach_vm.h>
57 #include <mach/mach_init.h>
58 #include <mach/vm_map.h>
59 #include <mach/task.h>
60 #include <mach/mach_port.h>
61 #include <mach/thread_act.h>
62 #include <mach/port.h>
64 #include "darwin-nat.h"
65 #include "common/filestuff.h"
68 Darwin kernel is Mach + BSD derived kernel. Note that they share the
69 same memory space and are linked together (ie there is no micro-kernel).
71 Although ptrace(2) is available on Darwin, it is not complete. We have
72 to use Mach calls to read and write memory and to modify registers. We
73 also use Mach to get inferior faults. As we cannot use select(2) or
74 signals with Mach port (the Mach communication channel), signals are
75 reported to gdb as an exception. Furthermore we detect death of the
76 inferior through a Mach notification message. This way we only wait
79 Some Mach documentation is available for Apple xnu source package or
83 #define PTRACE(CMD, PID, ADDR, SIG) \
84 darwin_ptrace(#CMD, CMD, (PID), (ADDR), (SIG))
86 static void darwin_interrupt (struct target_ops
*self
, ptid_t
);
88 static void darwin_resume_to (struct target_ops
*ops
, ptid_t ptid
, int step
,
89 enum gdb_signal signal
);
90 static void darwin_resume (ptid_t ptid
, int step
,
91 enum gdb_signal signal
);
93 static ptid_t
darwin_wait_to (struct target_ops
*ops
, ptid_t ptid
,
94 struct target_waitstatus
*status
, int options
);
95 static ptid_t
darwin_wait (ptid_t ptid
, struct target_waitstatus
*status
);
97 static void darwin_mourn_inferior (struct target_ops
*ops
);
99 static void darwin_kill_inferior (struct target_ops
*ops
);
101 static void darwin_ptrace_me (void);
103 static void darwin_ptrace_him (int pid
);
105 static void darwin_create_inferior (struct target_ops
*ops
, char *exec_file
,
106 char *allargs
, char **env
, int from_tty
);
108 static void darwin_files_info (struct target_ops
*ops
);
110 static char *darwin_pid_to_str (struct target_ops
*ops
, ptid_t tpid
);
112 static int darwin_thread_alive (struct target_ops
*ops
, ptid_t tpid
);
114 static void darwin_encode_reply (mig_reply_error_t
*reply
,
115 mach_msg_header_t
*hdr
, integer_t code
);
117 static void darwin_setup_request_notification (struct inferior
*inf
);
118 static void darwin_deallocate_exception_ports (darwin_inferior
*inf
);
119 static void darwin_setup_exceptions (struct inferior
*inf
);
120 static void darwin_deallocate_threads (struct inferior
*inf
);
122 /* Target operations for Darwin. */
123 static struct target_ops
*darwin_ops
;
125 /* Task identifier of gdb. */
126 static task_t gdb_task
;
128 /* A copy of mach_host_self (). */
129 mach_port_t darwin_host_self
;
131 /* Exception port. */
132 mach_port_t darwin_ex_port
;
134 /* Port set, to wait for answer on all ports. */
135 mach_port_t darwin_port_set
;
138 static vm_size_t mach_page_size
;
140 /* If Set, catch all mach exceptions (before they are converted to signals
142 static int enable_mach_exceptions
;
144 /* Inferior that should report a fake stop event. */
145 static struct inferior
*darwin_inf_fake_stop
;
147 #define PAGE_TRUNC(x) ((x) & ~(mach_page_size - 1))
148 #define PAGE_ROUND(x) PAGE_TRUNC((x) + mach_page_size - 1)
150 /* This controls output of inferior debugging. */
151 static unsigned int darwin_debug_flag
= 0;
153 /* Create a __TEXT __info_plist section in the executable so that gdb could
154 be signed. This is required to get an authorization for task_for_pid.
156 Once gdb is built, you must codesign it with any system-trusted signing
157 authority. See taskgated(8) for details. */
158 static const unsigned char info_plist
[]
159 __attribute__ ((section ("__TEXT,__info_plist"),used
)) =
160 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
161 "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
162 " \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
163 "<plist version=\"1.0\">\n"
165 " <key>CFBundleIdentifier</key>\n"
166 " <string>org.gnu.gdb</string>\n"
167 " <key>CFBundleName</key>\n"
168 " <string>gdb</string>\n"
169 " <key>CFBundleVersion</key>\n"
170 " <string>1.0</string>\n"
171 " <key>SecTaskAccess</key>\n"
173 " <string>allowed</string>\n"
174 " <string>debug</string>\n"
179 static void inferior_debug (int level
, const char *fmt
, ...)
180 ATTRIBUTE_PRINTF (2, 3);
183 inferior_debug (int level
, const char *fmt
, ...)
187 if (darwin_debug_flag
< level
)
191 printf_unfiltered (_("[%d inferior]: "), getpid ());
192 vprintf_unfiltered (fmt
, ap
);
197 mach_check_error (kern_return_t ret
, const char *file
,
198 unsigned int line
, const char *func
)
200 if (ret
== KERN_SUCCESS
)
203 func
= _("[UNKNOWN]");
205 warning (_("Mach error at \"%s:%u\" in function \"%s\": %s (0x%lx)"),
206 file
, line
, func
, mach_error_string (ret
), (unsigned long) ret
);
210 unparse_exception_type (unsigned int i
)
212 static char unknown_exception_buf
[32];
217 return "EXC_BAD_ACCESS";
218 case EXC_BAD_INSTRUCTION
:
219 return "EXC_BAD_INSTRUCTION";
221 return "EXC_ARITHMETIC";
223 return "EXC_EMULATION";
225 return "EXC_SOFTWARE";
227 return "EXC_BREAKPOINT";
229 return "EXC_SYSCALL";
230 case EXC_MACH_SYSCALL
:
231 return "EXC_MACH_SYSCALL";
233 return "EXC_RPC_ALERT";
237 snprintf (unknown_exception_buf
, 32, _("unknown (%d)"), i
);
238 return unknown_exception_buf
;
242 /* Set errno to zero, and then call ptrace with the given arguments.
243 If inferior debugging traces are on, then also print a debug
246 The returned value is the same as the value returned by ptrace,
247 except in the case where that value is -1 but errno is zero.
248 This case is documented to be a non-error situation, so we
249 return zero in that case. */
252 darwin_ptrace (const char *name
,
253 int request
, int pid
, caddr_t arg3
, int arg4
)
258 ret
= ptrace (request
, pid
, arg3
, arg4
);
259 if (ret
== -1 && errno
== 0)
262 inferior_debug (4, _("ptrace (%s, %d, 0x%lx, %d): %d (%s)\n"),
263 name
, pid
, (unsigned long) arg3
, arg4
, ret
,
264 (ret
!= 0) ? safe_strerror (errno
) : _("no error"));
269 cmp_thread_t (const void *l
, const void *r
)
271 thread_t tl
= *(const thread_t
*)l
;
272 thread_t tr
= *(const thread_t
*)r
;
273 return (int)(tl
- tr
);
277 darwin_check_new_threads (struct inferior
*inf
)
281 thread_array_t thread_list
;
282 unsigned int new_nbr
;
283 unsigned int old_nbr
;
284 unsigned int new_ix
, old_ix
;
285 darwin_inferior
*darwin_inf
= inf
->priv
;
286 VEC (darwin_thread_t
) *thread_vec
;
288 /* Get list of threads. */
289 kret
= task_threads (darwin_inf
->task
, &thread_list
, &new_nbr
);
290 MACH_CHECK_ERROR (kret
);
291 if (kret
!= KERN_SUCCESS
)
296 qsort (thread_list
, new_nbr
, sizeof (thread_t
), cmp_thread_t
);
298 if (darwin_inf
->threads
)
299 old_nbr
= VEC_length (darwin_thread_t
, darwin_inf
->threads
);
303 /* Quick check for no changes. */
304 if (old_nbr
== new_nbr
)
306 for (i
= 0; i
< new_nbr
; i
++)
308 != VEC_index (darwin_thread_t
, darwin_inf
->threads
, i
)->gdb_port
)
312 /* Deallocate ports. */
313 for (i
= 0; i
< new_nbr
; i
++)
315 kret
= mach_port_deallocate (mach_task_self (), thread_list
[i
]);
316 MACH_CHECK_ERROR (kret
);
319 /* Deallocate the buffer. */
320 kret
= vm_deallocate (gdb_task
, (vm_address_t
) thread_list
,
321 new_nbr
* sizeof (int));
322 MACH_CHECK_ERROR (kret
);
328 /* Full handling: detect new threads, remove dead threads. */
329 thread_vec
= VEC_alloc (darwin_thread_t
, new_nbr
);
331 for (new_ix
= 0, old_ix
= 0; new_ix
< new_nbr
|| old_ix
< old_nbr
;)
333 thread_t new_id
= (new_ix
< new_nbr
) ?
334 thread_list
[new_ix
] : THREAD_NULL
;
335 darwin_thread_t
*old
= (old_ix
< old_nbr
) ?
336 VEC_index (darwin_thread_t
, darwin_inf
->threads
, old_ix
) : NULL
;
337 thread_t old_id
= old
? old
->gdb_port
: THREAD_NULL
;
340 (12, _(" new_ix:%d/%d, old_ix:%d/%d, new_id:0x%x old_id:0x%x\n"),
341 new_ix
, new_nbr
, old_ix
, old_nbr
, new_id
, old_id
);
343 if (old_id
== new_id
)
345 /* Thread still exist. */
346 VEC_safe_push (darwin_thread_t
, thread_vec
, old
);
350 /* Deallocate the port. */
351 kret
= mach_port_deallocate (gdb_task
, new_id
);
352 MACH_CHECK_ERROR (kret
);
356 if (new_ix
< new_nbr
&& new_id
== MACH_PORT_DEAD
)
358 /* Ignore dead ports.
359 In some weird cases, we might get dead ports. They should
360 correspond to dead thread so they could safely be ignored. */
364 if (new_ix
< new_nbr
&& (old_ix
== old_nbr
|| new_id
< old_id
))
366 /* A thread was created. */
367 struct thread_info
*tp
;
368 struct private_thread_info
*pti
;
370 pti
= XCNEW (struct private_thread_info
);
371 pti
->gdb_port
= new_id
;
372 pti
->msg_state
= DARWIN_RUNNING
;
374 if (old_nbr
== 0 && new_ix
== 0)
376 /* A ptid is create when the inferior is started (see
377 fork-child.c) with lwp=tid=0. This ptid will be renamed
378 later by darwin_init_thread_list (). */
379 tp
= find_thread_ptid (ptid_build (inf
->pid
, 0, 0));
381 gdb_assert (tp
->priv
== NULL
);
386 /* Add the new thread. */
387 tp
= add_thread_with_info
388 (ptid_build (inf
->pid
, 0, new_id
), pti
);
390 VEC_safe_push (darwin_thread_t
, thread_vec
, pti
);
394 if (old_ix
< old_nbr
&& (new_ix
== new_nbr
|| new_id
> old_id
))
396 /* A thread was removed. */
397 delete_thread (ptid_build (inf
->pid
, 0, old_id
));
398 kret
= mach_port_deallocate (gdb_task
, old_id
);
399 MACH_CHECK_ERROR (kret
);
403 gdb_assert_not_reached ("unexpected thread case");
406 if (darwin_inf
->threads
)
407 VEC_free (darwin_thread_t
, darwin_inf
->threads
);
408 darwin_inf
->threads
= thread_vec
;
410 /* Deallocate the buffer. */
411 kret
= vm_deallocate (gdb_task
, (vm_address_t
) thread_list
,
412 new_nbr
* sizeof (int));
413 MACH_CHECK_ERROR (kret
);
417 find_inferior_task_it (struct inferior
*inf
, void *port_ptr
)
419 return inf
->priv
->task
== *(task_t
*)port_ptr
;
423 find_inferior_pid_it (struct inferior
*inf
, void *pid_ptr
)
425 return inf
->pid
== *(int *)pid_ptr
;
428 /* Return an inferior by task port. */
429 static struct inferior
*
430 darwin_find_inferior_by_task (task_t port
)
432 return iterate_over_inferiors (&find_inferior_task_it
, &port
);
435 /* Return an inferior by pid port. */
436 static struct inferior
*
437 darwin_find_inferior_by_pid (int pid
)
439 return iterate_over_inferiors (&find_inferior_pid_it
, &pid
);
442 /* Return a thread by port. */
443 static darwin_thread_t
*
444 darwin_find_thread (struct inferior
*inf
, thread_t thread
)
450 VEC_iterate (darwin_thread_t
, inf
->priv
->threads
, k
, t
);
452 if (t
->gdb_port
== thread
)
457 /* Suspend (ie stop) an inferior at Mach level. */
460 darwin_suspend_inferior (struct inferior
*inf
)
462 if (!inf
->priv
->suspended
)
466 kret
= task_suspend (inf
->priv
->task
);
467 MACH_CHECK_ERROR (kret
);
469 inf
->priv
->suspended
= 1;
473 /* Resume an inferior at Mach level. */
476 darwin_resume_inferior (struct inferior
*inf
)
478 if (inf
->priv
->suspended
)
482 kret
= task_resume (inf
->priv
->task
);
483 MACH_CHECK_ERROR (kret
);
485 inf
->priv
->suspended
= 0;
489 /* Iterator functions. */
492 darwin_suspend_inferior_it (struct inferior
*inf
, void *arg
)
494 darwin_suspend_inferior (inf
);
495 darwin_check_new_threads (inf
);
500 darwin_resume_inferior_it (struct inferior
*inf
, void *arg
)
502 darwin_resume_inferior (inf
);
507 darwin_dump_message (mach_msg_header_t
*hdr
, int disp_body
)
509 printf_unfiltered (_("message header:\n"));
510 printf_unfiltered (_(" bits: 0x%x\n"), hdr
->msgh_bits
);
511 printf_unfiltered (_(" size: 0x%x\n"), hdr
->msgh_size
);
512 printf_unfiltered (_(" remote-port: 0x%x\n"), hdr
->msgh_remote_port
);
513 printf_unfiltered (_(" local-port: 0x%x\n"), hdr
->msgh_local_port
);
514 printf_unfiltered (_(" reserved: 0x%x\n"), hdr
->msgh_reserved
);
515 printf_unfiltered (_(" id: 0x%x\n"), hdr
->msgh_id
);
519 const unsigned char *data
;
520 const unsigned int *ldata
;
524 data
= (unsigned char *)(hdr
+ 1);
525 size
= hdr
->msgh_size
- sizeof (mach_msg_header_t
);
527 if (hdr
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
)
529 mach_msg_body_t
*bod
= (mach_msg_body_t
*)data
;
530 mach_msg_port_descriptor_t
*desc
=
531 (mach_msg_port_descriptor_t
*)(bod
+ 1);
534 printf_unfiltered (_("body: descriptor_count=%u\n"),
535 bod
->msgh_descriptor_count
);
536 data
+= sizeof (mach_msg_body_t
);
537 size
-= sizeof (mach_msg_body_t
);
538 for (k
= 0; k
< bod
->msgh_descriptor_count
; k
++)
539 switch (desc
[k
].type
)
541 case MACH_MSG_PORT_DESCRIPTOR
:
543 (_(" descr %d: type=%u (port) name=0x%x, dispo=%d\n"),
544 k
, desc
[k
].type
, desc
[k
].name
, desc
[k
].disposition
);
547 printf_unfiltered (_(" descr %d: type=%u\n"),
551 data
+= bod
->msgh_descriptor_count
552 * sizeof (mach_msg_port_descriptor_t
);
553 size
-= bod
->msgh_descriptor_count
554 * sizeof (mach_msg_port_descriptor_t
);
555 ndr
= (NDR_record_t
*)(desc
+ bod
->msgh_descriptor_count
);
557 (_("NDR: mig=%02x if=%02x encod=%02x "
558 "int=%02x char=%02x float=%02x\n"),
559 ndr
->mig_vers
, ndr
->if_vers
, ndr
->mig_encoding
,
560 ndr
->int_rep
, ndr
->char_rep
, ndr
->float_rep
);
561 data
+= sizeof (NDR_record_t
);
562 size
-= sizeof (NDR_record_t
);
565 printf_unfiltered (_(" data:"));
566 ldata
= (const unsigned int *)data
;
567 for (i
= 0; i
< size
/ sizeof (unsigned int); i
++)
568 printf_unfiltered (" %08x", ldata
[i
]);
569 printf_unfiltered (_("\n"));
573 /* Adjust inferior data when a new task was created. */
575 static struct inferior
*
576 darwin_find_new_inferior (task_t task_port
, thread_t thread_port
)
579 struct inferior
*inf
;
583 /* Find the corresponding pid. */
584 kret
= pid_for_task (task_port
, &task_pid
);
585 if (kret
!= KERN_SUCCESS
)
587 MACH_CHECK_ERROR (kret
);
591 /* Find the inferior for this pid. */
592 inf
= darwin_find_inferior_by_pid (task_pid
);
596 /* Deallocate saved exception ports. */
597 darwin_deallocate_exception_ports (inf
->priv
);
599 /* No need to remove dead_name notification, but still... */
600 kret
= mach_port_request_notification (gdb_task
, inf
->priv
->task
,
601 MACH_NOTIFY_DEAD_NAME
, 0,
603 MACH_MSG_TYPE_MAKE_SEND_ONCE
,
605 if (kret
!= KERN_INVALID_ARGUMENT
)
606 MACH_CHECK_ERROR (kret
);
608 /* Replace old task port. */
609 kret
= mach_port_deallocate (gdb_task
, inf
->priv
->task
);
610 MACH_CHECK_ERROR (kret
);
611 inf
->priv
->task
= task_port
;
613 darwin_setup_request_notification (inf
);
614 darwin_setup_exceptions (inf
);
619 /* Check data representation. */
622 darwin_check_message_ndr (NDR_record_t
*ndr
)
624 if (ndr
->mig_vers
!= NDR_PROTOCOL_2_0
625 || ndr
->if_vers
!= NDR_PROTOCOL_2_0
626 || ndr
->mig_encoding
!= NDR_record
.mig_encoding
627 || ndr
->int_rep
!= NDR_record
.int_rep
628 || ndr
->char_rep
!= NDR_record
.char_rep
629 || ndr
->float_rep
!= NDR_record
.float_rep
)
634 /* Decode an exception message. */
637 darwin_decode_exception_message (mach_msg_header_t
*hdr
,
638 struct inferior
**pinf
,
639 darwin_thread_t
**pthread
)
641 mach_msg_body_t
*bod
= (mach_msg_body_t
*)(hdr
+ 1);
642 mach_msg_port_descriptor_t
*desc
= (mach_msg_port_descriptor_t
*)(bod
+ 1);
645 struct inferior
*inf
;
646 darwin_thread_t
*thread
;
648 thread_t thread_port
;
652 /* Check message destination. */
653 if (hdr
->msgh_local_port
!= darwin_ex_port
)
656 /* Check message header. */
657 if (!(hdr
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
))
660 /* Check descriptors. */
661 if (hdr
->msgh_size
< (sizeof (*hdr
) + sizeof (*bod
) + 2 * sizeof (*desc
)
662 + sizeof (*ndr
) + 2 * sizeof (integer_t
))
663 || bod
->msgh_descriptor_count
!= 2
664 || desc
[0].type
!= MACH_MSG_PORT_DESCRIPTOR
665 || desc
[0].disposition
!= MACH_MSG_TYPE_MOVE_SEND
666 || desc
[1].type
!= MACH_MSG_PORT_DESCRIPTOR
667 || desc
[1].disposition
!= MACH_MSG_TYPE_MOVE_SEND
)
670 /* Check data representation. */
671 ndr
= (NDR_record_t
*)(desc
+ 2);
672 if (darwin_check_message_ndr (ndr
) != 0)
675 /* Ok, the hard work. */
676 data
= (integer_t
*)(ndr
+ 1);
678 task_port
= desc
[1].name
;
679 thread_port
= desc
[0].name
;
681 /* Find process by port. */
682 inf
= darwin_find_inferior_by_task (task_port
);
685 if (inf
== NULL
&& data
[0] == EXC_SOFTWARE
&& data
[1] == 2
686 && data
[2] == EXC_SOFT_SIGNAL
&& data
[3] == SIGTRAP
)
688 /* Not a known inferior, but a sigtrap. This happens on darwin 16.1.0,
689 as a new Mach task is created when a process exec. */
690 inf
= darwin_find_new_inferior (task_port
, thread_port
);
695 /* Deallocate task_port, unless it was saved. */
696 kret
= mach_port_deallocate (mach_task_self (), task_port
);
697 MACH_CHECK_ERROR (kret
);
702 /* We got new rights to the task, get rid of it. Do not get rid of
703 thread right, as we will need it to find the thread. */
704 kret
= mach_port_deallocate (mach_task_self (), task_port
);
705 MACH_CHECK_ERROR (kret
);
710 /* Not a known inferior. This could happen if the child fork, as
711 the created process will inherit its exception port.
712 FIXME: should the exception port be restored ? */
714 mig_reply_error_t reply
;
717 (4, _("darwin_decode_exception_message: unknown task 0x%x\n"),
720 /* Free thread port (we don't know it). */
721 kret
= mach_port_deallocate (mach_task_self (), thread_port
);
722 MACH_CHECK_ERROR (kret
);
724 darwin_encode_reply (&reply
, hdr
, KERN_SUCCESS
);
726 kret
= mach_msg (&reply
.Head
, MACH_SEND_MSG
| MACH_SEND_INTERRUPT
,
727 reply
.Head
.msgh_size
, 0,
728 MACH_PORT_NULL
, MACH_MSG_TIMEOUT_NONE
,
730 MACH_CHECK_ERROR (kret
);
735 /* Find thread by port. */
736 /* Check for new threads. Do it early so that the port in the exception
737 message can be deallocated. */
738 darwin_check_new_threads (inf
);
740 /* Free the thread port (as gdb knows the thread, it has already has a right
741 for it, so this just decrement a reference counter). */
742 kret
= mach_port_deallocate (mach_task_self (), thread_port
);
743 MACH_CHECK_ERROR (kret
);
745 thread
= darwin_find_thread (inf
, thread_port
);
750 /* The thread should be running. However we have observed cases where a
751 thread got a SIGTTIN message after being stopped. */
752 gdb_assert (thread
->msg_state
!= DARWIN_MESSAGE
);
754 /* Finish decoding. */
755 thread
->event
.header
= *hdr
;
756 thread
->event
.thread_port
= thread_port
;
757 thread
->event
.task_port
= task_port
;
758 thread
->event
.ex_type
= data
[0];
759 thread
->event
.data_count
= data
[1];
761 if (hdr
->msgh_size
< (sizeof (*hdr
) + sizeof (*bod
) + 2 * sizeof (*desc
)
762 + sizeof (*ndr
) + 2 * sizeof (integer_t
)
763 + data
[1] * sizeof (integer_t
)))
765 for (i
= 0; i
< data
[1]; i
++)
766 thread
->event
.ex_data
[i
] = data
[2 + i
];
768 thread
->msg_state
= DARWIN_MESSAGE
;
773 /* Decode dead_name notify message. */
776 darwin_decode_notify_message (mach_msg_header_t
*hdr
, struct inferior
**pinf
)
778 NDR_record_t
*ndr
= (NDR_record_t
*)(hdr
+ 1);
779 integer_t
*data
= (integer_t
*)(ndr
+ 1);
780 struct inferior
*inf
;
781 darwin_thread_t
*thread
;
783 thread_t thread_port
;
787 /* Check message header. */
788 if (hdr
->msgh_bits
& MACH_MSGH_BITS_COMPLEX
)
791 /* Check descriptors. */
792 if (hdr
->msgh_size
< (sizeof (*hdr
) + sizeof (*ndr
) + sizeof (integer_t
)))
795 /* Check data representation. */
796 if (darwin_check_message_ndr (ndr
) != 0)
801 /* Find process by port. */
802 inf
= darwin_find_inferior_by_task (task_port
);
805 /* Check message destination. */
806 if (inf
!= NULL
&& hdr
->msgh_local_port
!= inf
->priv
->notify_port
)
813 darwin_encode_reply (mig_reply_error_t
*reply
, mach_msg_header_t
*hdr
,
816 mach_msg_header_t
*rh
= &reply
->Head
;
818 rh
->msgh_bits
= MACH_MSGH_BITS (MACH_MSGH_BITS_REMOTE (hdr
->msgh_bits
), 0);
819 rh
->msgh_remote_port
= hdr
->msgh_remote_port
;
820 rh
->msgh_size
= (mach_msg_size_t
) sizeof (mig_reply_error_t
);
821 rh
->msgh_local_port
= MACH_PORT_NULL
;
822 rh
->msgh_id
= hdr
->msgh_id
+ 100;
824 reply
->NDR
= NDR_record
;
825 reply
->RetCode
= code
;
829 darwin_send_reply (struct inferior
*inf
, darwin_thread_t
*thread
)
832 mig_reply_error_t reply
;
834 darwin_encode_reply (&reply
, &thread
->event
.header
, KERN_SUCCESS
);
836 kret
= mach_msg (&reply
.Head
, MACH_SEND_MSG
| MACH_SEND_INTERRUPT
,
837 reply
.Head
.msgh_size
, 0,
838 MACH_PORT_NULL
, MACH_MSG_TIMEOUT_NONE
,
840 MACH_CHECK_ERROR (kret
);
842 inf
->priv
->pending_messages
--;
846 darwin_resume_thread (struct inferior
*inf
, darwin_thread_t
*thread
,
847 int step
, int nsignal
)
853 (3, _("darwin_resume_thread: state=%d, thread=0x%x, step=%d nsignal=%d\n"),
854 thread
->msg_state
, thread
->gdb_port
, step
, nsignal
);
856 switch (thread
->msg_state
)
859 if (thread
->event
.ex_type
== EXC_SOFTWARE
860 && thread
->event
.ex_data
[0] == EXC_SOFT_SIGNAL
)
862 /* Either deliver a new signal or cancel the signal received. */
863 res
= PTRACE (PT_THUPDATE
, inf
->pid
,
864 (caddr_t
) (uintptr_t) thread
->gdb_port
, nsignal
);
866 inferior_debug (1, _("ptrace THUP: res=%d\n"), res
);
870 /* Note: ptrace is allowed only if the process is stopped.
871 Directly send the signal to the thread. */
872 res
= syscall (SYS___pthread_kill
, thread
->gdb_port
, nsignal
);
873 inferior_debug (4, _("darwin_resume_thread: kill 0x%x %d: %d\n"),
874 thread
->gdb_port
, nsignal
, res
);
875 thread
->signaled
= 1;
878 /* Set or reset single step. */
879 inferior_debug (4, _("darwin_set_sstep (thread=0x%x, enable=%d)\n"),
880 thread
->gdb_port
, step
);
881 darwin_set_sstep (thread
->gdb_port
, step
);
882 thread
->single_step
= step
;
884 darwin_send_reply (inf
, thread
);
885 thread
->msg_state
= DARWIN_RUNNING
;
892 kret
= thread_resume (thread
->gdb_port
);
893 MACH_CHECK_ERROR (kret
);
895 thread
->msg_state
= DARWIN_RUNNING
;
900 /* Resume all threads of the inferior. */
903 darwin_resume_inferior_threads (struct inferior
*inf
, int step
, int nsignal
)
905 darwin_thread_t
*thread
;
909 VEC_iterate (darwin_thread_t
, inf
->priv
->threads
, k
, thread
);
911 darwin_resume_thread (inf
, thread
, step
, nsignal
);
914 struct resume_inferior_threads_param
921 darwin_resume_inferior_threads_it (struct inferior
*inf
, void *param
)
923 int step
= ((struct resume_inferior_threads_param
*)param
)->step
;
924 int nsignal
= ((struct resume_inferior_threads_param
*)param
)->nsignal
;
926 darwin_resume_inferior_threads (inf
, step
, nsignal
);
931 /* Suspend all threads of INF. */
934 darwin_suspend_inferior_threads (struct inferior
*inf
)
936 darwin_thread_t
*thread
;
941 VEC_iterate (darwin_thread_t
, inf
->priv
->threads
, k
, thread
);
943 switch (thread
->msg_state
)
949 kret
= thread_suspend (thread
->gdb_port
);
950 MACH_CHECK_ERROR (kret
);
951 thread
->msg_state
= DARWIN_STOPPED
;
957 darwin_resume (ptid_t ptid
, int step
, enum gdb_signal signal
)
959 struct target_waitstatus status
;
965 struct inferior
*inf
;
968 (2, _("darwin_resume: pid=%d, tid=0x%lx, step=%d, signal=%d\n"),
969 ptid_get_pid (ptid
), ptid_get_tid (ptid
), step
, signal
);
971 if (signal
== GDB_SIGNAL_0
)
974 nsignal
= gdb_signal_to_host (signal
);
976 /* Don't try to single step all threads. */
978 ptid
= inferior_ptid
;
980 /* minus_one_ptid is RESUME_ALL. */
981 if (ptid_equal (ptid
, minus_one_ptid
))
983 struct resume_inferior_threads_param param
;
985 param
.nsignal
= nsignal
;
988 /* Resume threads. */
989 iterate_over_inferiors (darwin_resume_inferior_threads_it
, ¶m
);
991 iterate_over_inferiors (darwin_resume_inferior_it
, NULL
);
995 struct inferior
*inf
= find_inferior_ptid (ptid
);
996 long tid
= ptid_get_tid (ptid
);
998 /* Stop the inferior (should be useless). */
999 darwin_suspend_inferior (inf
);
1002 darwin_resume_inferior_threads (inf
, step
, nsignal
);
1005 darwin_thread_t
*thread
;
1007 /* Suspend threads of the task. */
1008 darwin_suspend_inferior_threads (inf
);
1010 /* Resume the selected thread. */
1011 thread
= darwin_find_thread (inf
, tid
);
1012 gdb_assert (thread
);
1013 darwin_resume_thread (inf
, thread
, step
, nsignal
);
1016 /* Resume the task. */
1017 darwin_resume_inferior (inf
);
1022 darwin_resume_to (struct target_ops
*ops
, ptid_t ptid
, int step
,
1023 enum gdb_signal signal
)
1025 return darwin_resume (ptid
, step
, signal
);
1029 darwin_decode_message (mach_msg_header_t
*hdr
,
1030 darwin_thread_t
**pthread
,
1031 struct inferior
**pinf
,
1032 struct target_waitstatus
*status
)
1034 darwin_thread_t
*thread
;
1035 struct inferior
*inf
;
1037 /* Exception message. 2401 == 0x961 is exc. */
1038 if (hdr
->msgh_id
== 2401)
1042 /* Decode message. */
1043 res
= darwin_decode_exception_message (hdr
, &inf
, &thread
);
1047 /* Should not happen... */
1049 (_("darwin_wait: ill-formatted message (id=0x%x)\n"), hdr
->msgh_id
);
1050 /* FIXME: send a failure reply? */
1051 status
->kind
= TARGET_WAITKIND_IGNORE
;
1052 return minus_one_ptid
;
1056 status
->kind
= TARGET_WAITKIND_IGNORE
;
1057 return minus_one_ptid
;
1061 inf
->priv
->pending_messages
++;
1063 status
->kind
= TARGET_WAITKIND_STOPPED
;
1064 thread
->msg_state
= DARWIN_MESSAGE
;
1066 inferior_debug (4, _("darwin_wait: thread=0x%x, got %s\n"),
1068 unparse_exception_type (thread
->event
.ex_type
));
1070 switch (thread
->event
.ex_type
)
1072 case EXC_BAD_ACCESS
:
1073 status
->value
.sig
= GDB_EXC_BAD_ACCESS
;
1075 case EXC_BAD_INSTRUCTION
:
1076 status
->value
.sig
= GDB_EXC_BAD_INSTRUCTION
;
1078 case EXC_ARITHMETIC
:
1079 status
->value
.sig
= GDB_EXC_ARITHMETIC
;
1082 status
->value
.sig
= GDB_EXC_EMULATION
;
1085 if (thread
->event
.ex_data
[0] == EXC_SOFT_SIGNAL
)
1088 gdb_signal_from_host (thread
->event
.ex_data
[1]);
1089 inferior_debug (5, _(" (signal %d: %s)\n"),
1090 thread
->event
.ex_data
[1],
1091 gdb_signal_to_name (status
->value
.sig
));
1093 /* If the thread is stopped because it has received a signal
1094 that gdb has just sent, continue. */
1095 if (thread
->signaled
)
1097 thread
->signaled
= 0;
1098 darwin_send_reply (inf
, thread
);
1099 thread
->msg_state
= DARWIN_RUNNING
;
1100 status
->kind
= TARGET_WAITKIND_IGNORE
;
1104 status
->value
.sig
= GDB_EXC_SOFTWARE
;
1106 case EXC_BREAKPOINT
:
1107 /* Many internal GDB routines expect breakpoints to be reported
1108 as GDB_SIGNAL_TRAP, and will report GDB_EXC_BREAKPOINT
1109 as a spurious signal. */
1110 status
->value
.sig
= GDB_SIGNAL_TRAP
;
1113 status
->value
.sig
= GDB_SIGNAL_UNKNOWN
;
1117 return ptid_build (inf
->pid
, 0, thread
->gdb_port
);
1119 else if (hdr
->msgh_id
== 0x48)
1121 /* MACH_NOTIFY_DEAD_NAME: notification for exit. */
1124 res
= darwin_decode_notify_message (hdr
, &inf
);
1128 /* Should not happen... */
1130 (_("darwin_wait: ill-formatted message (id=0x%x, res=%d)\n"),
1137 if (res
< 0 || inf
== NULL
)
1139 status
->kind
= TARGET_WAITKIND_IGNORE
;
1140 return minus_one_ptid
;
1145 if (!inf
->priv
->no_ptrace
)
1150 res
= wait4 (inf
->pid
, &wstatus
, 0, NULL
);
1151 if (res
< 0 || res
!= inf
->pid
)
1153 printf_unfiltered (_("wait4: res=%d: %s\n"),
1154 res
, safe_strerror (errno
));
1155 status
->kind
= TARGET_WAITKIND_IGNORE
;
1156 return minus_one_ptid
;
1158 if (WIFEXITED (wstatus
))
1160 status
->kind
= TARGET_WAITKIND_EXITED
;
1161 status
->value
.integer
= WEXITSTATUS (wstatus
);
1165 status
->kind
= TARGET_WAITKIND_SIGNALLED
;
1166 status
->value
.sig
= gdb_signal_from_host (WTERMSIG (wstatus
));
1169 inferior_debug (4, _("darwin_wait: pid=%d exit, status=0x%x\n"),
1172 /* Looks necessary on Leopard and harmless... */
1173 wait4 (inf
->pid
, &wstatus
, 0, NULL
);
1175 inferior_ptid
= ptid_build (inf
->pid
, 0, 0);
1176 return inferior_ptid
;
1180 inferior_debug (4, _("darwin_wait: pid=%d\n"), inf
->pid
);
1181 status
->kind
= TARGET_WAITKIND_EXITED
;
1182 status
->value
.integer
= 0; /* Don't know. */
1183 return ptid_build (inf
->pid
, 0, 0);
1188 /* Unknown message. */
1189 warning (_("darwin: got unknown message, id: 0x%x"), hdr
->msgh_id
);
1190 status
->kind
= TARGET_WAITKIND_IGNORE
;
1191 return minus_one_ptid
;
1195 cancel_breakpoint (ptid_t ptid
)
1197 /* Arrange for a breakpoint to be hit again later. We will handle
1198 the current event, eventually we will resume this thread, and this
1199 breakpoint will trap again.
1201 If we do not do this, then we run the risk that the user will
1202 delete or disable the breakpoint, but the thread will have already
1205 struct regcache
*regcache
= get_thread_regcache (ptid
);
1206 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
1209 pc
= regcache_read_pc (regcache
) - gdbarch_decr_pc_after_break (gdbarch
);
1210 if (breakpoint_inserted_here_p (get_regcache_aspace (regcache
), pc
))
1212 inferior_debug (4, "cancel_breakpoint for thread 0x%lx\n",
1213 (unsigned long) ptid_get_tid (ptid
));
1215 /* Back up the PC if necessary. */
1216 if (gdbarch_decr_pc_after_break (gdbarch
))
1217 regcache_write_pc (regcache
, pc
);
1225 darwin_wait (ptid_t ptid
, struct target_waitstatus
*status
)
1230 mach_msg_header_t hdr
;
1233 mach_msg_header_t
*hdr
= &msgin
.hdr
;
1235 darwin_thread_t
*thread
;
1236 struct inferior
*inf
;
1239 (2, _("darwin_wait: waiting for a message pid=%d thread=%lx\n"),
1240 ptid_get_pid (ptid
), ptid_get_tid (ptid
));
1242 /* Handle fake stop events at first. */
1243 if (darwin_inf_fake_stop
!= NULL
)
1245 inf
= darwin_inf_fake_stop
;
1246 darwin_inf_fake_stop
= NULL
;
1248 status
->kind
= TARGET_WAITKIND_STOPPED
;
1249 status
->value
.sig
= GDB_SIGNAL_TRAP
;
1250 thread
= VEC_index (darwin_thread_t
, inf
->priv
->threads
, 0);
1251 thread
->msg_state
= DARWIN_STOPPED
;
1252 return ptid_build (inf
->pid
, 0, thread
->gdb_port
);
1257 /* set_sigint_trap (); */
1259 /* Wait for a message. */
1260 kret
= mach_msg (&msgin
.hdr
, MACH_RCV_MSG
| MACH_RCV_INTERRUPT
, 0,
1261 sizeof (msgin
.data
), darwin_port_set
, 0, MACH_PORT_NULL
);
1263 /* clear_sigint_trap (); */
1265 if (kret
== MACH_RCV_INTERRUPTED
)
1267 status
->kind
= TARGET_WAITKIND_IGNORE
;
1268 return minus_one_ptid
;
1271 if (kret
!= MACH_MSG_SUCCESS
)
1273 inferior_debug (5, _("mach_msg: ret=0x%x\n"), kret
);
1274 status
->kind
= TARGET_WAITKIND_SPURIOUS
;
1275 return minus_one_ptid
;
1278 /* Debug: display message. */
1279 if (darwin_debug_flag
> 10)
1280 darwin_dump_message (hdr
, darwin_debug_flag
> 11);
1282 res
= darwin_decode_message (hdr
, &thread
, &inf
, status
);
1283 if (ptid_equal (res
, minus_one_ptid
))
1286 /* Early return in case an inferior has exited. */
1290 while (status
->kind
== TARGET_WAITKIND_IGNORE
);
1292 /* Stop all tasks. */
1293 iterate_over_inferiors (darwin_suspend_inferior_it
, NULL
);
1295 /* Read pending messages. */
1298 struct target_waitstatus status2
;
1301 kret
= mach_msg (&msgin
.hdr
,
1302 MACH_RCV_MSG
| MACH_RCV_TIMEOUT
, 0,
1303 sizeof (msgin
.data
), darwin_port_set
, 1, MACH_PORT_NULL
);
1305 if (kret
== MACH_RCV_TIMED_OUT
)
1307 if (kret
!= MACH_MSG_SUCCESS
)
1310 (5, _("darwin_wait: mach_msg(pending) ret=0x%x\n"), kret
);
1314 /* Debug: display message. */
1315 if (darwin_debug_flag
> 10)
1316 darwin_dump_message (hdr
, darwin_debug_flag
> 11);
1318 ptid2
= darwin_decode_message (hdr
, &thread
, &inf
, &status2
);
1320 if (inf
!= NULL
&& thread
!= NULL
1321 && thread
->event
.ex_type
== EXC_BREAKPOINT
)
1323 if (thread
->single_step
1324 || cancel_breakpoint (ptid_build (inf
->pid
, 0, thread
->gdb_port
)))
1326 gdb_assert (thread
->msg_state
== DARWIN_MESSAGE
);
1327 darwin_send_reply (inf
, thread
);
1328 thread
->msg_state
= DARWIN_RUNNING
;
1332 (3, _("darwin_wait: thread 0x%x hit a non-gdb breakpoint\n"),
1336 inferior_debug (3, _("darwin_wait: unhandled pending message\n"));
1342 darwin_wait_to (struct target_ops
*ops
,
1343 ptid_t ptid
, struct target_waitstatus
*status
, int options
)
1345 return darwin_wait (ptid
, status
);
1349 darwin_interrupt (struct target_ops
*self
, ptid_t t
)
1351 struct inferior
*inf
= current_inferior ();
1353 /* FIXME: handle in no_ptrace mode. */
1354 gdb_assert (!inf
->priv
->no_ptrace
);
1355 kill (inf
->pid
, SIGINT
);
1358 /* Deallocate threads port and vector. */
1361 darwin_deallocate_threads (struct inferior
*inf
)
1363 if (inf
->priv
->threads
)
1369 VEC_iterate (darwin_thread_t
, inf
->priv
->threads
, k
, t
);
1372 kret
= mach_port_deallocate (gdb_task
, t
->gdb_port
);
1373 MACH_CHECK_ERROR (kret
);
1375 VEC_free (darwin_thread_t
, inf
->priv
->threads
);
1376 inf
->priv
->threads
= NULL
;
1381 darwin_mourn_inferior (struct target_ops
*ops
)
1383 struct inferior
*inf
= current_inferior ();
1388 /* Deallocate threads. */
1389 darwin_deallocate_threads (inf
);
1391 /* Remove notify_port from darwin_port_set. */
1392 kret
= mach_port_move_member (gdb_task
,
1393 inf
->priv
->notify_port
, MACH_PORT_NULL
);
1394 MACH_CHECK_ERROR (kret
);
1396 /* Remove task port dead_name notification. */
1397 kret
= mach_port_request_notification (gdb_task
, inf
->priv
->task
,
1398 MACH_NOTIFY_DEAD_NAME
, 0,
1400 MACH_MSG_TYPE_MAKE_SEND_ONCE
,
1402 /* This can fail if the task is dead. */
1403 inferior_debug (4, "task=0x%x, prev=0x%x, notify_port=0x%x\n",
1404 inf
->priv
->task
, prev
, inf
->priv
->notify_port
);
1406 if (kret
== KERN_SUCCESS
)
1408 kret
= mach_port_deallocate (gdb_task
, prev
);
1409 MACH_CHECK_ERROR (kret
);
1412 /* Destroy notify_port. */
1413 kret
= mach_port_destroy (gdb_task
, inf
->priv
->notify_port
);
1414 MACH_CHECK_ERROR (kret
);
1416 /* Deallocate saved exception ports. */
1417 darwin_deallocate_exception_ports (inf
->priv
);
1419 /* Deallocate task port. */
1420 kret
= mach_port_deallocate (gdb_task
, inf
->priv
->task
);
1421 MACH_CHECK_ERROR (kret
);
1426 inf_child_mourn_inferior (ops
);
1430 darwin_reply_to_all_pending_messages (struct inferior
*inf
)
1436 VEC_iterate (darwin_thread_t
, inf
->priv
->threads
, k
, t
);
1439 if (t
->msg_state
== DARWIN_MESSAGE
)
1440 darwin_resume_thread (inf
, t
, 0, 0);
1445 darwin_stop_inferior (struct inferior
*inf
)
1447 struct target_waitstatus wstatus
;
1453 gdb_assert (inf
!= NULL
);
1455 darwin_suspend_inferior (inf
);
1457 darwin_reply_to_all_pending_messages (inf
);
1459 if (inf
->priv
->no_ptrace
)
1462 res
= kill (inf
->pid
, SIGSTOP
);
1464 warning (_("cannot kill: %s"), safe_strerror (errno
));
1466 /* Wait until the process is really stopped. */
1469 ptid
= darwin_wait (inferior_ptid
, &wstatus
);
1470 if (wstatus
.kind
== TARGET_WAITKIND_STOPPED
1471 && wstatus
.value
.sig
== GDB_SIGNAL_STOP
)
1476 static kern_return_t
1477 darwin_save_exception_ports (darwin_inferior
*inf
)
1481 inf
->exception_info
.count
=
1482 sizeof (inf
->exception_info
.ports
) / sizeof (inf
->exception_info
.ports
[0]);
1484 kret
= task_get_exception_ports
1485 (inf
->task
, EXC_MASK_ALL
, inf
->exception_info
.masks
,
1486 &inf
->exception_info
.count
, inf
->exception_info
.ports
,
1487 inf
->exception_info
.behaviors
, inf
->exception_info
.flavors
);
1491 static kern_return_t
1492 darwin_restore_exception_ports (darwin_inferior
*inf
)
1497 for (i
= 0; i
< inf
->exception_info
.count
; i
++)
1499 kret
= task_set_exception_ports
1500 (inf
->task
, inf
->exception_info
.masks
[i
], inf
->exception_info
.ports
[i
],
1501 inf
->exception_info
.behaviors
[i
], inf
->exception_info
.flavors
[i
]);
1502 if (kret
!= KERN_SUCCESS
)
1506 return KERN_SUCCESS
;
1509 /* Deallocate saved exception ports. */
1512 darwin_deallocate_exception_ports (darwin_inferior
*inf
)
1517 for (i
= 0; i
< inf
->exception_info
.count
; i
++)
1519 kret
= mach_port_deallocate (gdb_task
, inf
->exception_info
.ports
[i
]);
1520 MACH_CHECK_ERROR (kret
);
1522 inf
->exception_info
.count
= 0;
1526 darwin_setup_exceptions (struct inferior
*inf
)
1530 exception_mask_t mask
;
1532 kret
= darwin_save_exception_ports (inf
->priv
);
1533 if (kret
!= KERN_SUCCESS
)
1534 error (_("Unable to save exception ports, task_get_exception_ports"
1538 /* Set exception port. */
1539 if (enable_mach_exceptions
)
1540 mask
= EXC_MASK_ALL
;
1542 mask
= EXC_MASK_SOFTWARE
| EXC_MASK_BREAKPOINT
;
1543 kret
= task_set_exception_ports (inf
->priv
->task
, mask
, darwin_ex_port
,
1544 EXCEPTION_DEFAULT
, THREAD_STATE_NONE
);
1545 if (kret
!= KERN_SUCCESS
)
1546 error (_("Unable to set exception ports, task_set_exception_ports"
1552 darwin_kill_inferior (struct target_ops
*ops
)
1554 struct inferior
*inf
= current_inferior ();
1555 struct target_waitstatus wstatus
;
1561 if (ptid_equal (inferior_ptid
, null_ptid
))
1564 gdb_assert (inf
!= NULL
);
1566 kret
= darwin_restore_exception_ports (inf
->priv
);
1567 MACH_CHECK_ERROR (kret
);
1569 darwin_reply_to_all_pending_messages (inf
);
1571 res
= kill (inf
->pid
, 9);
1575 darwin_resume_inferior (inf
);
1577 ptid
= darwin_wait (inferior_ptid
, &wstatus
);
1579 else if (errno
!= ESRCH
)
1580 warning (_("Failed to kill inferior: kill (%d, 9) returned [%s]"),
1581 inf
->pid
, safe_strerror (errno
));
1583 target_mourn_inferior (inferior_ptid
);
1587 darwin_setup_request_notification (struct inferior
*inf
)
1590 mach_port_t prev_not
;
1592 kret
= mach_port_request_notification (gdb_task
, inf
->priv
->task
,
1593 MACH_NOTIFY_DEAD_NAME
, 0,
1594 inf
->priv
->notify_port
,
1595 MACH_MSG_TYPE_MAKE_SEND_ONCE
,
1597 if (kret
!= KERN_SUCCESS
)
1598 error (_("Termination notification request failed, "
1599 "mach_port_request_notification\n"
1602 if (prev_not
!= MACH_PORT_NULL
)
1604 /* This is unexpected, as there should not be any previously
1605 registered notification request. But this is not a fatal
1606 issue, so just emit a warning. */
1608 A task termination request was registered before the debugger registered\n\
1609 its own. This is unexpected, but should otherwise not have any actual\n\
1610 impact on the debugging session."));
1615 darwin_attach_pid (struct inferior
*inf
)
1618 mach_port_t prev_port
;
1620 mach_port_t prev_not
;
1621 exception_mask_t mask
;
1623 inf
->priv
= XCNEW (darwin_inferior
);
1625 kret
= task_for_pid (gdb_task
, inf
->pid
, &inf
->priv
->task
);
1626 if (kret
!= KERN_SUCCESS
)
1630 if (!inf
->attach_flag
)
1633 waitpid (inf
->pid
, &status
, 0);
1636 error (_("Unable to find Mach task port for process-id %d: %s (0x%lx).\n"
1637 " (please check gdb is codesigned - see taskgated(8))"),
1638 inf
->pid
, mach_error_string (kret
), (unsigned long) kret
);
1641 inferior_debug (2, _("inferior task: 0x%x, pid: %d\n"),
1642 inf
->priv
->task
, inf
->pid
);
1644 if (darwin_ex_port
== MACH_PORT_NULL
)
1646 /* Create a port to get exceptions. */
1647 kret
= mach_port_allocate (gdb_task
, MACH_PORT_RIGHT_RECEIVE
,
1649 if (kret
!= KERN_SUCCESS
)
1650 error (_("Unable to create exception port, mach_port_allocate "
1654 kret
= mach_port_insert_right (gdb_task
, darwin_ex_port
, darwin_ex_port
,
1655 MACH_MSG_TYPE_MAKE_SEND
);
1656 if (kret
!= KERN_SUCCESS
)
1657 error (_("Unable to create exception port, mach_port_insert_right "
1661 /* Create a port set and put ex_port in it. */
1662 kret
= mach_port_allocate (gdb_task
, MACH_PORT_RIGHT_PORT_SET
,
1664 if (kret
!= KERN_SUCCESS
)
1665 error (_("Unable to create port set, mach_port_allocate "
1669 kret
= mach_port_move_member (gdb_task
, darwin_ex_port
, darwin_port_set
);
1670 if (kret
!= KERN_SUCCESS
)
1671 error (_("Unable to move exception port into new port set, "
1672 "mach_port_move_member\n"
1677 /* Create a port to be notified when the child task terminates. */
1678 kret
= mach_port_allocate (gdb_task
, MACH_PORT_RIGHT_RECEIVE
,
1679 &inf
->priv
->notify_port
);
1680 if (kret
!= KERN_SUCCESS
)
1681 error (_("Unable to create notification port, mach_port_allocate "
1685 kret
= mach_port_move_member (gdb_task
,
1686 inf
->priv
->notify_port
, darwin_port_set
);
1687 if (kret
!= KERN_SUCCESS
)
1688 error (_("Unable to move notification port into new port set, "
1689 "mach_port_move_member\n"
1693 darwin_setup_request_notification (inf
);
1695 darwin_setup_exceptions (inf
);
1697 if (!target_is_pushed (darwin_ops
))
1698 push_target (darwin_ops
);
1702 darwin_init_thread_list (struct inferior
*inf
)
1704 darwin_thread_t
*thread
;
1707 darwin_check_new_threads (inf
);
1709 gdb_assert (inf
->priv
->threads
1710 && VEC_length (darwin_thread_t
, inf
->priv
->threads
) > 0);
1711 thread
= VEC_index (darwin_thread_t
, inf
->priv
->threads
, 0);
1713 /* Note: fork_inferior automatically add a thead but it uses a wrong ptid.
1715 new_ptid
= ptid_build (inf
->pid
, 0, thread
->gdb_port
);
1716 thread_change_ptid (inferior_ptid
, new_ptid
);
1717 inferior_ptid
= new_ptid
;
1720 /* The child must synchronize with gdb: gdb must set the exception port
1721 before the child call PTRACE_SIGEXC. We use a pipe to achieve this.
1722 FIXME: is there a lighter way ? */
1723 static int ptrace_fds
[2];
1726 darwin_ptrace_me (void)
1731 /* Close write end point. */
1732 close (ptrace_fds
[1]);
1734 /* Wait until gdb is ready. */
1735 res
= read (ptrace_fds
[0], &c
, 1);
1737 error (_("unable to read from pipe, read returned: %d"), res
);
1738 close (ptrace_fds
[0]);
1740 /* Get rid of privileges. */
1741 setegid (getgid ());
1744 PTRACE (PT_TRACE_ME
, 0, 0, 0);
1746 /* Redirect signals to exception port. */
1747 PTRACE (PT_SIGEXC
, 0, 0, 0);
1750 /* Dummy function to be sure fork_inferior uses fork(2) and not vfork(2). */
1752 darwin_pre_ptrace (void)
1754 if (pipe (ptrace_fds
) != 0)
1758 error (_("unable to create a pipe: %s"), safe_strerror (errno
));
1761 mark_fd_no_cloexec (ptrace_fds
[0]);
1762 mark_fd_no_cloexec (ptrace_fds
[1]);
1766 darwin_ptrace_him (int pid
)
1770 mach_port_t prev_port
;
1772 struct inferior
*inf
= current_inferior ();
1774 darwin_attach_pid (inf
);
1776 /* Let's the child run. */
1777 close (ptrace_fds
[0]);
1778 close (ptrace_fds
[1]);
1780 unmark_fd_no_cloexec (ptrace_fds
[0]);
1781 unmark_fd_no_cloexec (ptrace_fds
[1]);
1783 darwin_init_thread_list (inf
);
1785 startup_inferior (START_INFERIOR_TRAPS_EXPECTED
);
1789 darwin_execvp (const char *file
, char * const argv
[], char * const env
[])
1791 posix_spawnattr_t attr
;
1795 res
= posix_spawnattr_init (&attr
);
1799 (gdb_stderr
, "Cannot initialize attribute for posix_spawn\n");
1803 /* Do like execve: replace the image. */
1804 ps_flags
= POSIX_SPAWN_SETEXEC
;
1806 /* Disable ASLR. The constant doesn't look to be available outside the
1807 kernel include files. */
1808 #ifndef _POSIX_SPAWN_DISABLE_ASLR
1809 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100
1811 ps_flags
|= _POSIX_SPAWN_DISABLE_ASLR
;
1812 res
= posix_spawnattr_setflags (&attr
, ps_flags
);
1815 fprintf_unfiltered (gdb_stderr
, "Cannot set posix_spawn flags\n");
1819 posix_spawnp (NULL
, argv
[0], NULL
, &attr
, argv
, env
);
1823 darwin_create_inferior (struct target_ops
*ops
, char *exec_file
,
1824 char *allargs
, char **env
, int from_tty
)
1826 /* Do the hard work. */
1827 fork_inferior (exec_file
, allargs
, env
, darwin_ptrace_me
, darwin_ptrace_him
,
1828 darwin_pre_ptrace
, NULL
, darwin_execvp
);
1830 /* Return now in case of error. */
1831 if (ptid_equal (inferior_ptid
, null_ptid
))
1836 /* Set things up such that the next call to darwin_wait will immediately
1837 return a fake stop event for inferior INF.
1839 This assumes that the inferior's thread list has been initialized,
1840 as it will suspend the inferior's first thread. */
1843 darwin_setup_fake_stop_event (struct inferior
*inf
)
1845 darwin_thread_t
*thread
;
1848 gdb_assert (darwin_inf_fake_stop
== NULL
);
1849 darwin_inf_fake_stop
= inf
;
1851 /* When detecting a fake pending stop event, darwin_wait returns
1852 an event saying that the first thread is in a DARWIN_STOPPED
1853 state. To make that accurate, we need to suspend that thread
1854 as well. Otherwise, we'll try resuming it when resuming the
1855 inferior, and get a warning because the thread's suspend count
1856 is already zero, making the resume request useless. */
1857 thread
= VEC_index (darwin_thread_t
, inf
->priv
->threads
, 0);
1858 kret
= thread_suspend (thread
->gdb_port
);
1859 MACH_CHECK_ERROR (kret
);
1862 /* Attach to process PID, then initialize for debugging it
1863 and wait for the trace-trap that results from attaching. */
1865 darwin_attach (struct target_ops
*ops
, const char *args
, int from_tty
)
1871 struct inferior
*inf
;
1874 pid
= parse_pid_to_attach (args
);
1876 if (pid
== getpid ()) /* Trying to masturbate? */
1877 error (_("I refuse to debug myself!"));
1881 char *exec_file
= get_exec_file (0);
1884 printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file
,
1885 target_pid_to_str (pid_to_ptid (pid
)));
1887 printf_unfiltered (_("Attaching to %s\n"),
1888 target_pid_to_str (pid_to_ptid (pid
)));
1890 gdb_flush (gdb_stdout
);
1893 if (pid
== 0 || kill (pid
, 0) < 0)
1894 error (_("Can't attach to process %d: %s (%d)"),
1895 pid
, safe_strerror (errno
), errno
);
1897 inferior_ptid
= pid_to_ptid (pid
);
1898 inf
= current_inferior ();
1899 inferior_appeared (inf
, pid
);
1900 inf
->attach_flag
= 1;
1902 /* Always add a main thread. */
1903 add_thread_silent (inferior_ptid
);
1905 darwin_attach_pid (inf
);
1907 darwin_suspend_inferior (inf
);
1909 darwin_init_thread_list (inf
);
1911 darwin_check_osabi (inf
->priv
, ptid_get_tid (inferior_ptid
));
1913 darwin_setup_fake_stop_event (inf
);
1915 inf
->priv
->no_ptrace
= 1;
1918 /* Take a program previously attached to and detaches it.
1919 The program resumes execution and will no longer stop
1920 on signals, etc. We'd better not have left any breakpoints
1921 in the program or it'll die when it hits one. For this
1922 to work, it may be necessary for the process to have been
1923 previously attached. It *might* work if the program was
1924 started via fork. */
1926 darwin_detach (struct target_ops
*ops
, const char *args
, int from_tty
)
1928 pid_t pid
= ptid_get_pid (inferior_ptid
);
1929 struct inferior
*inf
= current_inferior ();
1933 /* Display message. */
1934 target_announce_detach (from_tty
);
1936 /* If ptrace() is in use, stop the process. */
1937 if (!inf
->priv
->no_ptrace
)
1938 darwin_stop_inferior (inf
);
1940 kret
= darwin_restore_exception_ports (inf
->priv
);
1941 MACH_CHECK_ERROR (kret
);
1943 if (!inf
->priv
->no_ptrace
)
1945 res
= PTRACE (PT_DETACH
, inf
->pid
, 0, 0);
1947 printf_unfiltered (_("Unable to detach from process-id %d: %s (%d)"),
1948 inf
->pid
, safe_strerror (errno
), errno
);
1951 darwin_reply_to_all_pending_messages (inf
);
1953 /* When using ptrace, we have just performed a PT_DETACH, which
1954 resumes the inferior. On the other hand, when we are not using
1955 ptrace, we need to resume its execution ourselves. */
1956 if (inf
->priv
->no_ptrace
)
1957 darwin_resume_inferior (inf
);
1959 darwin_mourn_inferior (ops
);
1963 darwin_files_info (struct target_ops
*ops
)
1968 darwin_pid_to_str (struct target_ops
*ops
, ptid_t ptid
)
1970 static char buf
[80];
1971 long tid
= ptid_get_tid (ptid
);
1975 snprintf (buf
, sizeof (buf
), _("Thread 0x%lx of process %u"),
1976 tid
, ptid_get_pid (ptid
));
1980 return normal_pid_to_str (ptid
);
1984 darwin_thread_alive (struct target_ops
*ops
, ptid_t ptid
)
1989 /* If RDADDR is not NULL, read inferior task's LEN bytes from ADDR and
1990 copy it to RDADDR in gdb's address space.
1991 If WRADDR is not NULL, write gdb's LEN bytes from WRADDR and copy it
1992 to ADDR in inferior task's address space.
1993 Return 0 on failure; number of bytes read / writen otherwise. */
1996 darwin_read_write_inferior (task_t task
, CORE_ADDR addr
,
1997 gdb_byte
*rdaddr
, const gdb_byte
*wraddr
,
2001 mach_vm_size_t res_length
= 0;
2003 mach_msg_type_number_t copy_count
;
2004 mach_vm_size_t remaining_length
;
2005 mach_vm_address_t region_address
;
2006 mach_vm_size_t region_length
;
2008 inferior_debug (8, _("darwin_read_write_inferior(task=0x%x, %s, len=%s)\n"),
2009 task
, core_addr_to_string (addr
), pulongest (length
));
2014 mach_vm_size_t count
;
2016 /* According to target.h(to_xfer_partial), one and only one may be
2018 gdb_assert (wraddr
== NULL
);
2020 kret
= mach_vm_read_overwrite (task
, addr
, length
,
2021 (mach_vm_address_t
) rdaddr
, &count
);
2022 if (kret
!= KERN_SUCCESS
)
2025 (1, _("darwin_read_write_inferior: mach_vm_read failed at %s: %s"),
2026 core_addr_to_string (addr
), mach_error_string (kret
));
2033 gdb_assert (wraddr
!= NULL
);
2037 mach_vm_address_t offset
= addr
& (mach_page_size
- 1);
2038 mach_vm_address_t region_address
= (mach_vm_address_t
) (addr
- offset
);
2039 mach_vm_size_t aligned_length
=
2040 (mach_vm_size_t
) PAGE_ROUND (offset
+ length
);
2041 vm_region_submap_short_info_data_64_t info
;
2042 mach_msg_type_number_t count
= VM_REGION_SUBMAP_SHORT_INFO_COUNT_64
;
2043 natural_t region_depth
= 1000;
2044 mach_vm_address_t region_start
= region_address
;
2045 mach_vm_size_t region_length
;
2046 mach_vm_size_t write_length
;
2048 /* Read page protection. */
2049 kret
= mach_vm_region_recurse
2050 (task
, ®ion_start
, ®ion_length
, ®ion_depth
,
2051 (vm_region_recurse_info_t
) &info
, &count
);
2053 if (kret
!= KERN_SUCCESS
)
2055 inferior_debug (1, _("darwin_read_write_inferior: "
2056 "mach_vm_region_recurse failed at %s: %s\n"),
2057 core_addr_to_string (region_address
),
2058 mach_error_string (kret
));
2063 (9, _("darwin_read_write_inferior: "
2064 "mach_vm_region_recurse addr=%s, start=%s, len=%s\n"),
2065 core_addr_to_string (region_address
),
2066 core_addr_to_string (region_start
),
2067 core_addr_to_string (region_length
));
2069 /* Check for holes in memory. */
2070 if (region_start
> region_address
)
2072 warning (_("No memory at %s (vs %s+0x%x). Nothing written"),
2073 core_addr_to_string (region_address
),
2074 core_addr_to_string (region_start
),
2075 (unsigned)region_length
);
2079 /* Adjust the length. */
2080 region_length
-= (region_address
- region_start
);
2081 if (region_length
> aligned_length
)
2082 region_length
= aligned_length
;
2084 /* Make the pages RW. */
2085 if (!(info
.protection
& VM_PROT_WRITE
))
2087 vm_prot_t prot
= VM_PROT_READ
| VM_PROT_WRITE
;
2089 kret
= mach_vm_protect (task
, region_address
, region_length
,
2091 if (kret
!= KERN_SUCCESS
)
2093 prot
|= VM_PROT_COPY
;
2094 kret
= mach_vm_protect (task
, region_address
, region_length
,
2097 if (kret
!= KERN_SUCCESS
)
2099 warning (_("darwin_read_write_inferior: "
2100 "mach_vm_protect failed at %s "
2101 "(len=0x%lx, prot=0x%x): %s"),
2102 core_addr_to_string (region_address
),
2103 (unsigned long) region_length
, (unsigned) prot
,
2104 mach_error_string (kret
));
2109 if (offset
+ length
> region_length
)
2110 write_length
= region_length
- offset
;
2112 write_length
= length
;
2115 kret
= mach_vm_write (task
, addr
, (vm_offset_t
) wraddr
, write_length
);
2116 if (kret
!= KERN_SUCCESS
)
2118 warning (_("darwin_read_write_inferior: mach_vm_write failed: %s"),
2119 mach_error_string (kret
));
2123 /* Restore page rights. */
2124 if (!(info
.protection
& VM_PROT_WRITE
))
2126 kret
= mach_vm_protect (task
, region_address
, region_length
,
2127 FALSE
, info
.protection
);
2128 if (kret
!= KERN_SUCCESS
)
2130 warning (_("darwin_read_write_inferior: "
2131 "mach_vm_protect restore failed at %s "
2133 core_addr_to_string (region_address
),
2134 (unsigned long) region_length
,
2135 mach_error_string (kret
));
2139 addr
+= write_length
;
2140 wraddr
+= write_length
;
2141 res_length
+= write_length
;
2142 length
-= write_length
;
2148 /* Read LENGTH bytes at offset ADDR of task_dyld_info for TASK, and copy them
2149 to RDADDR (in big endian).
2150 Return 0 on failure; number of bytes read / written otherwise. */
2152 #ifdef TASK_DYLD_INFO_COUNT
2153 /* This is not available in Darwin 9. */
2154 static enum target_xfer_status
2155 darwin_read_dyld_info (task_t task
, CORE_ADDR addr
, gdb_byte
*rdaddr
,
2156 ULONGEST length
, ULONGEST
*xfered_len
)
2158 struct task_dyld_info task_dyld_info
;
2159 mach_msg_type_number_t count
= TASK_DYLD_INFO_COUNT
;
2160 int sz
= TASK_DYLD_INFO_COUNT
* sizeof (natural_t
);
2163 if (addr
!= 0 || length
> sizeof (mach_vm_address_t
))
2164 return TARGET_XFER_EOF
;
2166 kret
= task_info (task
, TASK_DYLD_INFO
,
2167 (task_info_t
) &task_dyld_info
, &count
);
2168 MACH_CHECK_ERROR (kret
);
2169 if (kret
!= KERN_SUCCESS
)
2170 return TARGET_XFER_E_IO
;
2172 store_unsigned_integer (rdaddr
, length
, BFD_ENDIAN_BIG
,
2173 task_dyld_info
.all_image_info_addr
);
2174 *xfered_len
= (ULONGEST
) length
;
2175 return TARGET_XFER_OK
;
2181 static enum target_xfer_status
2182 darwin_xfer_partial (struct target_ops
*ops
,
2183 enum target_object object
, const char *annex
,
2184 gdb_byte
*readbuf
, const gdb_byte
*writebuf
,
2185 ULONGEST offset
, ULONGEST len
, ULONGEST
*xfered_len
)
2187 struct inferior
*inf
= current_inferior ();
2190 (8, _("darwin_xfer_partial(%s, %s, rbuf=%s, wbuf=%s) pid=%u\n"),
2191 core_addr_to_string (offset
), pulongest (len
),
2192 host_address_to_string (readbuf
), host_address_to_string (writebuf
),
2197 case TARGET_OBJECT_MEMORY
:
2199 int l
= darwin_read_write_inferior (inf
->priv
->task
, offset
,
2200 readbuf
, writebuf
, len
);
2203 return TARGET_XFER_EOF
;
2207 *xfered_len
= (ULONGEST
) l
;
2208 return TARGET_XFER_OK
;
2211 #ifdef TASK_DYLD_INFO_COUNT
2212 case TARGET_OBJECT_DARWIN_DYLD_INFO
:
2213 if (writebuf
!= NULL
|| readbuf
== NULL
)
2215 /* Support only read. */
2216 return TARGET_XFER_E_IO
;
2218 return darwin_read_dyld_info (inf
->priv
->task
, offset
, readbuf
, len
,
2222 return TARGET_XFER_E_IO
;
2228 set_enable_mach_exceptions (char *args
, int from_tty
,
2229 struct cmd_list_element
*c
)
2231 if (!ptid_equal (inferior_ptid
, null_ptid
))
2233 struct inferior
*inf
= current_inferior ();
2234 exception_mask_t mask
;
2237 if (enable_mach_exceptions
)
2238 mask
= EXC_MASK_ALL
;
2241 darwin_restore_exception_ports (inf
->priv
);
2242 mask
= EXC_MASK_SOFTWARE
| EXC_MASK_BREAKPOINT
;
2244 kret
= task_set_exception_ports (inf
->priv
->task
, mask
, darwin_ex_port
,
2245 EXCEPTION_DEFAULT
, THREAD_STATE_NONE
);
2246 MACH_CHECK_ERROR (kret
);
2251 darwin_pid_to_exec_file (struct target_ops
*self
, int pid
)
2253 static char path
[PATH_MAX
];
2256 res
= proc_pidinfo (pid
, PROC_PIDPATHINFO
, 0, path
, PATH_MAX
);
2264 darwin_get_ada_task_ptid (struct target_ops
*self
, long lwp
, long thread
)
2269 struct inferior
*inf
= current_inferior ();
2271 mach_port_name_array_t names
;
2272 mach_msg_type_number_t names_count
;
2273 mach_port_type_array_t types
;
2274 mach_msg_type_number_t types_count
;
2277 /* First linear search. */
2279 VEC_iterate (darwin_thread_t
, inf
->priv
->threads
, k
, t
);
2281 if (t
->inf_port
== lwp
)
2282 return ptid_build (ptid_get_pid (inferior_ptid
), 0, t
->gdb_port
);
2284 /* Maybe the port was never extract. Do it now. */
2286 /* First get inferior port names. */
2287 kret
= mach_port_names (inf
->priv
->task
, &names
, &names_count
, &types
,
2289 MACH_CHECK_ERROR (kret
);
2290 if (kret
!= KERN_SUCCESS
)
2293 /* For each name, copy the right in the gdb space and then compare with
2294 our view of the inferior threads. We don't forget to deallocate the
2296 for (i
= 0; i
< names_count
; i
++)
2298 mach_port_t local_name
;
2299 mach_msg_type_name_t local_type
;
2301 /* We just need to know the corresponding name in gdb name space.
2302 So extract and deallocate the right. */
2303 kret
= mach_port_extract_right (inf
->priv
->task
, names
[i
],
2304 MACH_MSG_TYPE_COPY_SEND
,
2305 &local_name
, &local_type
);
2306 if (kret
!= KERN_SUCCESS
)
2308 mach_port_deallocate (gdb_task
, local_name
);
2311 VEC_iterate (darwin_thread_t
, inf
->priv
->threads
, k
, t
);
2313 if (t
->gdb_port
== local_name
)
2315 t
->inf_port
= names
[i
];
2316 if (names
[i
] == lwp
)
2321 vm_deallocate (gdb_task
, (vm_address_t
) names
,
2322 names_count
* sizeof (mach_port_t
));
2325 return ptid_build (ptid_get_pid (inferior_ptid
), 0, res
);
2331 darwin_supports_multi_process (struct target_ops
*self
)
2336 /* -Wmissing-prototypes */
2337 extern initialize_file_ftype _initialize_darwin_inferior
;
2340 _initialize_darwin_inferior (void)
2344 gdb_task
= mach_task_self ();
2345 darwin_host_self
= mach_host_self ();
2347 /* Read page size. */
2348 kret
= host_page_size (darwin_host_self
, &mach_page_size
);
2349 if (kret
!= KERN_SUCCESS
)
2351 mach_page_size
= 0x1000;
2352 MACH_CHECK_ERROR (kret
);
2355 darwin_ops
= inf_child_target ();
2357 darwin_ops
->to_create_inferior
= darwin_create_inferior
;
2358 darwin_ops
->to_attach
= darwin_attach
;
2359 darwin_ops
->to_attach_no_wait
= 0;
2360 darwin_ops
->to_detach
= darwin_detach
;
2361 darwin_ops
->to_files_info
= darwin_files_info
;
2362 darwin_ops
->to_wait
= darwin_wait_to
;
2363 darwin_ops
->to_mourn_inferior
= darwin_mourn_inferior
;
2364 darwin_ops
->to_kill
= darwin_kill_inferior
;
2365 darwin_ops
->to_interrupt
= darwin_interrupt
;
2366 darwin_ops
->to_resume
= darwin_resume_to
;
2367 darwin_ops
->to_thread_alive
= darwin_thread_alive
;
2368 darwin_ops
->to_pid_to_str
= darwin_pid_to_str
;
2369 darwin_ops
->to_pid_to_exec_file
= darwin_pid_to_exec_file
;
2370 darwin_ops
->to_load
= NULL
;
2371 darwin_ops
->to_xfer_partial
= darwin_xfer_partial
;
2372 darwin_ops
->to_supports_multi_process
= darwin_supports_multi_process
;
2373 darwin_ops
->to_get_ada_task_ptid
= darwin_get_ada_task_ptid
;
2375 darwin_complete_target (darwin_ops
);
2377 add_target (darwin_ops
);
2379 inferior_debug (2, _("GDB task: 0x%lx, pid: %d\n"),
2380 (unsigned long) mach_task_self (), getpid ());
2382 add_setshow_zuinteger_cmd ("darwin", class_obscure
,
2383 &darwin_debug_flag
, _("\
2384 Set if printing inferior communication debugging statements."), _("\
2385 Show if printing inferior communication debugging statements."), NULL
,
2387 &setdebuglist
, &showdebuglist
);
2389 add_setshow_boolean_cmd ("mach-exceptions", class_support
,
2390 &enable_mach_exceptions
, _("\
2391 Set if mach exceptions are caught."), _("\
2392 Show if mach exceptions are caught."), _("\
2393 When this mode is on, all low level exceptions are reported before being\n\
2394 reported by the kernel."),
2395 &set_enable_mach_exceptions
, NULL
,
2396 &setlist
, &showlist
);