From patchwork Tue Apr 1 10:03:56 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tristan Gingold X-Patchwork-Id: 366 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx22.g.dreamhost.com (mx2.sub5.homie.mail.dreamhost.com [208.113.200.128]) by wilcox.dreamhost.com (Postfix) with ESMTP id 61BAD3600DB for ; Tue, 1 Apr 2014 03:04:03 -0700 (PDT) Received: by homiemail-mx22.g.dreamhost.com (Postfix, from userid 14314964) id 1BDE144B28A6; Tue, 1 Apr 2014 03:04:03 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx22.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx22.g.dreamhost.com (Postfix) with ESMTPS id E2CCB44B289C for ; Tue, 1 Apr 2014 03:04:02 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:content-type:content-transfer-encoding :subject:message-id:date:to:mime-version; q=dns; s=default; b=de EyH9PXx6vYaA/1o72/eUd/MWNqKP9gRkGAvWDmQb1Te1EInENmAs20ib1P+MgUkb n9SC0KorF7tmEk0mEtjLsk0muOn2nBlJjtYqvKUz/9LALoZHIG5aWjhm/GuM2CmI I7H4dL1ap3WXV0eX6SW8UUIr3ZgvYvZb4AHJKJIKY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:content-type:content-transfer-encoding :subject:message-id:date:to:mime-version; s=default; bh=qThuryGQ wtGBN4tFxVElfKtf1n4=; b=PnYpjAmaWLZan7dX+qT4dn27DtR0orV/gP2hdsLi ewlGAn199FacthNONv0gm3ubY1zUrPZxp/LvOn3G9DBtvMQSF6TOvzErVXP3vIQX 7Ru76j8CBJ+rMZb5g7lkQet7xOaV2DebjDEjFuSnVv1VacjD6r8MEOzWn7ia+k5j nBA= Received: (qmail 6313 invoked by alias); 1 Apr 2014 10:04:01 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 6299 invoked by uid 89); 1 Apr 2014 10:04:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 01 Apr 2014 10:03:58 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 1D5FF2720052 for ; Tue, 1 Apr 2014 12:03:56 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qLPz5K8DgFS5 for ; Tue, 1 Apr 2014 12:03:56 +0200 (CEST) Received: from ulanbator.act-europe.fr (ulanbator.act-europe.fr [10.10.1.67]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 0508D2720006 for ; Tue, 1 Apr 2014 12:03:55 +0200 (CEST) From: Tristan Gingold Subject: [Darwin]: Avoid a crash while debugging gdb Message-Id: <572D6E22-DC6F-4631-AB4B-C996B341B175@adacore.com> Date: Tue, 1 Apr 2014 12:03:56 +0200 To: " ml" Mime-Version: 1.0 (Mac OS X Mail 7.2 \(1874\)) X-IsSubscribed: yes X-DH-Original-To: gdb@patchwork.siddhesh.in Hi, it is possible that gdb gets mach exceptions from an unknown inferior. This happens when an inferior creates a child and that child gets a signal. So instead of reporting messages with unknown origins, simply reply to these notifications. The kernel will then post the unix signal. Committed on trunk. Tristan. gdb/ * darwin-nat.c (darwin_encode_reply): Add prototype. (darwin_decode_exception_message): Reply to unknown inferiors. (darwin_decode_message): Handle message by id. Ignore message to unknown inferior. (darwin_wait): Discard unknown messages, add debug trace. diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c index 3ea9696..3ce599c 100644 --- a/gdb/darwin-nat.c +++ b/gdb/darwin-nat.c @@ -113,6 +113,9 @@ static char *darwin_pid_to_str (struct target_ops *ops, ptid_t tpid); static int darwin_thread_alive (struct target_ops *ops, ptid_t tpid); +static void darwin_encode_reply (mig_reply_error_t *reply, + mach_msg_header_t *hdr, integer_t code); + /* Target operations for Darwin. */ static struct target_ops *darwin_ops; @@ -557,8 +560,8 @@ darwin_decode_exception_message (mach_msg_header_t *hdr, kern_return_t kret; int i; - /* Check message identifier. 2401 == 0x961 is exc. */ - if (hdr->msgh_id != 2401) + /* Check message identifier. */ + if (hdr->msgh_local_port != darwin_ex_port) return -1; /* Check message header. */ @@ -588,25 +591,42 @@ darwin_decode_exception_message (mach_msg_header_t *hdr, /* Ok, the hard work. */ data = (integer_t *)(ndr + 1); - /* Find process by port. */ task_port = desc[1].name; thread_port = desc[0].name; + + /* We got new rights to the task and the thread. Get rid of them. */ + kret = mach_port_deallocate (mach_task_self (), task_port); + MACH_CHECK_ERROR (kret); + kret = mach_port_deallocate (mach_task_self (), thread_port); + MACH_CHECK_ERROR (kret); + + /* Find process by port. */ inf = darwin_find_inferior_by_task (task_port); - if (inf == NULL) - return -1; *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; + + 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. */ /* Check for new threads. Do it early so that the port in the exception message can be deallocated. */ darwin_check_new_threads (inf); - /* We got new rights to the task and the thread. Get rid of them. */ - kret = mach_port_deallocate (mach_task_self (), task_port); - MACH_CHECK_ERROR (kret); - kret = mach_port_deallocate (mach_task_self (), thread_port); - MACH_CHECK_ERROR (kret); - thread = darwin_find_thread (inf, thread_port); if (thread == NULL) return -1; @@ -863,8 +883,8 @@ darwin_decode_message (mach_msg_header_t *hdr, darwin_thread_t *thread; struct inferior *inf; - /* Exception message. */ - if (hdr->msgh_local_port == darwin_ex_port) + /* Exception message. 2401 == 0x961 is exc. */ + if (hdr->msgh_id == 2401) { int res; @@ -877,7 +897,12 @@ darwin_decode_message (mach_msg_header_t *hdr, printf_unfiltered (_("darwin_wait: ill-formatted message (id=0x%x)\n"), hdr->msgh_id); /* FIXME: send a failure reply? */ - status->kind = TARGET_WAITKIND_SPURIOUS; + status->kind = TARGET_WAITKIND_IGNORE; + return minus_one_ptid; + } + if (inf == NULL) + { + status->kind = TARGET_WAITKIND_IGNORE; return minus_one_ptid; } *pinf = inf; @@ -940,56 +965,60 @@ darwin_decode_message (mach_msg_header_t *hdr, return ptid_build (inf->pid, 0, thread->gdb_port); } - - *pinf = NULL; - *pthread = NULL; - - inf = darwin_find_inferior_by_notify (hdr->msgh_local_port); - if (inf != NULL) + else if (hdr->msgh_id == 0x48) { - if (!inf->private->no_ptrace) - { - pid_t res; - int wstatus; + /* MACH_NOTIFY_DEAD_NAME: notification for exit. */ + *pinf = NULL; + *pthread = NULL; - res = wait4 (inf->pid, &wstatus, 0, NULL); - if (res < 0 || res != inf->pid) - { - printf_unfiltered (_("wait4: res=%d: %s\n"), - res, safe_strerror (errno)); - status->kind = TARGET_WAITKIND_SPURIOUS; - return minus_one_ptid; - } - if (WIFEXITED (wstatus)) + inf = darwin_find_inferior_by_notify (hdr->msgh_local_port); + if (inf != NULL) + { + if (!inf->private->no_ptrace) { - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = WEXITSTATUS (wstatus); + pid_t res; + int wstatus; + + res = wait4 (inf->pid, &wstatus, 0, NULL); + if (res < 0 || res != inf->pid) + { + printf_unfiltered (_("wait4: res=%d: %s\n"), + res, safe_strerror (errno)); + status->kind = TARGET_WAITKIND_IGNORE; + return minus_one_ptid; + } + if (WIFEXITED (wstatus)) + { + status->kind = TARGET_WAITKIND_EXITED; + status->value.integer = WEXITSTATUS (wstatus); + } + else + { + status->kind = TARGET_WAITKIND_SIGNALLED; + status->value.sig = WTERMSIG (wstatus); + } + + inferior_debug (4, _("darwin_wait: pid=%d exit, status=0x%x\n"), + res, wstatus); + + /* Looks necessary on Leopard and harmless... */ + wait4 (inf->pid, &wstatus, 0, NULL); + + return ptid_build (inf->pid, 0, 0); } else { - status->kind = TARGET_WAITKIND_SIGNALLED; - status->value.sig = WTERMSIG (wstatus); + inferior_debug (4, _("darwin_wait: pid=%d\n"), inf->pid); + status->kind = TARGET_WAITKIND_EXITED; + status->value.integer = 0; /* Don't know. */ + return ptid_build (inf->pid, 0, 0); } - - inferior_debug (4, _("darwin_wait: pid=%d exit, status=0x%x\n"), - res, wstatus); - - /* Looks necessary on Leopard and harmless... */ - wait4 (inf->pid, &wstatus, 0, NULL); - - return ptid_build (inf->pid, 0, 0); - } - else - { - inferior_debug (4, _("darwin_wait: pid=%d\n"), inf->pid); - status->kind = TARGET_WAITKIND_EXITED; - status->value.integer = 0; /* Don't know. */ - return ptid_build (inf->pid, 0, 0); } } - printf_unfiltered (_("Bad local-port: 0x%x\n"), hdr->msgh_local_port); - status->kind = TARGET_WAITKIND_SPURIOUS; + /* Unknown message. */ + warning (_("darwin: got unknown message, id: 0x%x\n"), hdr->msgh_id); + status->kind = TARGET_WAITKIND_IGNORE; return minus_one_ptid; } @@ -1082,7 +1111,10 @@ darwin_wait (ptid_t ptid, struct target_waitstatus *status) darwin_dump_message (hdr, darwin_debug_flag > 11); res = darwin_decode_message (hdr, &thread, &inf, status); + if (ptid_equal (res, minus_one_ptid)) + continue; + /* Early return in case an inferior has exited. */ if (inf == NULL) return res; } @@ -1110,6 +1142,10 @@ darwin_wait (ptid_t ptid, struct target_waitstatus *status) break; } + /* Debug: display message. */ + if (darwin_debug_flag > 10) + darwin_dump_message (hdr, darwin_debug_flag > 11); + ptid2 = darwin_decode_message (hdr, &thread, &inf, &status2); if (inf != NULL && thread != NULL