From: Eli Zaretskii <eliz@gnu.org>
To: Pedro Alves <palves@redhat.com>
Cc: gdb@sourceware.org
Subject: Re: Inadvertently run inferior threads
Date: Wed, 10 Jun 2015 15:50:00 -0000 [thread overview]
Message-ID: <83y4jrsgui.fsf@gnu.org> (raw)
In-Reply-To: <550458E0.10206@redhat.com>
> Date: Sat, 14 Mar 2015 15:50:56 +0000
> From: Pedro Alves <palves@redhat.com>
> 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
next prev parent reply other threads:[~2015-06-10 15:50 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-12 17:11 Eli Zaretskii
2015-03-14 13:40 ` Pedro Alves
2015-03-14 14:56 ` Eli Zaretskii
2015-03-14 15:36 ` Pedro Alves
2015-03-14 15:51 ` Pedro Alves
2015-03-14 15:58 ` Pedro Alves
2015-06-10 15:15 ` Eli Zaretskii
2015-03-14 16:06 ` Eli Zaretskii
2015-06-10 15:50 ` Eli Zaretskii [this message]
2015-06-11 13:42 ` Eli Zaretskii
2015-06-15 13:18 ` Pedro Alves
2015-06-15 15:27 ` Eli Zaretskii
2015-06-15 15:42 ` Pedro Alves
2015-06-23 4:07 ` Doug Evans
2015-06-23 12:19 ` Pedro Alves
2015-06-23 19:11 ` Pedro Alves
2015-06-23 19:52 ` Eli Zaretskii
2015-06-24 14:29 ` Eli Zaretskii
2015-06-29 15:57 ` Pedro Alves
2015-06-23 14:58 ` Eli Zaretskii
2015-06-15 13:01 ` Pedro Alves
2015-06-15 15:14 ` Eli Zaretskii
2015-06-15 15:28 ` Pedro Alves
2015-06-15 17:21 ` Eli Zaretskii
2015-06-15 17:56 ` Pedro Alves
2015-06-15 19:07 ` Eli Zaretskii
2015-06-23 11:51 ` Pedro Alves
2015-03-14 16:04 ` Eli Zaretskii
2015-03-14 16:15 ` Pedro Alves
2015-03-14 16:17 ` Eli Zaretskii
2015-03-14 16:23 ` Pedro Alves
2015-03-14 17:01 ` Eli Zaretskii
2015-03-14 17:46 ` Pedro Alves
2015-06-10 15:13 ` Eli Zaretskii
2015-06-15 13:08 ` Pedro Alves
2015-06-15 15:15 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=83y4jrsgui.fsf@gnu.org \
--to=eliz@gnu.org \
--cc=gdb@sourceware.org \
--cc=palves@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox