From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 75408 invoked by alias); 10 Jun 2015 15:50:27 -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 75399 invoked by uid 89); 10 Jun 2015 15:50:26 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL,BAYES_50,RCVD_IN_DNSWL_NONE,SPF_SOFTFAIL autolearn=no version=3.3.2 X-HELO: mtaout23.012.net.il Received: from mtaout23.012.net.il (HELO mtaout23.012.net.il) (80.179.55.175) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 10 Jun 2015 15:50:24 +0000 Received: from conversion-daemon.a-mtaout23.012.net.il by a-mtaout23.012.net.il (HyperSendmail v2007.08) id <0NPQ00H00JYG4U00@a-mtaout23.012.net.il> for gdb@sourceware.org; Wed, 10 Jun 2015 18:50:22 +0300 (IDT) Received: from HOME-C4E4A596F7 ([87.69.4.28]) by a-mtaout23.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0NPQ00HYHJZX3L10@a-mtaout23.012.net.il>; Wed, 10 Jun 2015 18:50:22 +0300 (IDT) Date: Wed, 10 Jun 2015 15:50:00 -0000 From: Eli Zaretskii Subject: Re: Inadvertently run inferior threads In-reply-to: <550458E0.10206@redhat.com> To: Pedro Alves Cc: gdb@sourceware.org Reply-to: Eli Zaretskii Message-id: <83y4jrsgui.fsf@gnu.org> References: <83h9tq3zu3.fsf@gnu.org> <55043A63.6020103@redhat.com> <8361a339xd.fsf@gnu.org> <5504555C.804@redhat.com> <550458E0.10206@redhat.com> X-IsSubscribed: yes X-SW-Source: 2015-06/txt/msg00005.txt.bz2 > Date: Sat, 14 Mar 2015 15:50:56 +0000 > From: Pedro Alves > CC: gdb@sourceware.org Sorry for the long delay: this problem is rare, and it took me time to find a semi-reliable reproducer for it, so I could investigate it efficiently. > I see what's going on here: > > #1 - we suppress the *stopped -> *running transitions/notification when > doing an inferior function call (the in_infcall checks in infrun.c). > > #2 - new threads are spawned and given *running state, because well, > they're running. > > #3 - we suppress the running -> *stopped transition when doing > an infcall, like in #1. (The in_infcall check in normal_stop). > > #4 - result: _new_ threads end up in "running" state, even though they > are stopped. > > I don't know off hand what the best fix is. > > I think this bug must be in the tree for a while. Curious that > we don't have a test that exercises this... > > I can't explain why you see _all_ threads as running instead of > only the new ones, though. I think I can explain that. First, in MinGW native debugging the function set_running, as well as most other thread-related functions that change state, are always called with minus_one_ptid as their ptid argument, and therefore they change the state of all the threads. The second part of the puzzle is that when these threads are started, we are inside the 'proceed' call made by 'run_inferior_call'. When a thread like this is started during this time, we get TARGET_WAITKIND_SPURIOUS event inside 'handle_inferior_event', and call 'resume'. But when 'resume' is called like that, inferior_ptid is set to the thread ID of the new thread that was started, and which triggered TARGET_WAITKIND_SPURIOUS. So when 'resume' wants to suppress the stopped -> running transition, here: if (!tp->control.in_infcall) set_running (user_visible_resume_ptid (user_step), 1); it winds up calling 'set_running', because the in_infcall flag is set on the thread that called the inferior function, not on the thread which was started and triggered TARGET_WAITKIND_SPURIOUS. So 'set_running' is called, and it is called with minus_one_ptid, which then has the effect of marking all the threads as running. What I don't understand is why doesn't the breakpoint we set at exit from the inferior function countermand that. I do see the effect of that breakpoint if I turn on infrun debugging: infrun: target_wait (-1, status) = infrun: 4608 [Thread 4608.0x4900], infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x88ba9f infrun: BPSTAT_WHAT_STOP_SILENT infrun: stop_waiting Why don't we mark all threads as stopped when we hit the breakpoint? is that because of #3 above? Any ideas how to solve this annoying problem? TIA