From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 130687 invoked by alias); 3 Nov 2016 22:05:19 -0000 Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org Received: (qmail 130671 invoked by uid 89); 3 Nov 2016 22:05:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.3.2 spammy=Jenkins, *inf, 104714, (unknown) X-HELO: mail.scootersoftware.com Received: from mail.scootersoftware.com (HELO mail.scootersoftware.com) (96.61.63.92) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 03 Nov 2016 22:05:17 +0000 X-MDAV-Result: clean X-MDAV-Processed: mail.scootersoftware.com, Thu, 03 Nov 2016 17:05:15 -0500 Received: from [x.x.x.x] by mail.scootersoftware.com (Cipher TLSv1.2:AES-SHA:256) (MDaemon PRO v16.0.4) with ESMTPSA id md50001979279.msg for ; Thu, 03 Nov 2016 17:05:15 -0500 X-Spam-Processed: mail.scootersoftware.com, Thu, 03 Nov 2016 17:05:15 -0500 (not processed: message from trusted or authenticated source) X-MDArrival-Date: Thu, 03 Nov 2016 17:05:15 -0500 X-Return-Path: prvs=1115785d4f=david@scootersoftware.com X-Envelope-From: david@scootersoftware.com X-MDaemon-Deliver-To: gdb@sourceware.org To: gdb@sourceware.org From: David Jenkins Subject: Re: gdb on macOS 10.12 "Sierra" Message-ID: <7638e6c3-2efd-1d07-10ef-d467b1a68352@scootersoftware.com> Date: Thu, 03 Nov 2016 22:05:00 -0000 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2016-11/txt/msg00004.txt.bz2 I can confirm that refreshing the task port after exec does allow gdb to work. Here is a patch that I made against 7.12 that allows gdb to run on Sierra. I cannot speak to the complete quality of the patch as this is my first dive into gdb code. We just starting using the patched gdb and it does allows us to break, step, and view variables in the Lazarus IDE. Patch is inlined below David Jenkins Scooter Software --- gdb-7.12/gdb/darwin-nat.c 2016-10-07 12:09:21.000000000 -0500 +++ gdb-7.12-dfj/gdb/darwin-nat.c 2016-11-03 15:56:49.000000000 -0500 @@ -171,6 +171,9 @@ "\n" "\n"; +static kern_return_t darwin_save_exception_ports (darwin_inferior *inf); +static kern_return_t darwin_restore_exception_ports (darwin_inferior *inf); + static void inferior_debug (int level, const char *fmt, ...) ATTRIBUTE_PRINTF (2, 3); @@ -401,6 +404,12 @@ } static int +find_inferior_pid_it (struct inferior *inf, void *pid_ptr) +{ + return inf->pid == *(int *)pid_ptr; +} + +static int find_inferior_task_it (struct inferior *inf, void *port_ptr) { return inf->priv->task == *(task_t*)port_ptr; @@ -412,6 +421,13 @@ return inf->priv->notify_port == *(task_t*)port_ptr; } +/* Return an inferior by pid. */ +static struct inferior * +darwin_find_inferior_by_pid (int pid) +{ + return iterate_over_inferiors (&find_inferior_pid_it, &pid); +} + /* Return an inferior by task port. */ static struct inferior * darwin_find_inferior_by_task (task_t port) @@ -572,6 +588,7 @@ thread_t thread_port; kern_return_t kret; int i; + int task_pid; /* Check message destination. */ if (hdr->msgh_local_port != darwin_ex_port) @@ -606,6 +623,7 @@ task_port = desc[1].name; thread_port = desc[0].name; + pid_for_task(task_port, &task_pid); /* We got new rights to the task, get rid of it. Do not get rid of thread right, as we will need it to find the thread. */ @@ -617,25 +635,61 @@ *pinf = inf; if (inf == NULL) { - /* Not a known inferior. This could happen if the child fork, as - the created process will inherit its exception port. - FIXME: should the exception port be restored ? */ - kern_return_t kret; - mig_reply_error_t reply; + if MACH_PORT_VALID(task_port) + { + //int task_pid; + mach_port_name_t new_task; + mach_port_t prev_not; + exception_mask_t mask; + + inf = darwin_find_inferior_by_pid(task_pid); + if (inf == NULL) + return 0; - /* Free thread port (we don't know it). */ - kret = mach_port_deallocate (mach_task_self (), thread_port); - MACH_CHECK_ERROR (kret); + kret = mach_port_deallocate (mach_task_self (), inf->priv->task); + MACH_CHECK_ERROR (kret); - darwin_encode_reply (&reply, hdr, KERN_SUCCESS); + task_for_pid(gdb_task, task_pid, &new_task); - kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT, - reply.Head.msgh_size, 0, - MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, - MACH_PORT_NULL); - MACH_CHECK_ERROR (kret); + inf->priv->task = new_task; + *pinf = inf; + + mach_port_request_notification (gdb_task, inf->priv->task, + MACH_NOTIFY_DEAD_NAME, 0, + inf->priv->notify_port, + MACH_MSG_TYPE_MAKE_SEND_ONCE, + &prev_not); + + darwin_restore_exception_ports(inf->priv); + if (enable_mach_exceptions) + mask = EXC_MASK_ALL; + else + mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT; + task_set_exception_ports (inf->priv->task, mask, darwin_ex_port, + EXCEPTION_DEFAULT, THREAD_STATE_NONE); + } + else + { + /* Not a known inferior. This could happen if the child fork, as + the created process will inherit its exception port. + FIXME: should the exception port be restored ? */ + kern_return_t kret; + mig_reply_error_t reply; + + /* Free thread port (we don't know it). */ + kret = mach_port_deallocate (mach_task_self (), thread_port); + MACH_CHECK_ERROR (kret); - return 0; + darwin_encode_reply (&reply, hdr, KERN_SUCCESS); + + kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT, + reply.Head.msgh_size, 0, + MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, + MACH_PORT_NULL); + MACH_CHECK_ERROR (kret); + + return 0; + } } /* Find thread by port. */ @@ -900,6 +954,7 @@ { darwin_thread_t *thread; struct inferior *inf; + /* Exception message. 2401 == 0x961 is exc. */ if (hdr->msgh_id == 2401) @@ -992,6 +1047,14 @@ inf = darwin_find_inferior_by_notify (hdr->msgh_local_port); if (inf != NULL) { + mach_dead_name_notification_t *notif; + mach_port_t dead_port; + + notif = (mach_dead_name_notification_t *)(hdr); + dead_port = notif->not_port; + if (dead_port != inf->priv->task) + return ptid_build (inf->pid, 0, 0); + if (!inf->priv->no_ptrace) { pid_t res;