From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18733 invoked by alias); 15 Jun 2015 15:42:59 -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 18716 invoked by uid 89); 15 Jun 2015 15:42:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.3 required=5.0 tests=AWL,BAYES_50,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=no 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 (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 15 Jun 2015 15:42:57 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id B13B1345AB0; Mon, 15 Jun 2015 15:42:56 +0000 (UTC) Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t5FFgsY0011956; Mon, 15 Jun 2015 11:42:55 -0400 Message-ID: <557EF27E.3030900@redhat.com> Date: Mon, 15 Jun 2015 15:42:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: Eli Zaretskii CC: gdb@sourceware.org Subject: Re: Inadvertently run inferior threads References: <83h9tq3zu3.fsf@gnu.org> <55043A63.6020103@redhat.com> <8361a339xd.fsf@gnu.org> <5504555C.804@redhat.com> <550458E0.10206@redhat.com> <83y4jrsgui.fsf@gnu.org> <83ioaus6pt.fsf@gnu.org> <557ED083.1060804@redhat.com> <83si9tngaj.fsf@gnu.org> In-Reply-To: <83si9tngaj.fsf@gnu.org> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-SW-Source: 2015-06/txt/msg00031.txt.bz2 On 06/15/2015 04:27 PM, Eli Zaretskii wrote: >> Date: Mon, 15 Jun 2015 14:17:55 +0100 >> From: Pedro Alves >> CC: gdb@sourceware.org >> >> On 06/11/2015 02:41 PM, Eli Zaretskii wrote: >> >>> And I have a question about your description of what happens on >>> GNU/Linux. You say: >>> >>>> #4 - result: _new_ threads end up in "running" state, even though they >>>> are stopped. >>> >>> My question is this: who or what stops the new threads that were >>> started by the function we infcall'ed? I know who stops them on >>> MS-Windows: the OS. >> >> GDB does, from within the target's target_wait implementation. >> For Linux, it's in linux-nat.c:linux_nat_wait_1: > > I guess this happens unless the breakpoint was thread-specific, right? No, it always happens. It's the core of run control that decides after everything has stopped whether a thread-specific breakpoint tripped for the wrong thread. > Otherwise the async execution would be much less useful, I presume. It's still useful, just not as efficient as you'd hope. > But I digress. ( The "[PATCH v4 00/18] All-stop on top of non-stop" series gives us the optimization you were expecting: https://sourceware.org/ml/gdb-patches/2015-05/msg00564.html ) > >>> If so, I don't understand why we suppress >>> the stopped <-> running transitions when in infcall. Or at least the >>> running -> stopped transition. The comment in normal_stop tries to >>> explain this: >> >> Say you have a breakpoint with a condition that does an infcall, like: >> >> int return_false (void) { return 0 }; >> >> (gdb) b somewhere_in_a_loop if return_false() >> (gdb) c >> >> >From the perspective of the user, the thread is always running >> after that "c". The breakpoint stops for both "somewhere_in_a_loop" and >> for the infcall's dummy breakpoint are all internal run control >> machinery details. > > I'm not sure I follow. From this user's (admittedly semi-naive) POV, > what happens with such a breakpoint is this: > > . Inferior hits the breakpoint and stops; the thread is now "not > running". > > . GDB gets control and evaluates the condition. > > . When GDB issues the infcall, as part of evaluating the condition, > the thread resumes -- now it is "running". > > . The thread that runs the infcall reaches the end of the function > and stops at the temporary breakpoint GDB inserted there -- the > thread is again "not running". > > . GDB evaluates the return value, decides that the condition was not > fulfilled, and resumes the inferior -- the thread is now "running" > again. Or GDB decides that the condition _was_ fulfilled, in > which case the thread stays at its "not running" state. That's what internal "executing" state tracks. With asynchronous control and background execution, you have to consider what happens if the user does "info threads" just while GDB is handling these internal stops. If the user does "step&" (step in the background, and give me the prompt right away), and then does "info threads" while the thread is busy doing the internal single-steps, it'd be highly confusing to sometimes see the thread as stopped (e.g., if it needed to be held a bit while another thread steps over a breakpoint) and sometimes as running. The user should not be able to issue "continue" right at the time a thread had stopped for such an internal event, and manage to override an already ongoing "step". > So it sounds to me that if we faithfully reflect the actual running > state of the thread during this scenario, without any exceptions or > exemptions, we are good. You say "internal run control machinery > details", but since these controls actually run and stop user threads, > I don't see why we should work so hard to conceal them, and in the > process shoot ourselves in the foot. > > What am I missing? > > Thanks for taking the time to explain these details. Thanks, Pedro Alves