1 /* Darwin support for GDB, the GNU debugger.
2 Copyright (C) 2008, 2009 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/>.
32 #include "gdbthread.h"
34 #include "event-top.h"
37 #include "exceptions.h"
38 #include "inf-child.h"
40 #include "arch-utils.h"
43 #include <sys/ptrace.h>
44 #include <sys/signal.h>
45 #include <machine/setjmp.h>
46 #include <sys/types.h>
51 #include <sys/param.h>
52 #include <sys/sysctl.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"
67 Darwin kernel is Mach + BSD derived kernel. Note that they share the
68 same memory space and are linked together (ie there is no micro-kernel).
70 Although ptrace(2) is available on Darwin, it is not complete. We have
71 to use Mach calls to read and write memory and to modify registers. We
72 also use Mach to get inferior faults. As we cannot use select(2) or
73 signals with Mach port (the Mach communication channel), signals are
74 reported to gdb as an exception. Furthermore we detect death of the
75 inferior through a Mach notification message. This way we only wait
78 Some Mach documentation is available for Apple xnu source package or
82 #define PTRACE(CMD, PID, ADDR, SIG) \
83 darwin_ptrace(#CMD, CMD, (PID), (ADDR), (SIG))
85 extern boolean_t
exc_server (mach_msg_header_t
*in
, mach_msg_header_t
*out
);
87 static void darwin_stop (ptid_t
);
89 static void darwin_resume (ptid_t ptid
, int step
,
90 enum target_signal signal
);
92 static void darwin_mourn_inferior (struct target_ops
*ops
);
94 static int darwin_lookup_task (char *args
, task_t
* ptask
, int *ppid
);
96 static void darwin_kill_inferior (void);
98 static void darwin_ptrace_me (void);
100 static void darwin_ptrace_him (int pid
);
102 static void darwin_create_inferior (struct target_ops
*ops
, char *exec_file
,
103 char *allargs
, char **env
, int from_tty
);
105 static void darwin_files_info (struct target_ops
*ops
);
107 static int darwin_thread_alive (ptid_t tpid
);
109 /* Current inferior. */
110 darwin_inferior
*darwin_inf
= NULL
;
112 /* Target operations for Darwin. */
113 static struct target_ops
*darwin_ops
;
115 /* Task identifier of gdb. */
116 static task_t gdb_task
;
118 /* A copy of mach_host_self (). */
119 mach_port_t darwin_host_self
;
121 /* Exception port. */
122 mach_port_t darwin_ex_port
;
124 /* Notification port. */
125 mach_port_t darwin_not_port
;
128 mach_port_t darwin_port_set
;
131 static vm_size_t mach_page_size
;
133 /* If Set, catch all mach exceptions (before they are converted to signals
135 static int enable_mach_exceptions
;
137 #define PAGE_TRUNC(x) ((x) & ~(mach_page_size - 1))
138 #define PAGE_ROUND(x) PAGE_TRUNC((x) + mach_page_size - 1)
140 /* Buffer containing received message and to be sent message. */
143 mach_msg_header_t hdr
;
147 /* Current message state.
148 If the kernel has sent a message it expects a reply and the inferior
149 can't be killed before. */
150 static enum msg_state
{ NO_MESSAGE
, GOT_MESSAGE
, REPLY_SENT
} msg_state
;
152 /* Unmarshalled received message. */
153 static struct exc_msg
158 /* Thread and task taking the exception. */
159 mach_port_t thread_port
;
160 mach_port_t task_port
;
162 /* Type of the exception. */
163 exception_type_t ex_type
;
165 /* Machine dependent details. */
166 mach_msg_type_number_t data_count
;
167 integer_t ex_data
[4];
171 /* This controls output of inferior debugging.
172 1 = basic exception handling
174 3 = thread management
175 4 = pending_event_handler
176 6 = most chatty level. */
178 static int darwin_debug_flag
= 0;
181 inferior_debug (int level
, const char *fmt
, ...)
185 if (darwin_debug_flag
< level
)
189 printf_unfiltered (_("[%d inferior]: "), getpid ());
190 vprintf_unfiltered (fmt
, ap
);
195 mach_check_error (kern_return_t ret
, const char *file
,
196 unsigned int line
, const char *func
)
198 if (ret
== KERN_SUCCESS
)
201 func
= _("[UNKNOWN]");
203 error (_("error on line %u of \"%s\" in function \"%s\": %s (0x%lx)\n"),
204 line
, file
, func
, mach_error_string (ret
), (unsigned long) ret
);
208 unparse_exception_type (unsigned int i
)
210 static char unknown_exception_buf
[32];
215 return "EXC_BAD_ACCESS";
216 case EXC_BAD_INSTRUCTION
:
217 return "EXC_BAD_INSTRUCTION";
219 return "EXC_ARITHMETIC";
221 return "EXC_EMULATION";
223 return "EXC_SOFTWARE";
225 return "EXC_BREAKPOINT";
227 return "EXC_SYSCALL";
228 case EXC_MACH_SYSCALL
:
229 return "EXC_MACH_SYSCALL";
231 return "EXC_RPC_ALERT";
235 snprintf (unknown_exception_buf
, 32, _("unknown (%d)"), i
);
236 return unknown_exception_buf
;
241 darwin_ptrace (const char *name
,
242 int request
, int pid
, PTRACE_TYPE_ARG3 arg3
, int arg4
)
246 ret
= ptrace (request
, pid
, (caddr_t
) arg3
, arg4
);
248 inferior_debug (2, _("ptrace (%s, %d, 0x%x, %d): %d (%s)\n"),
249 name
, pid
, arg3
, arg4
, ret
,
250 (ret
!= 0) ? strerror (errno
) : _("no error"));
255 cmp_thread_t (const void *l
, const void *r
)
257 thread_t lt
= *(const thread_t
*)l
;
258 thread_t lr
= *(const thread_t
*)r
;
259 return (int)(lr
- lt
);
263 darwin_check_new_threads (darwin_inferior
*inf
)
267 thread_array_t thread_list
;
268 unsigned int new_nbr
;
269 unsigned int old_nbr
;
270 unsigned int new_ix
, old_ix
;
271 VEC (thread_t
) *thread_vec
;
273 /* Get list of threads. */
274 kret
= task_threads (inf
->task
, &thread_list
, &new_nbr
);
275 MACH_CHECK_ERROR (kret
);
276 if (kret
!= KERN_SUCCESS
)
280 qsort (thread_list
, new_nbr
, sizeof (thread_t
), cmp_thread_t
);
282 thread_vec
= VEC_alloc (thread_t
, new_nbr
);
285 old_nbr
= VEC_length (thread_t
, inf
->threads
);
289 for (new_ix
= 0, old_ix
= 0; new_ix
< new_nbr
|| old_ix
< old_nbr
;)
291 thread_t new_id
= (new_ix
< new_nbr
) ?
292 thread_list
[new_ix
] : THREAD_NULL
;
293 thread_t old_id
= (old_ix
< old_nbr
) ?
294 VEC_index (thread_t
, inf
->threads
, old_ix
) : THREAD_NULL
;
296 if (old_id
== new_id
)
298 /* Thread still exist. */
299 VEC_safe_push (thread_t
, thread_vec
, old_id
);
303 kret
= mach_port_deallocate (gdb_task
, old_id
);
304 MACH_CHECK_ERROR (kret
);
307 if (new_id
< old_id
|| old_ix
== old_nbr
)
309 /* A thread was created. */
310 struct thread_info
*tp
;
312 tp
= add_thread (ptid_build (inf
->pid
, 0, new_id
));
313 VEC_safe_push (thread_t
, thread_vec
, new_id
);
317 if (new_id
> old_id
|| new_ix
== new_nbr
)
319 /* A thread was removed. */
320 delete_thread (ptid_build (inf
->pid
, 0, old_id
));
321 kret
= mach_port_deallocate (gdb_task
, old_id
);
322 MACH_CHECK_ERROR (kret
);
328 VEC_free (thread_t
, inf
->threads
);
329 inf
->threads
= thread_vec
;
331 kret
= vm_deallocate (gdb_task
, (vm_address_t
) thread_list
,
332 new_nbr
* sizeof (int));
333 MACH_CHECK_ERROR (kret
);
337 darwin_stop (ptid_t t
)
341 ret
= kill (ptid_get_pid (inferior_ptid
), SIGINT
);
345 darwin_resume (ptid_t ptid
, int step
, enum target_signal signal
)
347 struct target_waitstatus status
;
353 /* minus_one_ptid is RESUME_ALL. */
354 if (ptid_equal (ptid
, minus_one_ptid
))
355 ptid
= inferior_ptid
;
357 pid
= ptid_get_pid (ptid
);
358 thread
= ptid_get_tid (ptid
);
361 (2, _("darwin_resume: state=%d, thread=0x%x, step=%d signal=%d\n"),
362 msg_state
, thread
, step
, signal
);
367 switch (exc_msg
.ex_type
)
370 if (exc_msg
.ex_data
[0] == EXC_SOFT_SIGNAL
)
372 int nsignal
= target_signal_to_host (signal
);
373 res
= PTRACE (PT_THUPDATE
, pid
,
374 (void *)exc_msg
.thread_port
, nsignal
);
376 printf_unfiltered (_("ptrace THUP: res=%d\n"), res
);
386 inferior_debug (2, _("darwin_set_sstep (thread=%x, enable=%d)\n"),
388 darwin_set_sstep (thread
, step
);
391 kret
= mach_msg (&msgout
.hdr
, MACH_SEND_MSG
| MACH_SEND_INTERRUPT
,
392 msgout
.hdr
.msgh_size
, 0,
393 MACH_PORT_NULL
, MACH_MSG_TIMEOUT_NONE
,
396 printf_unfiltered (_("mach_msg (reply) ret=%d\n"), kret
);
398 msg_state
= REPLY_SENT
;
403 res
= PTRACE (PT_STEP
, pid
, (caddr_t
)1, 0);
405 res
= PTRACE (PT_CONTINUE
, pid
, (caddr_t
)1, 0);
414 catch_exception_raise_state
416 exception_type_t exception_type
, mach_exception_data_t exception_data
,
417 mach_msg_type_number_t data_count
, thread_state_flavor_t
* state_flavor
,
418 thread_state_t in_state
, mach_msg_type_number_t in_state_count
,
419 thread_state_t out_state
, mach_msg_type_number_t out_state_count
)
425 catch_exception_raise_state_identity
426 (mach_port_t port
, mach_port_t thread_port
, mach_port_t task_port
,
427 exception_type_t exception_type
, mach_exception_data_t exception_data
,
428 mach_msg_type_number_t data_count
, thread_state_flavor_t
* state_flavor
,
429 thread_state_t in_state
, mach_msg_type_number_t in_state_count
,
430 thread_state_t out_state
, mach_msg_type_number_t out_state_count
)
434 kret
= mach_port_deallocate (mach_task_self (), task_port
);
435 MACH_CHECK_ERROR (kret
);
436 kret
= mach_port_deallocate (mach_task_self (), thread_port
);
437 MACH_CHECK_ERROR (kret
);
443 catch_exception_raise (mach_port_t port
,
444 mach_port_t thread_port
,
445 mach_port_t task_port
,
446 exception_type_t exception_type
,
447 exception_data_t exception_data
,
448 mach_msg_type_number_t data_count
)
454 /* We got new rights to the task. Get rid of it. */
455 kret
= mach_port_deallocate (mach_task_self (), task_port
);
456 MACH_CHECK_ERROR (kret
);
459 (7, _("catch_exception_raise: exception_type=%d, data_count=%d\n"),
460 exception_type
, data_count
);
461 if (darwin_debug_flag
> 7)
463 for (i
= 0; i
< data_count
; i
++)
464 printf_unfiltered (" %08x", exception_data
[i
]);
465 printf_unfiltered ("\n");
469 FIXME: this should be in a per-thread variable. */
471 exc_msg
.thread_port
= thread_port
;
472 exc_msg
.task_port
= task_port
;
473 exc_msg
.ex_type
= exception_type
;
474 exc_msg
.data_count
= data_count
;
475 for (i
= 0; i
< data_count
&& i
< 4; i
++)
476 exc_msg
.ex_data
[i
] = exception_data
[i
];
482 darwin_wait (struct target_ops
*ops
,
483 ptid_t ptid
, struct target_waitstatus
*status
)
486 mach_msg_header_t
*hdr
= &msgin
.hdr
;
487 pid_t pid
= ptid_get_pid (inferior_ptid
); /* FIXME. */
489 gdb_assert (msg_state
!= GOT_MESSAGE
);
491 inferior_debug (6, _("darwin_wait: waiting for a message\n"));
493 /* Wait for a message. */
494 kret
= mach_msg (&msgin
.hdr
, MACH_RCV_MSG
| MACH_RCV_INTERRUPT
, 0,
495 sizeof (msgin
.data
), darwin_port_set
, 0, MACH_PORT_NULL
);
497 if (kret
== MACH_RCV_INTERRUPTED
)
499 status
->kind
= TARGET_WAITKIND_IGNORE
;
500 return minus_one_ptid
;
503 if (kret
!= MACH_MSG_SUCCESS
)
505 inferior_debug (1, _("mach_msg: ret=%x\n"), kret
);
506 status
->kind
= TARGET_WAITKIND_SPURIOUS
;
507 return minus_one_ptid
;
510 /* Debug: display message. */
511 if (darwin_debug_flag
> 10)
513 const unsigned long *buf
= (unsigned long *) hdr
;
516 printf_unfiltered (_(" bits: 0x%x"), hdr
->msgh_bits
);
517 printf_unfiltered (_(", size: 0x%x"), hdr
->msgh_size
);
518 printf_unfiltered (_(", remote-port: 0x%x"), hdr
->msgh_remote_port
);
519 printf_unfiltered (_(", local-port: 0x%x"), hdr
->msgh_local_port
);
520 printf_unfiltered (_(", reserved: 0x%x"), hdr
->msgh_reserved
);
521 printf_unfiltered (_(", id: 0x%x\n"), hdr
->msgh_id
);
523 if (darwin_debug_flag
> 11)
525 printf_unfiltered (_(" data:"));
526 for (i
= 0; i
< hdr
->msgh_size
; i
++)
527 printf_unfiltered (" %08lx", buf
[i
]);
528 printf_unfiltered (_("\n"));
532 /* Exception message. */
533 if (hdr
->msgh_local_port
== darwin_ex_port
)
535 /* Handle it via the exception server. */
536 if (!exc_server (&msgin
.hdr
, &msgout
.hdr
))
538 printf_unfiltered (_("exc_server: unknown message (id=%x)\n"),
540 status
->kind
= TARGET_WAITKIND_SPURIOUS
;
541 return minus_one_ptid
;
544 status
->kind
= TARGET_WAITKIND_STOPPED
;
546 inferior_debug (2, _("darwin_wait: thread=%x, got %s\n"),
548 unparse_exception_type (exc_msg
.ex_type
));
550 switch (exc_msg
.ex_type
)
553 status
->value
.sig
= TARGET_EXC_BAD_ACCESS
;
555 case EXC_BAD_INSTRUCTION
:
556 status
->value
.sig
= TARGET_EXC_BAD_INSTRUCTION
;
559 status
->value
.sig
= TARGET_EXC_ARITHMETIC
;
562 status
->value
.sig
= TARGET_EXC_EMULATION
;
565 if (exc_msg
.ex_data
[0] == EXC_SOFT_SIGNAL
)
567 status
->value
.sig
= target_signal_from_host (exc_msg
.ex_data
[1]);
568 inferior_debug (2, _(" (signal %d: %s)\n"),
570 target_signal_to_name (status
->value
.sig
));
573 status
->value
.sig
= TARGET_EXC_SOFTWARE
;
576 /* Many internal GDB routines expect breakpoints to be reported
577 as TARGET_SIGNAL_TRAP, and will report TARGET_EXC_BREAKPOINT
578 as a spurious signal. */
579 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
582 status
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
586 msg_state
= GOT_MESSAGE
;
588 return ptid_build (pid
, 0, exc_msg
.thread_port
);
590 else if (hdr
->msgh_local_port
== darwin_not_port
)
595 /* FIXME: translate task port to pid. */
596 res
= wait4 (pid
, &wstatus
, 0, NULL
);
599 printf_unfiltered (_("wait4: res=%x\n"), res
);
602 status
->kind
= TARGET_WAITKIND_EXITED
;
603 status
->value
.integer
= WEXITSTATUS (wstatus
);
605 inferior_debug (2, _("darwin_wait: pid=%d exit, status=%x\n"),
608 msg_state
= NO_MESSAGE
;
614 printf_unfiltered (_("Bad local-port: %x\n"), hdr
->msgh_local_port
);
615 status
->kind
= TARGET_WAITKIND_SPURIOUS
;
616 return minus_one_ptid
;
621 darwin_mourn_inferior (struct target_ops
*ops
)
623 struct inferior
*inf
= current_inferior ();
628 unpush_target (darwin_ops
);
630 /* Deallocate threads. */
631 if (darwin_inf
->threads
)
635 for (k
= 0; VEC_iterate (thread_t
, darwin_inf
->threads
, k
, t
); k
++)
637 kret
= mach_port_deallocate (gdb_task
, t
);
638 MACH_CHECK_ERROR (kret
);
640 VEC_free (thread_t
, darwin_inf
->threads
);
641 darwin_inf
->threads
= NULL
;
644 kret
= mach_port_request_notification (gdb_task
, darwin_inf
->task
,
645 MACH_NOTIFY_DEAD_NAME
, 0,
646 darwin_inf
->prev_not_port
,
647 MACH_MSG_TYPE_MAKE_SEND_ONCE
,
649 /* This can fail if the task is dead. */
650 if (kret
== KERN_SUCCESS
)
652 kret
= mach_port_deallocate (gdb_task
, prev
);
653 MACH_CHECK_ERROR (kret
);
656 /* Deallocate saved exception ports. */
657 for (i
= 0; i
< darwin_inf
->exception_info
.count
; i
++)
659 kret
= mach_port_deallocate
660 (gdb_task
, darwin_inf
->exception_info
.ports
[i
]);
661 MACH_CHECK_ERROR (kret
);
663 darwin_inf
->exception_info
.count
= 0;
665 kret
= mach_port_deallocate (gdb_task
, darwin_inf
->task
);
666 MACH_CHECK_ERROR (kret
);
668 darwin_inf
->task
= 0;
671 generic_mourn_inferior ();
675 darwin_stop_inferior (darwin_inferior
*inf
)
677 struct target_waitstatus wstatus
;
683 gdb_assert (inf
!= NULL
);
685 kret
= task_suspend (inf
->task
);
686 MACH_CHECK_ERROR (kret
);
688 if (msg_state
== GOT_MESSAGE
)
689 darwin_resume (inferior_ptid
, 0, 0);
691 res
= kill (inf
->pid
, SIGSTOP
);
693 warning (_("cannot kill: %s\n"), strerror (errno
));
695 ptid
= darwin_wait (inferior_ptid
, &wstatus
);
696 gdb_assert (wstatus
.kind
= TARGET_WAITKIND_STOPPED
);
700 darwin_kill_inferior (void)
702 struct target_waitstatus wstatus
;
708 gdb_assert (darwin_inf
!= NULL
);
710 if (ptid_equal (inferior_ptid
, null_ptid
))
713 darwin_stop_inferior (darwin_inf
);
715 res
= PTRACE (PT_KILL
, darwin_inf
->pid
, 0, 0);
716 gdb_assert (res
== 0);
718 if (msg_state
== GOT_MESSAGE
)
721 darwin_resume (inferior_ptid
, 0, 0);
724 kret
= task_resume (darwin_inf
->task
);
725 MACH_CHECK_ERROR (kret
);
727 ptid
= darwin_wait (inferior_ptid
, &wstatus
);
729 /* This double wait seems required... */
730 res
= waitpid (darwin_inf
->pid
, &status
, 0);
731 gdb_assert (res
== darwin_inf
->pid
);
733 msg_state
= NO_MESSAGE
;
735 target_mourn_inferior ();
738 /* The child must synchronize with gdb: gdb must set the exception port
739 before the child call PTRACE_SIGEXC. We use a pipe to achieve this.
740 FIXME: is there a lighter way ? */
741 static int ptrace_fds
[2];
744 darwin_ptrace_me (void)
749 /* Close write end point. */
750 close (ptrace_fds
[1]);
752 /* Wait until gdb is ready. */
753 res
= read (ptrace_fds
[0], &c
, 1);
754 gdb_assert (res
== 0);
755 close (ptrace_fds
[0]);
757 /* Get rid of privileges. */
761 PTRACE (PT_TRACE_ME
, 0, 0, 0);
763 /* Redirect signals to exception port. */
764 PTRACE (PT_SIGEXC
, 0, 0, 0);
767 /* Dummy function to be sure fork_inferior uses fork(2) and not vfork(2). */
769 darwin_pre_ptrace (void)
771 if (pipe (ptrace_fds
) != 0)
775 error (_("unable to create a pipe: %s"), safe_strerror (errno
));
780 darwin_save_exception_ports (darwin_inferior
*inf
)
784 inf
->exception_info
.count
=
785 sizeof (inf
->exception_info
.ports
) / sizeof (inf
->exception_info
.ports
[0]);
787 kret
= task_get_exception_ports
788 (inf
->task
, EXC_MASK_ALL
, inf
->exception_info
.masks
,
789 &inf
->exception_info
.count
, inf
->exception_info
.ports
,
790 inf
->exception_info
.behaviors
, inf
->exception_info
.flavors
);
795 darwin_restore_exception_ports (darwin_inferior
*inf
)
800 for (i
= 0; i
< inf
->exception_info
.count
; i
++)
802 kret
= task_set_exception_ports
803 (inf
->task
, inf
->exception_info
.masks
[i
], inf
->exception_info
.ports
[i
],
804 inf
->exception_info
.behaviors
[i
], inf
->exception_info
.flavors
[i
]);
805 if (kret
!= KERN_SUCCESS
)
813 darwin_attach_pid (int pid
)
817 mach_port_t prev_port
;
819 exception_mask_t mask
;
821 kret
= task_for_pid (gdb_task
, pid
, &itask
);
822 if (kret
!= KERN_SUCCESS
)
825 struct inferior
*inf
= current_inferior ();
827 if (!inf
->attach_flag
)
830 waitpid (pid
, &status
, 0);
833 error (_("Unable to find Mach task port for process-id %d: %s (0x%lx).\n"
834 " (please check gdb is setgid procmod)"),
835 pid
, mach_error_string (kret
), (unsigned long) kret
);
838 inferior_debug (2, _("inferior task: 0x%08x, pid: %d\n"), itask
, pid
);
840 if (darwin_ex_port
== MACH_PORT_NULL
)
842 /* Create a port to get exceptions. */
843 kret
= mach_port_allocate (gdb_task
, MACH_PORT_RIGHT_RECEIVE
,
845 gdb_assert (kret
== KERN_SUCCESS
);
847 kret
= mach_port_insert_right (gdb_task
, darwin_ex_port
, darwin_ex_port
,
848 MACH_MSG_TYPE_MAKE_SEND
);
849 gdb_assert (kret
== KERN_SUCCESS
);
851 /* Create a port set and put ex_port in it. */
852 kret
= mach_port_allocate (gdb_task
, MACH_PORT_RIGHT_PORT_SET
,
854 gdb_assert (kret
== KERN_SUCCESS
);
856 kret
= mach_port_move_member (gdb_task
, darwin_ex_port
, darwin_port_set
);
857 gdb_assert (kret
== KERN_SUCCESS
);
859 /* Create a port to be notified when the child task terminates. */
860 kret
= mach_port_allocate (gdb_task
, MACH_PORT_RIGHT_RECEIVE
,
862 gdb_assert (kret
== KERN_SUCCESS
);
864 kret
= mach_port_insert_right (gdb_task
, darwin_not_port
, darwin_not_port
,
865 MACH_MSG_TYPE_MAKE_SEND
);
866 gdb_assert (kret
== KERN_SUCCESS
);
868 kret
= mach_port_move_member (gdb_task
, darwin_not_port
, darwin_port_set
);
869 gdb_assert (kret
== KERN_SUCCESS
);
872 kret
= mach_port_request_notification (gdb_task
, itask
,
873 MACH_NOTIFY_DEAD_NAME
, 0,
875 MACH_MSG_TYPE_MAKE_SEND_ONCE
,
876 &darwin_inf
->prev_not_port
);
877 gdb_assert (kret
== KERN_SUCCESS
);
879 darwin_inf
->task
= itask
;
880 darwin_inf
->pid
= pid
;
882 kret
= darwin_save_exception_ports (darwin_inf
);
883 gdb_assert (kret
== KERN_SUCCESS
);
885 /* Set exception port. */
886 if (enable_mach_exceptions
)
889 mask
= EXC_MASK_SOFTWARE
;
890 kret
= task_set_exception_ports
891 (itask
, mask
, darwin_ex_port
, EXCEPTION_DEFAULT
, THREAD_STATE_NONE
);
892 gdb_assert (kret
== KERN_SUCCESS
);
894 push_target (darwin_ops
);
898 darwin_init_thread_list (darwin_inferior
*inf
)
902 darwin_check_new_threads (inf
);
904 gdb_assert (inf
->threads
&& VEC_length (thread_t
, inf
->threads
) > 0);
905 thread
= VEC_index (thread_t
, inf
->threads
, 0);
906 inferior_ptid
= ptid_build (inf
->pid
, 0, thread
);
910 darwin_ptrace_him (int pid
)
914 mach_port_t prev_port
;
917 darwin_attach_pid (pid
);
919 /* Let's the child run. */
920 close (ptrace_fds
[0]);
921 close (ptrace_fds
[1]);
923 /* fork_inferior automatically add a thread - but it uses a wrong tid. */
924 delete_thread_silent (inferior_ptid
);
925 darwin_init_thread_list (darwin_inf
);
927 startup_inferior (START_INFERIOR_TRAPS_EXPECTED
);
931 darwin_create_inferior (struct target_ops
*ops
, char *exec_file
,
932 char *allargs
, char **env
, int from_tty
)
934 /* Do the hard work. */
935 fork_inferior (exec_file
, allargs
, env
, darwin_ptrace_me
, darwin_ptrace_him
,
936 darwin_pre_ptrace
, NULL
);
938 /* Return now in case of error. */
939 if (ptid_equal (inferior_ptid
, null_ptid
))
944 /* Attach to process PID, then initialize for debugging it
945 and wait for the trace-trap that results from attaching. */
947 darwin_attach (struct target_ops
*ops
, char *args
, int from_tty
)
953 struct inferior
*inf
;
955 gdb_assert (msg_state
== NO_MESSAGE
);
958 error_no_arg (_("process-id to attach"));
962 if (pid
== getpid ()) /* Trying to masturbate? */
963 error (_("I refuse to debug myself!"));
966 printf_unfiltered (_("Attaching to pid %d\n"), pid
);
968 res
= PTRACE (PT_ATTACHEXC
, pid
, 0, 0);
970 error (_("Unable to attach to process-id %d: %s (%d)"),
971 pid
, strerror (errno
), errno
);
973 inf
= add_inferior (pid
);
974 inf
->attach_flag
= 1;
976 darwin_attach_pid (pid
);
978 pid2
= wait4 (pid
, &wstatus
, WUNTRACED
, NULL
);
979 gdb_assert (pid2
== pid
);
980 inferior_debug (1, _("darwin_attach: wait4 pid=%d, status=0x%x\n"),
984 darwin_init_thread_list (darwin_inf
);
986 darwin_check_osabi (darwin_inf
, ptid_get_tid (inferior_ptid
));
988 /* Looks strange, but the kernel doesn't stop the process...
991 /* FIXME: doesn't look to work with multi-threads!! */
995 /* Take a program previously attached to and detaches it.
996 The program resumes execution and will no longer stop
997 on signals, etc. We'd better not have left any breakpoints
998 in the program or it'll die when it hits one. For this
999 to work, it may be necessary for the process to have been
1000 previously attached. It *might* work if the program was
1001 started via fork. */
1003 darwin_detach (struct target_ops
*ops
, char *args
, int from_tty
)
1010 char *exec_file
= get_exec_file (0);
1013 printf_unfiltered (_("Detaching from program: %s, %d\n"), exec_file
,
1014 ptid_get_pid (inferior_ptid
));
1015 gdb_flush (gdb_stdout
);
1018 darwin_stop_inferior (darwin_inf
);
1020 kret
= darwin_restore_exception_ports (darwin_inf
);
1021 MACH_CHECK_ERROR (kret
);
1023 if (msg_state
== GOT_MESSAGE
)
1025 exc_msg
.ex_type
= 0;
1026 darwin_resume (inferior_ptid
, 0, 0);
1029 kret
= task_resume (darwin_inf
->task
);
1030 gdb_assert (kret
== KERN_SUCCESS
);
1032 res
= PTRACE (PT_DETACH
, darwin_inf
->pid
, 0, 0);
1034 printf_unfiltered (_("Unable to detach from process-id %d: %s (%d)"),
1035 darwin_inf
->pid
, strerror (errno
), errno
);
1037 msg_state
= NO_MESSAGE
;
1039 darwin_mourn_inferior (ops
);
1043 darwin_files_info (struct target_ops
*ops
)
1045 gdb_assert (darwin_inf
!= NULL
);
1049 darwin_pid_to_str (struct target_ops
*ops
, ptid_t ptid
)
1051 static char buf
[128];
1053 snprintf (buf
, sizeof (buf
),
1054 _("process %d gdb-thread 0x%lx"),
1055 (unsigned) ptid_get_pid (ptid
),
1056 (unsigned long) ptid_get_tid (ptid
));
1061 darwin_thread_alive (ptid_t ptid
)
1066 /* If RDADDR is not NULL, read inferior task's LEN bytes from ADDR and
1067 copy it to RDADDR in gdb's address space.
1068 If WRADDR is not NULL, write gdb's LEN bytes from WRADDR and copy it
1069 to ADDR in inferior task's address space.
1070 Return 0 on failure; number of bytes read / writen otherwise. */
1072 darwin_read_write_inferior (task_t task
, CORE_ADDR addr
,
1073 char *rdaddr
, const char *wraddr
, int length
)
1076 mach_vm_address_t offset
= addr
& (mach_page_size
- 1);
1077 mach_vm_address_t low_address
= (mach_vm_address_t
) (addr
- offset
);
1078 mach_vm_size_t aligned_length
= (mach_vm_size_t
) PAGE_ROUND (offset
+ length
);
1081 mach_vm_size_t remaining_length
;
1082 mach_vm_address_t region_address
;
1083 mach_vm_size_t region_length
;
1085 inferior_debug (8, _("darwin_read_write_inferior(%s, len=%d)\n"),
1086 core_addr_to_string (addr
), length
);
1088 /* Get memory from inferior with page aligned addresses */
1089 err
= mach_vm_read (task
, low_address
, aligned_length
,
1090 &copied
, ©_count
);
1091 if (err
!= KERN_SUCCESS
)
1093 warning (_("darwin_read_write_inferior: vm_read failed: %s"),
1094 mach_error_string (err
));
1099 memcpy (rdaddr
, (char *)copied
+ offset
, length
);
1104 memcpy ((char *)copied
+ offset
, wraddr
, length
);
1106 /* Do writes atomically.
1107 First check for holes and unwritable memory. */
1108 for (region_address
= low_address
, remaining_length
= aligned_length
;
1109 region_address
< low_address
+ aligned_length
;
1110 region_address
+= region_length
, remaining_length
-= region_length
)
1112 vm_region_basic_info_data_64_t info
;
1113 mach_port_t object_name
;
1114 mach_vm_address_t old_address
= region_address
;
1115 mach_msg_type_number_t count
;
1117 region_length
= remaining_length
;
1118 count
= VM_REGION_BASIC_INFO_COUNT_64
;
1119 err
= mach_vm_region (task
, ®ion_address
, ®ion_length
,
1120 VM_REGION_BASIC_INFO_64
,
1121 (vm_region_info_t
) &info
, &count
, &object_name
);
1123 if (err
!= KERN_SUCCESS
)
1125 warning (_("darwin_write_inferior: mach_vm_region failed: %s"),
1126 mach_error_string (err
));
1130 /* Check for holes in memory */
1131 if (region_address
> old_address
)
1133 warning (_("No memory at %s (vs %s+0x%x). Nothing written"),
1134 core_addr_to_string (old_address
),
1135 core_addr_to_string (region_address
),
1136 (unsigned)region_length
);
1141 if (!(info
.max_protection
& VM_PROT_WRITE
))
1143 warning (_("Memory at address %s is unwritable. Nothing written"),
1144 core_addr_to_string (old_address
));
1149 if (!(info
.protection
& VM_PROT_WRITE
))
1151 err
= mach_vm_protect (task
, old_address
, region_length
,
1152 FALSE
, info
.protection
| VM_PROT_WRITE
);
1153 if (err
!= KERN_SUCCESS
)
1156 (_("darwin_read_write_inferior: mach_vm_protect failed: %s"),
1157 mach_error_string (err
));
1164 err
= mach_vm_write (task
, low_address
, copied
, aligned_length
);
1166 if (err
!= KERN_SUCCESS
)
1168 warning (_("darwin_read_write_inferior: mach_vm_write failed: %s"),
1169 mach_error_string (err
));
1173 mach_vm_deallocate (mach_task_self (), copied
, copy_count
);
1178 /* Return 0 on failure, number of bytes handled otherwise. TARGET
1181 darwin_xfer_memory (CORE_ADDR memaddr
, gdb_byte
*myaddr
, int len
, int write
,
1182 struct mem_attrib
*attrib
, struct target_ops
*target
)
1184 task_t task
= darwin_inf
->task
;
1186 if (task
== MACH_PORT_NULL
)
1189 inferior_debug (8, _("darwin_xfer_memory(%s, %d, %c)\n"),
1190 core_addr_to_string (memaddr
), len
, write
? 'w' : 'r');
1193 return darwin_read_write_inferior (task
, memaddr
, NULL
, myaddr
, len
);
1195 return darwin_read_write_inferior (task
, memaddr
, myaddr
, NULL
, len
);
1199 darwin_xfer_partial (struct target_ops
*ops
,
1200 enum target_object object
, const char *annex
,
1201 gdb_byte
*readbuf
, const gdb_byte
*writebuf
,
1202 ULONGEST offset
, LONGEST len
)
1204 inferior_debug (8, _("darwin_xfer_partial(%s, %d, rbuf=%p, wbuf=%p)\n"),
1205 core_addr_to_string (offset
), (int)len
, readbuf
, writebuf
);
1207 if (object
!= TARGET_OBJECT_MEMORY
)
1210 return darwin_read_write_inferior (darwin_inf
->task
, offset
,
1211 readbuf
, writebuf
, len
);
1215 set_enable_mach_exceptions (char *args
, int from_tty
,
1216 struct cmd_list_element
*c
)
1218 if (darwin_inf
&& darwin_inf
->task
!= TASK_NULL
)
1220 exception_mask_t mask
;
1223 if (enable_mach_exceptions
)
1224 mask
= EXC_MASK_ALL
;
1227 darwin_restore_exception_ports (darwin_inf
);
1228 mask
= EXC_MASK_SOFTWARE
;
1230 kret
= task_set_exception_ports (darwin_inf
->task
, mask
, darwin_ex_port
,
1231 EXCEPTION_DEFAULT
, THREAD_STATE_NONE
);
1232 MACH_CHECK_ERROR (kret
);
1237 _initialize_darwin_inferior ()
1241 gdb_assert (darwin_inf
== NULL
);
1243 gdb_task
= mach_task_self ();
1244 darwin_host_self
= mach_host_self ();
1246 /* Read page size. */
1247 kret
= host_page_size (darwin_host_self
, &mach_page_size
);
1248 if (kret
!= KERN_SUCCESS
)
1250 mach_page_size
= 0x1000;
1251 MACH_CHECK_ERROR (kret
);
1254 darwin_inf
= (struct darwin_inferior
*)
1255 xmalloc (sizeof (struct darwin_inferior
));
1257 memset (darwin_inf
, 0, sizeof (*darwin_inf
));
1259 darwin_ops
= inf_child_target ();
1261 darwin_ops
->to_shortname
= "darwin-child";
1262 darwin_ops
->to_longname
= _("Darwin child process");
1263 darwin_ops
->to_doc
=
1264 _("Darwin child process (started by the \"run\" command).");
1265 darwin_ops
->to_create_inferior
= darwin_create_inferior
;
1266 darwin_ops
->to_attach
= darwin_attach
;
1267 darwin_ops
->to_attach_no_wait
= 0;
1268 darwin_ops
->to_detach
= darwin_detach
;
1269 darwin_ops
->to_files_info
= darwin_files_info
;
1270 darwin_ops
->to_wait
= darwin_wait
;
1271 darwin_ops
->to_mourn_inferior
= darwin_mourn_inferior
;
1272 darwin_ops
->to_kill
= darwin_kill_inferior
;
1273 darwin_ops
->to_stop
= darwin_stop
;
1274 darwin_ops
->to_resume
= darwin_resume
;
1275 darwin_ops
->to_thread_alive
= darwin_thread_alive
;
1276 darwin_ops
->to_pid_to_str
= darwin_pid_to_str
;
1277 darwin_ops
->to_load
= NULL
;
1278 darwin_ops
->deprecated_xfer_memory
= darwin_xfer_memory
;
1279 darwin_ops
->to_xfer_partial
= darwin_xfer_partial
;
1280 darwin_ops
->to_has_thread_control
= tc_schedlock
/*| tc_switch */;
1282 darwin_complete_target (darwin_ops
);
1284 add_target (darwin_ops
);
1286 inferior_debug (2, _("GDB task: 0x%lx, pid: %d\n"), mach_task_self (),
1289 add_setshow_zinteger_cmd ("darwin", class_obscure
,
1290 &darwin_debug_flag
, _("\
1291 Set if printing inferior communication debugging statements."), _("\
1292 Show if printing inferior communication debugging statements."), NULL
,
1294 &setdebuglist
, &showdebuglist
);
1296 add_setshow_boolean_cmd ("mach-exceptions", class_support
,
1297 &enable_mach_exceptions
, _("\
1298 Set if mach exceptions are caught."), _("\
1299 Show if mach exceptions are caught."), _("\
1300 When this mode is on, all low level exceptions are reported before being\n\
1301 reported by the kernel."),
1302 &set_enable_mach_exceptions
, NULL
,
1303 &setlist
, &showlist
);