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_mourn_inferior (struct target_ops
*ops
);
91 static int darwin_lookup_task (char *args
, task_t
* ptask
, int *ppid
);
93 static void darwin_kill_inferior (struct target_ops
*ops
);
95 static void darwin_ptrace_me (void);
97 static void darwin_ptrace_him (int pid
);
99 static void darwin_create_inferior (struct target_ops
*ops
, char *exec_file
,
100 char *allargs
, char **env
, int from_tty
);
102 static void darwin_files_info (struct target_ops
*ops
);
104 /* Current inferior. */
105 darwin_inferior
*darwin_inf
= NULL
;
107 /* Target operations for Darwin. */
108 static struct target_ops
*darwin_ops
;
110 /* Task identifier of gdb. */
111 static task_t gdb_task
;
113 /* A copy of mach_host_self (). */
114 mach_port_t darwin_host_self
;
116 /* Exception port. */
117 mach_port_t darwin_ex_port
;
119 /* Notification port. */
120 mach_port_t darwin_not_port
;
123 mach_port_t darwin_port_set
;
126 static vm_size_t mach_page_size
;
128 /* If Set, catch all mach exceptions (before they are converted to signals
130 static int enable_mach_exceptions
;
132 #define PAGE_TRUNC(x) ((x) & ~(mach_page_size - 1))
133 #define PAGE_ROUND(x) PAGE_TRUNC((x) + mach_page_size - 1)
135 /* Buffer containing received message and to be sent message. */
138 mach_msg_header_t hdr
;
142 /* Current message state.
143 If the kernel has sent a message it expects a reply and the inferior
144 can't be killed before. */
145 static enum msg_state
{ NO_MESSAGE
, GOT_MESSAGE
, REPLY_SENT
} msg_state
;
147 /* Unmarshalled received message. */
148 static struct exc_msg
153 /* Thread and task taking the exception. */
154 mach_port_t thread_port
;
155 mach_port_t task_port
;
157 /* Type of the exception. */
158 exception_type_t ex_type
;
160 /* Machine dependent details. */
161 mach_msg_type_number_t data_count
;
162 integer_t ex_data
[4];
166 /* This controls output of inferior debugging.
167 1 = basic exception handling
169 3 = thread management
170 4 = pending_event_handler
171 6 = most chatty level. */
173 static int darwin_debug_flag
= 0;
176 inferior_debug (int level
, const char *fmt
, ...)
180 if (darwin_debug_flag
< level
)
184 printf_unfiltered (_("[%d inferior]: "), getpid ());
185 vprintf_unfiltered (fmt
, ap
);
190 mach_check_error (kern_return_t ret
, const char *file
,
191 unsigned int line
, const char *func
)
193 if (ret
== KERN_SUCCESS
)
196 func
= _("[UNKNOWN]");
198 error (_("error on line %u of \"%s\" in function \"%s\": %s (0x%lx)\n"),
199 line
, file
, func
, mach_error_string (ret
), (unsigned long) ret
);
203 unparse_exception_type (unsigned int i
)
205 static char unknown_exception_buf
[32];
210 return "EXC_BAD_ACCESS";
211 case EXC_BAD_INSTRUCTION
:
212 return "EXC_BAD_INSTRUCTION";
214 return "EXC_ARITHMETIC";
216 return "EXC_EMULATION";
218 return "EXC_SOFTWARE";
220 return "EXC_BREAKPOINT";
222 return "EXC_SYSCALL";
223 case EXC_MACH_SYSCALL
:
224 return "EXC_MACH_SYSCALL";
226 return "EXC_RPC_ALERT";
230 snprintf (unknown_exception_buf
, 32, _("unknown (%d)"), i
);
231 return unknown_exception_buf
;
236 darwin_ptrace (const char *name
,
237 int request
, int pid
, PTRACE_TYPE_ARG3 arg3
, int arg4
)
241 ret
= ptrace (request
, pid
, (caddr_t
) arg3
, arg4
);
243 inferior_debug (2, _("ptrace (%s, %d, 0x%x, %d): %d (%s)\n"),
244 name
, pid
, arg3
, arg4
, ret
,
245 (ret
!= 0) ? safe_strerror (errno
) : _("no error"));
250 cmp_thread_t (const void *l
, const void *r
)
252 thread_t lt
= *(const thread_t
*)l
;
253 thread_t lr
= *(const thread_t
*)r
;
254 return (int)(lr
- lt
);
258 darwin_check_new_threads (darwin_inferior
*inf
)
262 thread_array_t thread_list
;
263 unsigned int new_nbr
;
264 unsigned int old_nbr
;
265 unsigned int new_ix
, old_ix
;
266 VEC (thread_t
) *thread_vec
;
268 /* Get list of threads. */
269 kret
= task_threads (inf
->task
, &thread_list
, &new_nbr
);
270 MACH_CHECK_ERROR (kret
);
271 if (kret
!= KERN_SUCCESS
)
275 qsort (thread_list
, new_nbr
, sizeof (thread_t
), cmp_thread_t
);
277 thread_vec
= VEC_alloc (thread_t
, new_nbr
);
280 old_nbr
= VEC_length (thread_t
, inf
->threads
);
284 for (new_ix
= 0, old_ix
= 0; new_ix
< new_nbr
|| old_ix
< old_nbr
;)
286 thread_t new_id
= (new_ix
< new_nbr
) ?
287 thread_list
[new_ix
] : THREAD_NULL
;
288 thread_t old_id
= (old_ix
< old_nbr
) ?
289 VEC_index (thread_t
, inf
->threads
, old_ix
) : THREAD_NULL
;
291 if (old_id
== new_id
)
293 /* Thread still exist. */
294 VEC_safe_push (thread_t
, thread_vec
, old_id
);
298 kret
= mach_port_deallocate (gdb_task
, old_id
);
299 MACH_CHECK_ERROR (kret
);
302 if (new_id
< old_id
|| old_ix
== old_nbr
)
304 /* A thread was created. */
305 struct thread_info
*tp
;
307 tp
= add_thread (ptid_build (inf
->pid
, 0, new_id
));
308 VEC_safe_push (thread_t
, thread_vec
, new_id
);
312 if (new_id
> old_id
|| new_ix
== new_nbr
)
314 /* A thread was removed. */
315 delete_thread (ptid_build (inf
->pid
, 0, old_id
));
316 kret
= mach_port_deallocate (gdb_task
, old_id
);
317 MACH_CHECK_ERROR (kret
);
323 VEC_free (thread_t
, inf
->threads
);
324 inf
->threads
= thread_vec
;
326 kret
= vm_deallocate (gdb_task
, (vm_address_t
) thread_list
,
327 new_nbr
* sizeof (int));
328 MACH_CHECK_ERROR (kret
);
332 darwin_stop (ptid_t t
)
336 ret
= kill (ptid_get_pid (inferior_ptid
), SIGINT
);
340 darwin_resume (struct target_ops
*ops
,
341 ptid_t ptid
, int step
, enum target_signal signal
)
343 struct target_waitstatus status
;
349 /* minus_one_ptid is RESUME_ALL. */
350 if (ptid_equal (ptid
, minus_one_ptid
))
351 ptid
= inferior_ptid
;
353 pid
= ptid_get_pid (ptid
);
354 thread
= ptid_get_tid (ptid
);
357 (2, _("darwin_resume: state=%d, thread=0x%x, step=%d signal=%d\n"),
358 msg_state
, thread
, step
, signal
);
363 switch (exc_msg
.ex_type
)
366 if (exc_msg
.ex_data
[0] == EXC_SOFT_SIGNAL
)
368 int nsignal
= target_signal_to_host (signal
);
369 res
= PTRACE (PT_THUPDATE
, pid
,
370 (void *)(uintptr_t)exc_msg
.thread_port
, nsignal
);
372 printf_unfiltered (_("ptrace THUP: res=%d\n"), res
);
382 inferior_debug (2, _("darwin_set_sstep (thread=%x, enable=%d)\n"),
384 darwin_set_sstep (thread
, step
);
387 kret
= mach_msg (&msgout
.hdr
, MACH_SEND_MSG
| MACH_SEND_INTERRUPT
,
388 msgout
.hdr
.msgh_size
, 0,
389 MACH_PORT_NULL
, MACH_MSG_TIMEOUT_NONE
,
392 printf_unfiltered (_("mach_msg (reply) ret=%d\n"), kret
);
394 msg_state
= REPLY_SENT
;
399 res
= PTRACE (PT_STEP
, pid
, (caddr_t
)1, 0);
401 res
= PTRACE (PT_CONTINUE
, pid
, (caddr_t
)1, 0);
410 catch_exception_raise_state
412 exception_type_t exception_type
, mach_exception_data_t exception_data
,
413 mach_msg_type_number_t data_count
, thread_state_flavor_t
* state_flavor
,
414 thread_state_t in_state
, mach_msg_type_number_t in_state_count
,
415 thread_state_t out_state
, mach_msg_type_number_t out_state_count
)
421 catch_exception_raise_state_identity
422 (mach_port_t port
, mach_port_t thread_port
, mach_port_t task_port
,
423 exception_type_t exception_type
, mach_exception_data_t exception_data
,
424 mach_msg_type_number_t data_count
, thread_state_flavor_t
* state_flavor
,
425 thread_state_t in_state
, mach_msg_type_number_t in_state_count
,
426 thread_state_t out_state
, mach_msg_type_number_t out_state_count
)
430 kret
= mach_port_deallocate (mach_task_self (), task_port
);
431 MACH_CHECK_ERROR (kret
);
432 kret
= mach_port_deallocate (mach_task_self (), thread_port
);
433 MACH_CHECK_ERROR (kret
);
439 catch_exception_raise (mach_port_t port
,
440 mach_port_t thread_port
,
441 mach_port_t task_port
,
442 exception_type_t exception_type
,
443 exception_data_t exception_data
,
444 mach_msg_type_number_t data_count
)
450 /* We got new rights to the task. Get rid of it. */
451 kret
= mach_port_deallocate (mach_task_self (), task_port
);
452 MACH_CHECK_ERROR (kret
);
455 (7, _("catch_exception_raise: exception_type=%d, data_count=%d\n"),
456 exception_type
, data_count
);
457 if (darwin_debug_flag
> 7)
459 for (i
= 0; i
< data_count
; i
++)
460 printf_unfiltered (" %08x", exception_data
[i
]);
461 printf_unfiltered ("\n");
465 FIXME: this should be in a per-thread variable. */
467 exc_msg
.thread_port
= thread_port
;
468 exc_msg
.task_port
= task_port
;
469 exc_msg
.ex_type
= exception_type
;
470 exc_msg
.data_count
= data_count
;
471 for (i
= 0; i
< data_count
&& i
< 4; i
++)
472 exc_msg
.ex_data
[i
] = exception_data
[i
];
478 darwin_wait (struct target_ops
*ops
,
479 ptid_t ptid
, struct target_waitstatus
*status
)
482 mach_msg_header_t
*hdr
= &msgin
.hdr
;
483 pid_t pid
= ptid_get_pid (inferior_ptid
); /* FIXME. */
485 gdb_assert (msg_state
!= GOT_MESSAGE
);
487 inferior_debug (6, _("darwin_wait: waiting for a message\n"));
489 /* Wait for a message. */
490 kret
= mach_msg (&msgin
.hdr
, MACH_RCV_MSG
| MACH_RCV_INTERRUPT
, 0,
491 sizeof (msgin
.data
), darwin_port_set
, 0, MACH_PORT_NULL
);
493 if (kret
== MACH_RCV_INTERRUPTED
)
495 status
->kind
= TARGET_WAITKIND_IGNORE
;
496 return minus_one_ptid
;
499 if (kret
!= MACH_MSG_SUCCESS
)
501 inferior_debug (1, _("mach_msg: ret=%x\n"), kret
);
502 status
->kind
= TARGET_WAITKIND_SPURIOUS
;
503 return minus_one_ptid
;
506 /* Debug: display message. */
507 if (darwin_debug_flag
> 10)
509 const unsigned long *buf
= (unsigned long *) hdr
;
512 printf_unfiltered (_(" bits: 0x%x"), hdr
->msgh_bits
);
513 printf_unfiltered (_(", size: 0x%x"), hdr
->msgh_size
);
514 printf_unfiltered (_(", remote-port: 0x%x"), hdr
->msgh_remote_port
);
515 printf_unfiltered (_(", local-port: 0x%x"), hdr
->msgh_local_port
);
516 printf_unfiltered (_(", reserved: 0x%x"), hdr
->msgh_reserved
);
517 printf_unfiltered (_(", id: 0x%x\n"), hdr
->msgh_id
);
519 if (darwin_debug_flag
> 11)
521 printf_unfiltered (_(" data:"));
522 for (i
= 0; i
< hdr
->msgh_size
; i
++)
523 printf_unfiltered (" %08lx", buf
[i
]);
524 printf_unfiltered (_("\n"));
528 /* Exception message. */
529 if (hdr
->msgh_local_port
== darwin_ex_port
)
531 /* Handle it via the exception server. */
532 if (!exc_server (&msgin
.hdr
, &msgout
.hdr
))
534 printf_unfiltered (_("exc_server: unknown message (id=%x)\n"),
536 status
->kind
= TARGET_WAITKIND_SPURIOUS
;
537 return minus_one_ptid
;
540 status
->kind
= TARGET_WAITKIND_STOPPED
;
542 inferior_debug (2, _("darwin_wait: thread=%x, got %s\n"),
544 unparse_exception_type (exc_msg
.ex_type
));
546 switch (exc_msg
.ex_type
)
549 status
->value
.sig
= TARGET_EXC_BAD_ACCESS
;
551 case EXC_BAD_INSTRUCTION
:
552 status
->value
.sig
= TARGET_EXC_BAD_INSTRUCTION
;
555 status
->value
.sig
= TARGET_EXC_ARITHMETIC
;
558 status
->value
.sig
= TARGET_EXC_EMULATION
;
561 if (exc_msg
.ex_data
[0] == EXC_SOFT_SIGNAL
)
563 status
->value
.sig
= target_signal_from_host (exc_msg
.ex_data
[1]);
564 inferior_debug (2, _(" (signal %d: %s)\n"),
566 target_signal_to_name (status
->value
.sig
));
569 status
->value
.sig
= TARGET_EXC_SOFTWARE
;
572 /* Many internal GDB routines expect breakpoints to be reported
573 as TARGET_SIGNAL_TRAP, and will report TARGET_EXC_BREAKPOINT
574 as a spurious signal. */
575 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
578 status
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
582 msg_state
= GOT_MESSAGE
;
584 return ptid_build (pid
, 0, exc_msg
.thread_port
);
586 else if (hdr
->msgh_local_port
== darwin_not_port
)
591 /* FIXME: translate task port to pid. */
592 res
= wait4 (pid
, &wstatus
, 0, NULL
);
595 printf_unfiltered (_("wait4: res=%x\n"), res
);
598 status
->kind
= TARGET_WAITKIND_EXITED
;
599 status
->value
.integer
= WEXITSTATUS (wstatus
);
601 inferior_debug (2, _("darwin_wait: pid=%d exit, status=%x\n"),
604 msg_state
= NO_MESSAGE
;
610 printf_unfiltered (_("Bad local-port: %x\n"), hdr
->msgh_local_port
);
611 status
->kind
= TARGET_WAITKIND_SPURIOUS
;
612 return minus_one_ptid
;
617 darwin_mourn_inferior (struct target_ops
*ops
)
619 struct inferior
*inf
= current_inferior ();
624 unpush_target (darwin_ops
);
626 /* Deallocate threads. */
627 if (darwin_inf
->threads
)
631 for (k
= 0; VEC_iterate (thread_t
, darwin_inf
->threads
, k
, t
); k
++)
633 kret
= mach_port_deallocate (gdb_task
, t
);
634 MACH_CHECK_ERROR (kret
);
636 VEC_free (thread_t
, darwin_inf
->threads
);
637 darwin_inf
->threads
= NULL
;
640 kret
= mach_port_request_notification (gdb_task
, darwin_inf
->task
,
641 MACH_NOTIFY_DEAD_NAME
, 0,
642 darwin_inf
->prev_not_port
,
643 MACH_MSG_TYPE_MAKE_SEND_ONCE
,
645 /* This can fail if the task is dead. */
646 if (kret
== KERN_SUCCESS
)
648 kret
= mach_port_deallocate (gdb_task
, prev
);
649 MACH_CHECK_ERROR (kret
);
652 /* Deallocate saved exception ports. */
653 for (i
= 0; i
< darwin_inf
->exception_info
.count
; i
++)
655 kret
= mach_port_deallocate
656 (gdb_task
, darwin_inf
->exception_info
.ports
[i
]);
657 MACH_CHECK_ERROR (kret
);
659 darwin_inf
->exception_info
.count
= 0;
661 kret
= mach_port_deallocate (gdb_task
, darwin_inf
->task
);
662 MACH_CHECK_ERROR (kret
);
664 darwin_inf
->task
= 0;
667 generic_mourn_inferior ();
671 darwin_stop_inferior (struct target_ops
*ops
, darwin_inferior
*inf
)
673 struct target_waitstatus wstatus
;
679 gdb_assert (inf
!= NULL
);
681 kret
= task_suspend (inf
->task
);
682 MACH_CHECK_ERROR (kret
);
684 if (msg_state
== GOT_MESSAGE
)
685 darwin_resume (darwin_ops
, inferior_ptid
, 0, 0);
687 res
= kill (inf
->pid
, SIGSTOP
);
689 warning (_("cannot kill: %s\n"), safe_strerror (errno
));
691 ptid
= darwin_wait (ops
, inferior_ptid
, &wstatus
);
692 gdb_assert (wstatus
.kind
= TARGET_WAITKIND_STOPPED
);
696 darwin_kill_inferior (struct target_ops
*ops
)
698 struct target_waitstatus wstatus
;
704 gdb_assert (darwin_inf
!= NULL
);
706 if (ptid_equal (inferior_ptid
, null_ptid
))
709 darwin_stop_inferior (ops
, darwin_inf
);
711 res
= PTRACE (PT_KILL
, darwin_inf
->pid
, 0, 0);
712 gdb_assert (res
== 0);
714 if (msg_state
== GOT_MESSAGE
)
717 darwin_resume (ops
, inferior_ptid
, 0, 0);
720 kret
= task_resume (darwin_inf
->task
);
721 MACH_CHECK_ERROR (kret
);
723 ptid
= darwin_wait (ops
, inferior_ptid
, &wstatus
);
725 /* This double wait seems required... */
726 res
= waitpid (darwin_inf
->pid
, &status
, 0);
727 gdb_assert (res
== darwin_inf
->pid
);
729 msg_state
= NO_MESSAGE
;
731 target_mourn_inferior ();
734 /* The child must synchronize with gdb: gdb must set the exception port
735 before the child call PTRACE_SIGEXC. We use a pipe to achieve this.
736 FIXME: is there a lighter way ? */
737 static int ptrace_fds
[2];
740 darwin_ptrace_me (void)
745 /* Close write end point. */
746 close (ptrace_fds
[1]);
748 /* Wait until gdb is ready. */
749 res
= read (ptrace_fds
[0], &c
, 1);
750 gdb_assert (res
== 0);
751 close (ptrace_fds
[0]);
753 /* Get rid of privileges. */
757 PTRACE (PT_TRACE_ME
, 0, 0, 0);
759 /* Redirect signals to exception port. */
760 PTRACE (PT_SIGEXC
, 0, 0, 0);
763 /* Dummy function to be sure fork_inferior uses fork(2) and not vfork(2). */
765 darwin_pre_ptrace (void)
767 if (pipe (ptrace_fds
) != 0)
771 error (_("unable to create a pipe: %s"), safe_strerror (errno
));
776 darwin_save_exception_ports (darwin_inferior
*inf
)
780 inf
->exception_info
.count
=
781 sizeof (inf
->exception_info
.ports
) / sizeof (inf
->exception_info
.ports
[0]);
783 kret
= task_get_exception_ports
784 (inf
->task
, EXC_MASK_ALL
, inf
->exception_info
.masks
,
785 &inf
->exception_info
.count
, inf
->exception_info
.ports
,
786 inf
->exception_info
.behaviors
, inf
->exception_info
.flavors
);
791 darwin_restore_exception_ports (darwin_inferior
*inf
)
796 for (i
= 0; i
< inf
->exception_info
.count
; i
++)
798 kret
= task_set_exception_ports
799 (inf
->task
, inf
->exception_info
.masks
[i
], inf
->exception_info
.ports
[i
],
800 inf
->exception_info
.behaviors
[i
], inf
->exception_info
.flavors
[i
]);
801 if (kret
!= KERN_SUCCESS
)
809 darwin_attach_pid (int pid
)
813 mach_port_t prev_port
;
815 exception_mask_t mask
;
817 kret
= task_for_pid (gdb_task
, pid
, &itask
);
818 if (kret
!= KERN_SUCCESS
)
821 struct inferior
*inf
= current_inferior ();
823 if (!inf
->attach_flag
)
826 waitpid (pid
, &status
, 0);
829 error (_("Unable to find Mach task port for process-id %d: %s (0x%lx).\n"
830 " (please check gdb is setgid procmod)"),
831 pid
, mach_error_string (kret
), (unsigned long) kret
);
834 inferior_debug (2, _("inferior task: 0x%08x, pid: %d\n"), itask
, pid
);
836 if (darwin_ex_port
== MACH_PORT_NULL
)
838 /* Create a port to get exceptions. */
839 kret
= mach_port_allocate (gdb_task
, MACH_PORT_RIGHT_RECEIVE
,
841 gdb_assert (kret
== KERN_SUCCESS
);
843 kret
= mach_port_insert_right (gdb_task
, darwin_ex_port
, darwin_ex_port
,
844 MACH_MSG_TYPE_MAKE_SEND
);
845 gdb_assert (kret
== KERN_SUCCESS
);
847 /* Create a port set and put ex_port in it. */
848 kret
= mach_port_allocate (gdb_task
, MACH_PORT_RIGHT_PORT_SET
,
850 gdb_assert (kret
== KERN_SUCCESS
);
852 kret
= mach_port_move_member (gdb_task
, darwin_ex_port
, darwin_port_set
);
853 gdb_assert (kret
== KERN_SUCCESS
);
855 /* Create a port to be notified when the child task terminates. */
856 kret
= mach_port_allocate (gdb_task
, MACH_PORT_RIGHT_RECEIVE
,
858 gdb_assert (kret
== KERN_SUCCESS
);
860 kret
= mach_port_insert_right (gdb_task
, darwin_not_port
, darwin_not_port
,
861 MACH_MSG_TYPE_MAKE_SEND
);
862 gdb_assert (kret
== KERN_SUCCESS
);
864 kret
= mach_port_move_member (gdb_task
, darwin_not_port
, darwin_port_set
);
865 gdb_assert (kret
== KERN_SUCCESS
);
868 kret
= mach_port_request_notification (gdb_task
, itask
,
869 MACH_NOTIFY_DEAD_NAME
, 0,
871 MACH_MSG_TYPE_MAKE_SEND_ONCE
,
872 &darwin_inf
->prev_not_port
);
873 gdb_assert (kret
== KERN_SUCCESS
);
875 darwin_inf
->task
= itask
;
876 darwin_inf
->pid
= pid
;
878 kret
= darwin_save_exception_ports (darwin_inf
);
879 gdb_assert (kret
== KERN_SUCCESS
);
881 /* Set exception port. */
882 if (enable_mach_exceptions
)
885 mask
= EXC_MASK_SOFTWARE
;
886 kret
= task_set_exception_ports
887 (itask
, mask
, darwin_ex_port
, EXCEPTION_DEFAULT
, THREAD_STATE_NONE
);
888 gdb_assert (kret
== KERN_SUCCESS
);
890 push_target (darwin_ops
);
894 darwin_init_thread_list (darwin_inferior
*inf
)
898 darwin_check_new_threads (inf
);
900 gdb_assert (inf
->threads
&& VEC_length (thread_t
, inf
->threads
) > 0);
901 thread
= VEC_index (thread_t
, inf
->threads
, 0);
902 inferior_ptid
= ptid_build (inf
->pid
, 0, thread
);
906 darwin_ptrace_him (int pid
)
910 mach_port_t prev_port
;
913 darwin_attach_pid (pid
);
915 /* Let's the child run. */
916 close (ptrace_fds
[0]);
917 close (ptrace_fds
[1]);
919 /* fork_inferior automatically add a thread - but it uses a wrong tid. */
920 delete_thread_silent (inferior_ptid
);
921 darwin_init_thread_list (darwin_inf
);
923 startup_inferior (START_INFERIOR_TRAPS_EXPECTED
);
927 darwin_create_inferior (struct target_ops
*ops
, char *exec_file
,
928 char *allargs
, char **env
, int from_tty
)
930 /* Do the hard work. */
931 fork_inferior (exec_file
, allargs
, env
, darwin_ptrace_me
, darwin_ptrace_him
,
932 darwin_pre_ptrace
, NULL
);
934 /* Return now in case of error. */
935 if (ptid_equal (inferior_ptid
, null_ptid
))
940 /* Attach to process PID, then initialize for debugging it
941 and wait for the trace-trap that results from attaching. */
943 darwin_attach (struct target_ops
*ops
, char *args
, int from_tty
)
949 struct inferior
*inf
;
951 gdb_assert (msg_state
== NO_MESSAGE
);
954 error_no_arg (_("process-id to attach"));
958 if (pid
== getpid ()) /* Trying to masturbate? */
959 error (_("I refuse to debug myself!"));
962 printf_unfiltered (_("Attaching to pid %d\n"), pid
);
964 res
= PTRACE (PT_ATTACHEXC
, pid
, 0, 0);
966 error (_("Unable to attach to process-id %d: %s (%d)"),
967 pid
, safe_strerror (errno
), errno
);
969 inf
= add_inferior (pid
);
970 inf
->attach_flag
= 1;
972 darwin_attach_pid (pid
);
974 pid2
= wait4 (pid
, &wstatus
, WUNTRACED
, NULL
);
975 gdb_assert (pid2
== pid
);
976 inferior_debug (1, _("darwin_attach: wait4 pid=%d, status=0x%x\n"),
980 darwin_init_thread_list (darwin_inf
);
982 darwin_check_osabi (darwin_inf
, ptid_get_tid (inferior_ptid
));
984 /* Looks strange, but the kernel doesn't stop the process...
987 /* FIXME: doesn't look to work with multi-threads!! */
991 /* Take a program previously attached to and detaches it.
992 The program resumes execution and will no longer stop
993 on signals, etc. We'd better not have left any breakpoints
994 in the program or it'll die when it hits one. For this
995 to work, it may be necessary for the process to have been
996 previously attached. It *might* work if the program was
999 darwin_detach (struct target_ops
*ops
, char *args
, int from_tty
)
1006 char *exec_file
= get_exec_file (0);
1009 printf_unfiltered (_("Detaching from program: %s, %d\n"), exec_file
,
1010 ptid_get_pid (inferior_ptid
));
1011 gdb_flush (gdb_stdout
);
1014 darwin_stop_inferior (ops
, darwin_inf
);
1016 kret
= darwin_restore_exception_ports (darwin_inf
);
1017 MACH_CHECK_ERROR (kret
);
1019 if (msg_state
== GOT_MESSAGE
)
1021 exc_msg
.ex_type
= 0;
1022 darwin_resume (ops
, inferior_ptid
, 0, 0);
1025 kret
= task_resume (darwin_inf
->task
);
1026 gdb_assert (kret
== KERN_SUCCESS
);
1028 res
= PTRACE (PT_DETACH
, darwin_inf
->pid
, 0, 0);
1030 printf_unfiltered (_("Unable to detach from process-id %d: %s (%d)"),
1031 darwin_inf
->pid
, safe_strerror (errno
), errno
);
1033 msg_state
= NO_MESSAGE
;
1035 darwin_mourn_inferior (ops
);
1039 darwin_files_info (struct target_ops
*ops
)
1041 gdb_assert (darwin_inf
!= NULL
);
1045 darwin_pid_to_str (struct target_ops
*ops
, ptid_t ptid
)
1047 static char buf
[128];
1049 snprintf (buf
, sizeof (buf
),
1050 _("process %d gdb-thread 0x%lx"),
1051 (unsigned) ptid_get_pid (ptid
),
1052 (unsigned long) ptid_get_tid (ptid
));
1057 darwin_thread_alive (struct target_ops
*ops
, ptid_t ptid
)
1062 /* If RDADDR is not NULL, read inferior task's LEN bytes from ADDR and
1063 copy it to RDADDR in gdb's address space.
1064 If WRADDR is not NULL, write gdb's LEN bytes from WRADDR and copy it
1065 to ADDR in inferior task's address space.
1066 Return 0 on failure; number of bytes read / writen otherwise. */
1068 darwin_read_write_inferior (task_t task
, CORE_ADDR addr
,
1069 char *rdaddr
, const char *wraddr
, int length
)
1072 mach_vm_address_t offset
= addr
& (mach_page_size
- 1);
1073 mach_vm_address_t low_address
= (mach_vm_address_t
) (addr
- offset
);
1074 mach_vm_size_t aligned_length
= (mach_vm_size_t
) PAGE_ROUND (offset
+ length
);
1077 mach_vm_size_t remaining_length
;
1078 mach_vm_address_t region_address
;
1079 mach_vm_size_t region_length
;
1081 inferior_debug (8, _("darwin_read_write_inferior(%s, len=%d)\n"),
1082 core_addr_to_string (addr
), length
);
1084 /* Get memory from inferior with page aligned addresses */
1085 err
= mach_vm_read (task
, low_address
, aligned_length
,
1086 &copied
, ©_count
);
1087 if (err
!= KERN_SUCCESS
)
1089 warning (_("darwin_read_write_inferior: vm_read failed: %s"),
1090 mach_error_string (err
));
1095 memcpy (rdaddr
, (char *)copied
+ offset
, length
);
1100 memcpy ((char *)copied
+ offset
, wraddr
, length
);
1102 /* Do writes atomically.
1103 First check for holes and unwritable memory. */
1104 for (region_address
= low_address
, remaining_length
= aligned_length
;
1105 region_address
< low_address
+ aligned_length
;
1106 region_address
+= region_length
, remaining_length
-= region_length
)
1108 vm_region_basic_info_data_64_t info
;
1109 mach_port_t object_name
;
1110 mach_vm_address_t old_address
= region_address
;
1111 mach_msg_type_number_t count
;
1113 region_length
= remaining_length
;
1114 count
= VM_REGION_BASIC_INFO_COUNT_64
;
1115 err
= mach_vm_region (task
, ®ion_address
, ®ion_length
,
1116 VM_REGION_BASIC_INFO_64
,
1117 (vm_region_info_t
) &info
, &count
, &object_name
);
1119 if (err
!= KERN_SUCCESS
)
1121 warning (_("darwin_write_inferior: mach_vm_region failed: %s"),
1122 mach_error_string (err
));
1126 /* Check for holes in memory */
1127 if (region_address
> old_address
)
1129 warning (_("No memory at %s (vs %s+0x%x). Nothing written"),
1130 core_addr_to_string (old_address
),
1131 core_addr_to_string (region_address
),
1132 (unsigned)region_length
);
1137 if (!(info
.max_protection
& VM_PROT_WRITE
))
1139 warning (_("Memory at address %s is unwritable. Nothing written"),
1140 core_addr_to_string (old_address
));
1145 if (!(info
.protection
& VM_PROT_WRITE
))
1147 err
= mach_vm_protect (task
, old_address
, region_length
,
1148 FALSE
, info
.protection
| VM_PROT_WRITE
);
1149 if (err
!= KERN_SUCCESS
)
1152 (_("darwin_read_write_inferior: mach_vm_protect failed: %s"),
1153 mach_error_string (err
));
1160 err
= mach_vm_write (task
, low_address
, copied
, aligned_length
);
1162 if (err
!= KERN_SUCCESS
)
1164 warning (_("darwin_read_write_inferior: mach_vm_write failed: %s"),
1165 mach_error_string (err
));
1169 mach_vm_deallocate (mach_task_self (), copied
, copy_count
);
1174 /* Return 0 on failure, number of bytes handled otherwise. TARGET
1177 darwin_xfer_memory (CORE_ADDR memaddr
, gdb_byte
*myaddr
, int len
, int write
,
1178 struct mem_attrib
*attrib
, struct target_ops
*target
)
1180 task_t task
= darwin_inf
->task
;
1182 if (task
== MACH_PORT_NULL
)
1185 inferior_debug (8, _("darwin_xfer_memory(%s, %d, %c)\n"),
1186 core_addr_to_string (memaddr
), len
, write
? 'w' : 'r');
1189 return darwin_read_write_inferior (task
, memaddr
, NULL
, myaddr
, len
);
1191 return darwin_read_write_inferior (task
, memaddr
, myaddr
, NULL
, len
);
1195 darwin_xfer_partial (struct target_ops
*ops
,
1196 enum target_object object
, const char *annex
,
1197 gdb_byte
*readbuf
, const gdb_byte
*writebuf
,
1198 ULONGEST offset
, LONGEST len
)
1200 inferior_debug (8, _("darwin_xfer_partial(%s, %d, rbuf=%p, wbuf=%p)\n"),
1201 core_addr_to_string (offset
), (int)len
, readbuf
, writebuf
);
1203 if (object
!= TARGET_OBJECT_MEMORY
)
1206 return darwin_read_write_inferior (darwin_inf
->task
, offset
,
1207 readbuf
, writebuf
, len
);
1211 set_enable_mach_exceptions (char *args
, int from_tty
,
1212 struct cmd_list_element
*c
)
1214 if (darwin_inf
&& darwin_inf
->task
!= TASK_NULL
)
1216 exception_mask_t mask
;
1219 if (enable_mach_exceptions
)
1220 mask
= EXC_MASK_ALL
;
1223 darwin_restore_exception_ports (darwin_inf
);
1224 mask
= EXC_MASK_SOFTWARE
;
1226 kret
= task_set_exception_ports (darwin_inf
->task
, mask
, darwin_ex_port
,
1227 EXCEPTION_DEFAULT
, THREAD_STATE_NONE
);
1228 MACH_CHECK_ERROR (kret
);
1233 _initialize_darwin_inferior ()
1237 gdb_assert (darwin_inf
== NULL
);
1239 gdb_task
= mach_task_self ();
1240 darwin_host_self
= mach_host_self ();
1242 /* Read page size. */
1243 kret
= host_page_size (darwin_host_self
, &mach_page_size
);
1244 if (kret
!= KERN_SUCCESS
)
1246 mach_page_size
= 0x1000;
1247 MACH_CHECK_ERROR (kret
);
1250 darwin_inf
= (struct darwin_inferior
*)
1251 xmalloc (sizeof (struct darwin_inferior
));
1253 memset (darwin_inf
, 0, sizeof (*darwin_inf
));
1255 darwin_ops
= inf_child_target ();
1257 darwin_ops
->to_shortname
= "darwin-child";
1258 darwin_ops
->to_longname
= _("Darwin child process");
1259 darwin_ops
->to_doc
=
1260 _("Darwin child process (started by the \"run\" command).");
1261 darwin_ops
->to_create_inferior
= darwin_create_inferior
;
1262 darwin_ops
->to_attach
= darwin_attach
;
1263 darwin_ops
->to_attach_no_wait
= 0;
1264 darwin_ops
->to_detach
= darwin_detach
;
1265 darwin_ops
->to_files_info
= darwin_files_info
;
1266 darwin_ops
->to_wait
= darwin_wait
;
1267 darwin_ops
->to_mourn_inferior
= darwin_mourn_inferior
;
1268 darwin_ops
->to_kill
= darwin_kill_inferior
;
1269 darwin_ops
->to_stop
= darwin_stop
;
1270 darwin_ops
->to_resume
= darwin_resume
;
1271 darwin_ops
->to_thread_alive
= darwin_thread_alive
;
1272 darwin_ops
->to_pid_to_str
= darwin_pid_to_str
;
1273 darwin_ops
->to_load
= NULL
;
1274 darwin_ops
->deprecated_xfer_memory
= darwin_xfer_memory
;
1275 darwin_ops
->to_xfer_partial
= darwin_xfer_partial
;
1276 darwin_ops
->to_has_thread_control
= tc_schedlock
/*| tc_switch */;
1278 darwin_complete_target (darwin_ops
);
1280 add_target (darwin_ops
);
1282 inferior_debug (2, _("GDB task: 0x%lx, pid: %d\n"), mach_task_self (),
1285 add_setshow_zinteger_cmd ("darwin", class_obscure
,
1286 &darwin_debug_flag
, _("\
1287 Set if printing inferior communication debugging statements."), _("\
1288 Show if printing inferior communication debugging statements."), NULL
,
1290 &setdebuglist
, &showdebuglist
);
1292 add_setshow_boolean_cmd ("mach-exceptions", class_support
,
1293 &enable_mach_exceptions
, _("\
1294 Set if mach exceptions are caught."), _("\
1295 Show if mach exceptions are caught."), _("\
1296 When this mode is on, all low level exceptions are reported before being\n\
1297 reported by the kernel."),
1298 &set_enable_mach_exceptions
, NULL
,
1299 &setlist
, &showlist
);