From patchwork Thu Mar 20 18:28:13 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 198 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx21.g.dreamhost.com (caibbdcaaahb.dreamhost.com [208.113.200.71]) by wilcox.dreamhost.com (Postfix) with ESMTP id 8C464360108 for ; Thu, 20 Mar 2014 11:28:24 -0700 (PDT) Received: by homiemail-mx21.g.dreamhost.com (Postfix, from userid 14314964) id 9E8CFCB8420; Thu, 20 Mar 2014 11:28:23 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx21.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-mx21.g.dreamhost.com (Postfix) with ESMTPS id 54C18CA3255 for ; Thu, 20 Mar 2014 11:28:23 -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:message-id:date:from:mime-version:to:cc :subject:references:in-reply-to:content-type :content-transfer-encoding; q=dns; s=default; b=OnOGk8s+npTYTrLG 8sPI7Rv6sDqdSL03EJPAr+MsFxtnqvj3SIcEIE3LIEPD1i6burMvBgxLg8GPQnEK fGW3hm6E9vLKzasGjjhFyqMhLL973mOWYb7ga5Ddr134Z1GekrV4qaw7Nlh1OTIQ DRTWRDtaLKWk1shDgPuSjPgp508= 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:message-id:date:from:mime-version:to:cc :subject:references:in-reply-to:content-type :content-transfer-encoding; s=default; bh=LNhb6Dz/Lim5GCZ1gyUw1c BzPwg=; b=YmOqfJnJJuz3OJ5avcROuXW+DOnjTjmJrgocCkZPoqY/pVMUuLkkQN FMyiLGUcuksy9zncXqw+28yRBaHCJ8LrXnC3ks4WUBfzUlb+m232Wz11cSu1cdVI kc0a3RwdQoaOLQD8ptITssGH4kG+UdtAhDY80ZVVisW1qX15axRLA= Received: (qmail 32042 invoked by alias); 20 Mar 2014 18:28:21 -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 32025 invoked by uid 89); 20 Mar 2014 18:28:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 20 Mar 2014 18:28:18 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s2KISFCr004697 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 20 Mar 2014 14:28:16 -0400 Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s2KISEtB000430; Thu, 20 Mar 2014 14:28:14 -0400 Message-ID: <532B333D.9050204@redhat.com> Date: Thu, 20 Mar 2014 18:28:13 +0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130625 Thunderbird/17.0.7 MIME-Version: 1.0 To: Tom Tromey CC: gdb-patches@sourceware.org Subject: Re: [RFC v5 6/8] fix py-finish-breakpoint.exp with always-async References: <1393957974-4521-1-git-send-email-tromey@redhat.com> <1393957974-4521-7-git-send-email-tromey@redhat.com> In-Reply-To: <1393957974-4521-7-git-send-email-tromey@redhat.com> X-DH-Original-To: gdb@patchwork.siddhesh.in Hi, I somehow neglected to respond to your response to: https://sourceware.org/ml/gdb-patches/2013-11/msg00298.html at: https://sourceware.org/ml/gdb-patches/2013-12/msg00349.html I investigated this further in the direction of my comments, and extended the commit log with the resulting details. Here's what I pushed. Thanks. ----------------- From: Tom Tromey Fix py-finish-breakpoint.exp with target async. With target async enabled, py-finish-breakpoint.exp triggers an assertion failure. The failure occurs because execute_command re-enters the event loop in some circumstances, and in this case resets the sync_execution flag. Then later GDB reaches this assertion in normal_stop: gdb_assert (sync_execution || !target_can_async_p ()); In detail: #1 - A synchronous execution command is run. sync_execution is set. #2 - A python breakpoint is hit (TARGET_WAITKIND_STOPPED), and the corresponding Python breakpoint's stop method is executed. When and while python commands are executed, interpreter_async is forced to 0. #3 - The Python stop method happens to execute a not-execution-related gdb command. In this case, "where 1". #4 - Seeing that sync_execution is set, execute_command nests a new event loop (although that wasn't necessary; this is the problem). #5 - The linux-nat target's pipe in the event loop happens to be marked. That's normal, due to this in linux_nat_wait: /* If we requested any event, and something came out, assume there may be more. If we requested a specific lwp or process, also assume there may be more. */ The nested event loop thus immediately wakes up and calls target_wait. No thread is actually executing in the inferior, so the target returns TARGET_WAITKIND_NO_RESUMED. #6 - normal_stop is reached. GDB prints "No unwaited-for children left.", and resets the sync_execution flag (IOW, there are no resumed threads left, so the synchronous command is considered completed.) This is already bogus. We were handling a breakpoint! #7 - the nested event loop unwinds/ends. GDB is now back to handling the python stop method (TARGET_WAITKIND_STOPPED), which decides the breakpoint should stop. normal_stop is called for this event. However, normal_stop actually works with the _last_ reported target status: void normal_stop (void) { struct target_waitstatus last; ptid_t last_ptid; struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); ... get_last_target_status (&last_ptid, &last); ... if (last.kind == TARGET_WAITKIND_NO_RESUMED) { gdb_assert (sync_execution || !target_can_async_p ()); target_terminal_ours_for_output (); printf_filtered (_("No unwaited-for children left.\n")); } And due to the nesting in execute command, the last event is now TARGET_WAITKIND_NO_RESUMED, not the actual breakpoint event being handled. This could be seen to be broken in itself, but we can leave fixing that for another pass. The assertion is reached, and fails. execute_command has a comment explaining when it should synchronously wait for events: /* If the interpreter is in sync mode (we're running a user command's list, running command hooks or similars), and we just ran a synchronous command that started the target, wait for that command to end. */ However, the code did not follow this comment -- it didn't check to see if the command actually started the target, just whether the target was executing a sync command at this point. This patch fixes the problem by noting whether the target was executing in sync_execution mode before running the command, and then augmenting the condition to test this as well. 2014-03-20 Tom Tromey PR gdb/14135 * top.c (execute_command): Only dispatch events if the command started the target. --- gdb/ChangeLog | 6 ++++++ gdb/top.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index acb25f8..1db0ee9 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,11 @@ 2014-03-20 Tom Tromey + PR gdb/14135 + * top.c (execute_command): Only dispatch events if the command + started the target. + +2014-03-20 Tom Tromey + PR cli/15718 * infcall.c: Include event-top.h. (run_inferior_call): Call async_disable_stdin if needed. diff --git a/gdb/top.c b/gdb/top.c index e1a1331..fa20025 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -406,6 +406,8 @@ execute_command (char *p, int from_tty) { const char *cmd = p; char *arg; + int was_sync = sync_execution; + line = p; /* If trace-commands is set then this will print this command. */ @@ -461,7 +463,7 @@ execute_command (char *p, int from_tty) command's list, running command hooks or similars), and we just ran a synchronous command that started the target, wait for that command to end. */ - if (!interpreter_async && sync_execution) + if (!interpreter_async && !was_sync && sync_execution) { while (gdb_do_one_event () >= 0) if (!sync_execution)