public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* Inadvertently run inferior threads
@ 2015-03-12 17:11 Eli Zaretskii
  2015-03-14 13:40 ` Pedro Alves
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2015-03-12 17:11 UTC (permalink / raw)
  To: gdb

This happens to me quite a lot when I debug Emacs on Windows and
invoke a command that calls a function in the inferior:

  Breakpoint 3, font_matches_spec (type=4, font=0x88b678, spec=22662725,
      backend=33216, logfont=0x88b860) at w32font.c:1197
  1197                      if (! memq_no_quit (val, support))
  (gdb) p val
  $1 = -7860248
  (gdb) xtype
  Lisp_Symbol
  (gdb) xsymbol
  $2 = (struct Lisp_Symbol *) 0x1913eb0 <dumped_data+3723472>
  "mathematical-bold"
  (gdb) n
  1198                        return 0;
  (gdb) p support
  $3 = 25938803
  (gdb) pp support
  [New Thread 20240.0x1134]
  [New Thread 20240.0x445c]
  (symbol arabic hebrew cyrillic greek phonetic latin)
  (gdb) c
  Continuing.
  Cannot execute this command while the selected thread is running.
  (gdb) info threads
    Id   Target Id         Frame
    6    Thread 20240.0x445c (running)
    5    Thread 20240.0x1134 (running)
    4    Thread 20240.0x24bc (running)
    3    Thread 20240.0x1cb4 (running)
    2    Thread 20240.0xb5c (running)
  * 1    Thread 20240.0x464c (running)

"pp" is in this case the command that invokes an inferior function,
see src/.gdbinit in the Emacs sources for the details.  'support' is a
Lisp object, a list in this case, and "pp" displays it in
human-readable form.  Note that invoking "pp" started 2 new threads in
the inferior, for some reason -- neither the command itself nor the
function it invokes start any threads.  It's Windows itself that
starts them, so it seems.

I only see this on Windows 7, never on XP (didn't try newer versions).

Once this happens, the debugging session seems to be ruined: the only
thing I can do is kill the inferior and quit the debugger.  Because
there doesn't seem to be any way of stopping the threads again, not on
Windows anyway.

Am I the only one who sees this annoying problem?  Does anyone know
how to avoid it, or where to look for fixing it?

TIA

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-12 17:11 Inadvertently run inferior threads Eli Zaretskii
@ 2015-03-14 13:40 ` Pedro Alves
  2015-03-14 14:56   ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Pedro Alves @ 2015-03-14 13:40 UTC (permalink / raw)
  To: Eli Zaretskii, gdb

On 03/12/2015 05:11 PM, Eli Zaretskii wrote:

> "pp" is in this case the command that invokes an inferior function,
> see src/.gdbinit in the Emacs sources for the details.

Here's a handy direct url:

  http://git.savannah.gnu.org/cgit/emacs.git/tree/src/.gdbinit

> Once this happens, the debugging session seems to be ruined: the only
> thing I can do is kill the inferior and quit the debugger.  Because
> there doesn't seem to be any way of stopping the threads again, not on
> Windows anyway.

The threads are probably stopped, and GDB managed to get out of
sync somehow.  Otherwise, "(gdb) interrupt" would probably work.

> Am I the only one who sees this annoying problem?  Does anyone know
> how to avoid it, or where to look for fixing it?

Never seen that, but then again I don't use Windows nowadays.

For run control bugs, logs are usually necessary to make sense of
things.  Try "set debug infrun 1" + the multiple Windows
specific "set debugfoo" commands.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 13:40 ` Pedro Alves
@ 2015-03-14 14:56   ` Eli Zaretskii
  2015-03-14 15:36     ` Pedro Alves
  2015-06-10 15:13     ` Eli Zaretskii
  0 siblings, 2 replies; 36+ messages in thread
From: Eli Zaretskii @ 2015-03-14 14:56 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Sat, 14 Mar 2015 13:40:51 +0000
> From: Pedro Alves <palves@redhat.com>
> 
> > Once this happens, the debugging session seems to be ruined: the only
> > thing I can do is kill the inferior and quit the debugger.  Because
> > there doesn't seem to be any way of stopping the threads again, not on
> > Windows anyway.
> 
> The threads are probably stopped, and GDB managed to get out of
> sync somehow.

In that case, the cause of it getting out of sync is the new thread
that was started (probably by Windows)?

> Otherwise, "(gdb) interrupt" would probably work.

Thanks, I will try using this next time.

> For run control bugs, logs are usually necessary to make sense of
> things.  Try "set debug infrun 1" + the multiple Windows
> specific "set debugfoo" commands.

OK, will try that as well.  Thanks.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 14:56   ` Eli Zaretskii
@ 2015-03-14 15:36     ` Pedro Alves
  2015-03-14 15:51       ` Pedro Alves
  2015-03-14 16:04       ` Eli Zaretskii
  2015-06-10 15:13     ` Eli Zaretskii
  1 sibling, 2 replies; 36+ messages in thread
From: Pedro Alves @ 2015-03-14 15:36 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 03/14/2015 02:55 PM, Eli Zaretskii wrote:
>> Date: Sat, 14 Mar 2015 13:40:51 +0000
>> From: Pedro Alves <palves@redhat.com>
>>
>>> Once this happens, the debugging session seems to be ruined: the only
>>> thing I can do is kill the inferior and quit the debugger.  Because
>>> there doesn't seem to be any way of stopping the threads again, not on
>>> Windows anyway.
>>
>> The threads are probably stopped, and GDB managed to get out of
>> sync somehow.
> 
> In that case, the cause of it getting out of sync is the new thread
> that was started (probably by Windows)?

Calling a function that ends up starting new threads should
work OK, but indeed that seems to be broken...

On GNU/Linux, and a trivial program with:

~~~
void
start_thread (void)
{
  pthread_t thread;

  pthread_create (&thread, NULL, thread_function, NULL);
}
~~~

results in:

(gdb) p start_thread ()
[New Thread 0x7ffff7fc1700 (LWP 9903)]
$1 = void
(gdb) info threads
  Id   Target Id         Frame
  2    Thread 0x7ffff7fc1700 (LWP 9903) "start-thread-in" (running)
* 1    Thread 0x7ffff7fc2740 (LWP 9899) "start-thread-in" main () at start-thread-infcall.c:35

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 15:36     ` Pedro Alves
@ 2015-03-14 15:51       ` Pedro Alves
  2015-03-14 15:58         ` Pedro Alves
                           ` (2 more replies)
  2015-03-14 16:04       ` Eli Zaretskii
  1 sibling, 3 replies; 36+ messages in thread
From: Pedro Alves @ 2015-03-14 15:51 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 03/14/2015 03:35 PM, Pedro Alves wrote:
> On 03/14/2015 02:55 PM, Eli Zaretskii wrote:
>>> Date: Sat, 14 Mar 2015 13:40:51 +0000
>>> From: Pedro Alves <palves@redhat.com>
>>>
>>>> Once this happens, the debugging session seems to be ruined: the only
>>>> thing I can do is kill the inferior and quit the debugger.  Because
>>>> there doesn't seem to be any way of stopping the threads again, not on
>>>> Windows anyway.
>>>
>>> The threads are probably stopped, and GDB managed to get out of
>>> sync somehow.
>>
>> In that case, the cause of it getting out of sync is the new thread
>> that was started (probably by Windows)?
> 
> Calling a function that ends up starting new threads should
> work OK, but indeed that seems to be broken...
> 
> On GNU/Linux, and a trivial program with:
> 
> ~~~
> void
> start_thread (void)
> {
>   pthread_t thread;
> 
>   pthread_create (&thread, NULL, thread_function, NULL);
> }
> ~~~
> 
> results in:
> 
> (gdb) p start_thread ()
> [New Thread 0x7ffff7fc1700 (LWP 9903)]
> $1 = void
> (gdb) info threads
>   Id   Target Id         Frame
>   2    Thread 0x7ffff7fc1700 (LWP 9903) "start-thread-in" (running)
> * 1    Thread 0x7ffff7fc2740 (LWP 9899) "start-thread-in" main () at start-thread-infcall.c:35
> 

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.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  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
  2 siblings, 1 reply; 36+ messages in thread
From: Pedro Alves @ 2015-03-14 15:58 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 03/14/2015 03:50 PM, Pedro Alves wrote:

>> Calling a function that ends up starting new threads should
>> work OK, but indeed that seems to be broken...
>>
>> On GNU/Linux, and a trivial program with:
>>
>> ~~~
>> void
>> start_thread (void)
>> {
>>   pthread_t thread;
>>
>>   pthread_create (&thread, NULL, thread_function, NULL);
>> }
>> ~~~
>>
>> results in:
>>
>> (gdb) p start_thread ()
>> [New Thread 0x7ffff7fc1700 (LWP 9903)]
>> $1 = void
>> (gdb) info threads
>>   Id   Target Id         Frame
>>   2    Thread 0x7ffff7fc1700 (LWP 9903) "start-thread-in" (running)
>> * 1    Thread 0x7ffff7fc2740 (LWP 9899) "start-thread-in" main () at start-thread-infcall.c:35
>>
> 
> 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.

This is now: https://sourceware.org/bugzilla/show_bug.cgi?id=18127

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 15:36     ` Pedro Alves
  2015-03-14 15:51       ` Pedro Alves
@ 2015-03-14 16:04       ` Eli Zaretskii
  2015-03-14 16:15         ` Pedro Alves
  1 sibling, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2015-03-14 16:04 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Sat, 14 Mar 2015 15:35:56 +0000
> From: Pedro Alves <palves@redhat.com>
> CC: gdb@sourceware.org
> 
> > In that case, the cause of it getting out of sync is the new thread
> > that was started (probably by Windows)?
> 
> Calling a function that ends up starting new threads should
> work OK, but indeed that seems to be broken...

Yes, but in my case the called function didn't really start any
threads...

That said, thanks for the info, it could very well be relevant.

> (gdb) info threads
>   Id   Target Id         Frame
>   2    Thread 0x7ffff7fc1700 (LWP 9903) "start-thread-in" (running)
> * 1    Thread 0x7ffff7fc2740 (LWP 9899) "start-thread-in" main () at start-thread-infcall.c:35

What does "start-thread-in" signify in this display?

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 15:51       ` Pedro Alves
  2015-03-14 15:58         ` Pedro Alves
@ 2015-03-14 16:06         ` Eli Zaretskii
  2015-06-10 15:50         ` Eli Zaretskii
  2 siblings, 0 replies; 36+ messages in thread
From: Eli Zaretskii @ 2015-03-14 16:06 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Sat, 14 Mar 2015 15:50:56 +0000
> From: Pedro Alves <palves@redhat.com>
> CC: gdb@sourceware.org
> 
> I can't explain why you see _all_ threads as running instead of
> only the new ones, though.

Could be Windows-specific.  I will take a look, thanks for all the
background info.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 16:04       ` Eli Zaretskii
@ 2015-03-14 16:15         ` Pedro Alves
  2015-03-14 16:17           ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Pedro Alves @ 2015-03-14 16:15 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 03/14/2015 04:04 PM, Eli Zaretskii wrote:
>> Date: Sat, 14 Mar 2015 15:35:56 +0000
>> From: Pedro Alves <palves@redhat.com>
>> CC: gdb@sourceware.org
>>
>>> In that case, the cause of it getting out of sync is the new thread
>>> that was started (probably by Windows)?
>>
>> Calling a function that ends up starting new threads should
>> work OK, but indeed that seems to be broken...
> 
> Yes, but in my case the called function didn't really start any
> threads...

If emacs doesn't start a new thread directly, it just looks to
me that some Windows API function internally spawns them
sometimes, then?  From gdb's perspective, it's exactly the same
thing, it's all code in the inferior.

> 
> That said, thanks for the info, it could very well be relevant.
> 
>> (gdb) info threads
>>   Id   Target Id         Frame
>>   2    Thread 0x7ffff7fc1700 (LWP 9903) "start-thread-in" (running)
>> * 1    Thread 0x7ffff7fc2740 (LWP 9899) "start-thread-in" main () at start-thread-infcall.c:35
> 
> What does "start-thread-in" signify in this display?

It's the thread name, which defaults to the binary's file name name,
which was "start-thread-infcall", but Linux trims it to 15 or so
characters, IIRC.  For this to work, you need to implement the
target_thread_name hook.  AFAICS, only linux-nat.c implements this.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 16:15         ` Pedro Alves
@ 2015-03-14 16:17           ` Eli Zaretskii
  2015-03-14 16:23             ` Pedro Alves
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2015-03-14 16:17 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Sat, 14 Mar 2015 16:15:03 +0000
> From: Pedro Alves <palves@redhat.com>
> CC: gdb@sourceware.org
> 
> > Yes, but in my case the called function didn't really start any
> > threads...
> 
> If emacs doesn't start a new thread directly, it just looks to
> me that some Windows API function internally spawns them
> sometimes, then?

Yes, I think so.

> From gdb's perspective, it's exactly the same thing, it's all code
> in the inferior.

Certainly.

> >> (gdb) info threads
> >>   Id   Target Id         Frame
> >>   2    Thread 0x7ffff7fc1700 (LWP 9903) "start-thread-in" (running)
> >> * 1    Thread 0x7ffff7fc2740 (LWP 9899) "start-thread-in" main () at start-thread-infcall.c:35
> > 
> > What does "start-thread-in" signify in this display?
> 
> It's the thread name, which defaults to the binary's file name name,
> which was "start-thread-infcall", but Linux trims it to 15 or so
> characters, IIRC.  For this to work, you need to implement the
> target_thread_name hook.  AFAICS, only linux-nat.c implements this.

Well, Windows threads don't really have names, AFAIK.

Thanks.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 16:17           ` Eli Zaretskii
@ 2015-03-14 16:23             ` Pedro Alves
  2015-03-14 17:01               ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Pedro Alves @ 2015-03-14 16:23 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 03/14/2015 04:17 PM, Eli Zaretskii wrote:
>> Date: Sat, 14 Mar 2015 16:15:03 +0000
>> From: Pedro Alves <palves@redhat.com>
>> CC: gdb@sourceware.org
>>
>>> Yes, but in my case the called function didn't really start any
>>> threads...
>>
>> If emacs doesn't start a new thread directly, it just looks to
>> me that some Windows API function internally spawns them
>> sometimes, then?
> 
> Yes, I think so.
> 
>> From gdb's perspective, it's exactly the same thing, it's all code
>> in the inferior.
> 
> Certainly.
> 
>>>> (gdb) info threads
>>>>   Id   Target Id         Frame
>>>>   2    Thread 0x7ffff7fc1700 (LWP 9903) "start-thread-in" (running)
>>>> * 1    Thread 0x7ffff7fc2740 (LWP 9899) "start-thread-in" main () at start-thread-infcall.c:35
>>>
>>> What does "start-thread-in" signify in this display?
>>
>> It's the thread name, which defaults to the binary's file name name,
>> which was "start-thread-infcall", but Linux trims it to 15 or so
>> characters, IIRC.  For this to work, you need to implement the
>> target_thread_name hook.  AFAICS, only linux-nat.c implements this.
> 
> Well, Windows threads don't really have names, AFAIK.

Last I looked, Visual Studio does support that.  It's based on a
funny hack:

 https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx

I think the idea is that the debugger intercepts that MS_VC_EXCEPTION
SEH exception and reads the thread name off of the inferior memory
pointed at by the THREADNAME_INFO structure.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 16:23             ` Pedro Alves
@ 2015-03-14 17:01               ` Eli Zaretskii
  2015-03-14 17:46                 ` Pedro Alves
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2015-03-14 17:01 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Sat, 14 Mar 2015 16:23:40 +0000
> From: Pedro Alves <palves@redhat.com>
> CC: gdb@sourceware.org
> 
> >> It's the thread name, which defaults to the binary's file name name,
> >> which was "start-thread-infcall", but Linux trims it to 15 or so
> >> characters, IIRC.  For this to work, you need to implement the
> >> target_thread_name hook.  AFAICS, only linux-nat.c implements this.
> > 
> > Well, Windows threads don't really have names, AFAIK.
> 
> Last I looked, Visual Studio does support that.  It's based on a
> funny hack:
> 
>  https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx

That's only for viewing thread names in a debugger.  Is that what
target_thread_name hook does?

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 17:01               ` Eli Zaretskii
@ 2015-03-14 17:46                 ` Pedro Alves
  0 siblings, 0 replies; 36+ messages in thread
From: Pedro Alves @ 2015-03-14 17:46 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 03/14/2015 05:01 PM, Eli Zaretskii wrote:
>> From: Pedro Alves <palves@redhat.com>

>>> Well, Windows threads don't really have names, AFAIK.
>>
>> Last I looked, Visual Studio does support that.  It's based on a
>> funny hack:
>>
>>  https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
> 
> That's only for viewing thread names in a debugger.  Is that what
> target_thread_name hook does?

It retrieves the thread's name from the target, for display
and whatever else we might give it a use for in the future.
It's a convenience thing for the user.  On GNU/Linux, a user
can call pthread_setname_np to set the name in the program,
and then GDB can display the name in "info threads", for easier
thread identification.  I found that useful in the
attach-many-short-lived-threads test, for example.

Currently it's shown in "info threads", and also used
in "thread find".  That is, you can use "thread find foo" to
find the thread named "foo".

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 14:56   ` Eli Zaretskii
  2015-03-14 15:36     ` Pedro Alves
@ 2015-06-10 15:13     ` Eli Zaretskii
  2015-06-15 13:08       ` Pedro Alves
  1 sibling, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-10 15:13 UTC (permalink / raw)
  To: palves; +Cc: gdb

> Date: Sat, 14 Mar 2015 16:55:58 +0200
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: gdb@sourceware.org
> 
> > Otherwise, "(gdb) interrupt" would probably work.
> 
> Thanks, I will try using this next time.

It seems like 'interrupt' does nothing in native debugging of a target
that doesn't support async execution, at least on MS-Windows.  Is that
a bug, or is it expected?

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 15:58         ` Pedro Alves
@ 2015-06-10 15:15           ` Eli Zaretskii
  0 siblings, 0 replies; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-10 15:15 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Sat, 14 Mar 2015 15:58:49 +0000
> From: Pedro Alves <palves@redhat.com>
> CC: gdb@sourceware.org
> 
> On 03/14/2015 03:50 PM, Pedro Alves wrote:
> 
> >> Calling a function that ends up starting new threads should
> >> work OK, but indeed that seems to be broken...
> >>
> >> On GNU/Linux, and a trivial program with:
> >>
> >> ~~~
> >> void
> >> start_thread (void)
> >> {
> >>   pthread_t thread;
> >>
> >>   pthread_create (&thread, NULL, thread_function, NULL);
> >> }
> >> ~~~
> >>
> >> results in:
> >>
> >> (gdb) p start_thread ()
> >> [New Thread 0x7ffff7fc1700 (LWP 9903)]
> >> $1 = void
> >> (gdb) info threads
> >>   Id   Target Id         Frame
> >>   2    Thread 0x7ffff7fc1700 (LWP 9903) "start-thread-in" (running)
> >> * 1    Thread 0x7ffff7fc2740 (LWP 9899) "start-thread-in" main () at start-thread-infcall.c:35
> >>
> > 
> > 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.
> 
> This is now: https://sourceware.org/bugzilla/show_bug.cgi?id=18127

I think I'm starting to understand why this happens.  I will describe
my findings in the bug report.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-03-14 15:51       ` Pedro Alves
  2015-03-14 15:58         ` Pedro Alves
  2015-03-14 16:06         ` Eli Zaretskii
@ 2015-06-10 15:50         ` Eli Zaretskii
  2015-06-11 13:42           ` Eli Zaretskii
  2015-06-15 13:01           ` Pedro Alves
  2 siblings, 2 replies; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-10 15:50 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> 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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-10 15:50         ` Eli Zaretskii
@ 2015-06-11 13:42           ` Eli Zaretskii
  2015-06-15 13:18             ` Pedro Alves
  2015-06-15 13:01           ` Pedro Alves
  1 sibling, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-11 13:42 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Wed, 10 Jun 2015 18:50:13 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: gdb@sourceware.org
> 
> > 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?

I suggested a patch on gdb-patches which solved the problem for me, at
least in the MinGW-compiled GDB on MS-Windows.

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.  This is described in the MSDN documentation:

  When the system notifies the debugger of a debugging event, it also
  suspends all threads in the affected process. The threads do not
  resume execution until the debugger continues the debugging event by
  using ContinueDebugEvent.

Does the same happen on GNU/Linux (and other systems that support
asynchronous execution)?  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:

  /* Let the user/frontend see the threads as stopped, but do nothing
     if the thread was running an infcall.  We may be e.g., evaluating
     a breakpoint condition.  In that case, the thread had state
     THREAD_RUNNING before the infcall, and shall remain set to
     running, all without informing the user/frontend about state
     transition changes.  If this is actually a call command, then the
     thread was originally already stopped, so there's no state to
     finish either.  */
  if (target_has_execution && inferior_thread ()->control.in_infcall)
    discard_cleanups (old_chain);
  else
    do_cleanups (old_chain);

I don't understand this explanation, in particular why it says the
thread was in THREAD_RUNNING state before the infcall.  If we are
evaluating a breakpoint condition, the thread should be stopped, since
we hit a breakpoint, no?

Or maybe this belongs to my being confused regarding THREAD_RUNNING
state, as I wrote earlier here:

  https://sourceware.org/ml/gdb-patches/2015-06/msg00191.html

In general, we should have the the thread state reflect its actual
state, as far as the OS is concerned.  If the above comment is
accurate about the THREAD_RUNNING state, it sounds like we need a
reference count to go with that state, so that we could increment and
decrement it as needed, without the fear of overwriting someone else's
"running" state.

Does this make sense?

Thanks.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-10 15:50         ` Eli Zaretskii
  2015-06-11 13:42           ` Eli Zaretskii
@ 2015-06-15 13:01           ` Pedro Alves
  2015-06-15 15:14             ` Eli Zaretskii
  1 sibling, 1 reply; 36+ messages in thread
From: Pedro Alves @ 2015-06-15 13:01 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 06/10/2015 04:50 PM, Eli Zaretskii wrote:

>> I can't explain why you see _all_ threads as running instead of
>> only the new ones, though.
> 
> I think I can explain that.

Thanks for the investigation.

> 
> 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.

So that should mean that even for GNU/Linux, it should be possible
to end in the exact same, when any thread other than the one that we
had started the infcall in reports an event that doesn't cause a stop.
E.g., a thread specific breakpoint, a "handle nostop" signal, etc.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-10 15:13     ` Eli Zaretskii
@ 2015-06-15 13:08       ` Pedro Alves
  2015-06-15 15:15         ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Pedro Alves @ 2015-06-15 13:08 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 06/10/2015 04:13 PM, Eli Zaretskii wrote:
>> Date: Sat, 14 Mar 2015 16:55:58 +0200
>> From: Eli Zaretskii <eliz@gnu.org>
>> Cc: gdb@sourceware.org
>>
>>> Otherwise, "(gdb) interrupt" would probably work.
>>
>> Thanks, I will try using this next time.
> 
> It seems like 'interrupt' does nothing in native debugging of a target
> that doesn't support async execution, at least on MS-Windows.  Is that
> a bug, or is it expected?

It's old code, but I think the idea of the target_can_async check
in interrupt_command is "this shouldn't even be possible".  If the
target doesn't support async execution, you're not supposed to
be able to end up with a prompt while the target is running
in the first place.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-11 13:42           ` Eli Zaretskii
@ 2015-06-15 13:18             ` Pedro Alves
  2015-06-15 15:27               ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Pedro Alves @ 2015-06-15 13:18 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

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:

...
      /* Now stop all other LWP's ...  */
      iterate_over_lwps (minus_one_ptid, stop_callback, NULL);

      /* ... and wait until all of them have reported back that
	 they're no longer running.  */
      iterate_over_lwps (minus_one_ptid, stop_wait_callback, NULL);
...

> Does the same happen on GNU/Linux (and other systems that support
> asynchronous execution)?  

Yes.  It's gdb's own code that does it, but from infrun.c's
perspective, it's the same.

> 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.

(BBL to reply to the rest.)

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-15 13:01           ` Pedro Alves
@ 2015-06-15 15:14             ` Eli Zaretskii
  2015-06-15 15:28               ` Pedro Alves
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-15 15:14 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Mon, 15 Jun 2015 14:01:25 +0100
> From: Pedro Alves <palves@redhat.com>
> CC: gdb@sourceware.org
> 
> > 	  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.
> 
> So that should mean that even for GNU/Linux, it should be possible
> to end in the exact same, when any thread other than the one that we
> had started the infcall in reports an event that doesn't cause a stop.
> E.g., a thread specific breakpoint, a "handle nostop" signal, etc.

Does that involve minus_one_ptid on GNU/Linux as well?  If not, that
call will not mark all threads as running, will it?

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-15 13:08       ` Pedro Alves
@ 2015-06-15 15:15         ` Eli Zaretskii
  0 siblings, 0 replies; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-15 15:15 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Mon, 15 Jun 2015 14:07:57 +0100
> From: Pedro Alves <palves@redhat.com>
> CC: gdb@sourceware.org
> 
> > It seems like 'interrupt' does nothing in native debugging of a target
> > that doesn't support async execution, at least on MS-Windows.  Is that
> > a bug, or is it expected?
> 
> It's old code, but I think the idea of the target_can_async check
> in interrupt_command is "this shouldn't even be possible".  If the
> target doesn't support async execution, you're not supposed to
> be able to end up with a prompt while the target is running
> in the first place.

IOW, we don't have even a fire escape when something like that
happens.  Would it be a good idea to have at least a maint command to
stop a thread, or all threads?

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-15 13:18             ` Pedro Alves
@ 2015-06-15 15:27               ` Eli Zaretskii
  2015-06-15 15:42                 ` Pedro Alves
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-15 15:27 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Mon, 15 Jun 2015 14:17:55 +0100
> From: Pedro Alves <palves@redhat.com>
> 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?
Otherwise the async execution would be much less useful, I presume.
But I digress.

> > 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.

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.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-15 15:14             ` Eli Zaretskii
@ 2015-06-15 15:28               ` Pedro Alves
  2015-06-15 17:21                 ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Pedro Alves @ 2015-06-15 15:28 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 06/15/2015 04:13 PM, Eli Zaretskii wrote:
>> Date: Mon, 15 Jun 2015 14:01:25 +0100
>> From: Pedro Alves <palves@redhat.com>
>> CC: gdb@sourceware.org
>>
>>> 	  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.
>>
>> So that should mean that even for GNU/Linux, it should be possible
>> to end in the exact same, when any thread other than the one that we
>> had started the infcall in reports an event that doesn't cause a stop.
>> E.g., a thread specific breakpoint, a "handle nostop" signal, etc.
> 
> Does that involve minus_one_ptid on GNU/Linux as well?  If not, that
> call will not mark all threads as running, will it?

It does.  user_visible_resume_ptid returns the same irrespective
of target_can_async.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-15 15:27               ` Eli Zaretskii
@ 2015-06-15 15:42                 ` Pedro Alves
  2015-06-23  4:07                   ` Doug Evans
  0 siblings, 1 reply; 36+ messages in thread
From: Pedro Alves @ 2015-06-15 15:42 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 06/15/2015 04:27 PM, Eli Zaretskii wrote:
>> Date: Mon, 15 Jun 2015 14:17:55 +0100
>> From: Pedro Alves <palves@redhat.com>
>> 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

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-15 15:28               ` Pedro Alves
@ 2015-06-15 17:21                 ` Eli Zaretskii
  2015-06-15 17:56                   ` Pedro Alves
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-15 17:21 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Mon, 15 Jun 2015 16:28:14 +0100
> From: Pedro Alves <palves@redhat.com>
> CC: gdb@sourceware.org
> 
> >> So that should mean that even for GNU/Linux, it should be possible
> >> to end in the exact same, when any thread other than the one that we
> >> had started the infcall in reports an event that doesn't cause a stop.
> >> E.g., a thread specific breakpoint, a "handle nostop" signal, etc.
> > 
> > Does that involve minus_one_ptid on GNU/Linux as well?  If not, that
> > call will not mark all threads as running, will it?
> 
> It does.  user_visible_resume_ptid returns the same irrespective
> of target_can_async.

Then how come your test program ended up showing just that additional
thread running?  You even said you couldn't explain why I saw all my
threads running on Windows.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  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
  0 siblings, 2 replies; 36+ messages in thread
From: Pedro Alves @ 2015-06-15 17:56 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 06/15/2015 06:21 PM, Eli Zaretskii wrote:
>> Date: Mon, 15 Jun 2015 16:28:14 +0100
>> From: Pedro Alves <palves@redhat.com>
>> CC: gdb@sourceware.org
>>
>>>> So that should mean that even for GNU/Linux, it should be possible
>>>> to end in the exact same, when any thread other than the one that we
>>>> had started the infcall in reports an event that doesn't cause a stop.
>>>> E.g., a thread specific breakpoint, a "handle nostop" signal, etc.
>>>
>>> Does that involve minus_one_ptid on GNU/Linux as well?  If not, that
>>> call will not mark all threads as running, will it?
>>
>> It does.  user_visible_resume_ptid returns the same irrespective
>> of target_can_async.
> 
> Then how come your test program ended up showing just that additional
> thread running?  You even said you couldn't explain why I saw all my
> threads running on Windows.

Because linux-nat.c does not report any event to infrun when a
thread is created, it just immediately goes back to waiting, unlike
windows-nat.c, which reports TARGET_WAITKIND_SPURIOUS.  By previous
test program did not have the new thread trip on any event after
its creation.

That's why I said:
~~~
So that should mean that even for GNU/Linux, it should be possible
to end in the exact same, when any thread other than the one that we
had started the infcall in reports an event that doesn't cause a stop.
E.g., a thread specific breakpoint, a "handle nostop" signal, etc.
~~~

And I just confirmed it, with a thread-specific breakpoint that
trips on the wrong thread, thus, reporting a trap to the core,
which does not cause a user-visible stop, and then ends up
marking all threads running when we gdb internally re-resumes
the program.  Like so:

~~~
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>

volatile int count;

static int
foo (void)
{
  usleep (1);
}

static void *
thread_function (void *arg)
{
  pthread_t thread;

  printf ("created thread %d\n", count++);
  while (1)
    {
      foo ();
    }
}

void
new_thread (void)
{
  pthread_t thread;

  pthread_create (&thread, NULL, thread_function, NULL);
}

int
main (int argc, char **argv)
{
  while (1)
    {
      usleep (1);
    }
}
~~~

~~~
(gdb) start
...
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffd858) at threads_infcall.c:39
39            usleep (1);
(gdb) b foo thread 1
Breakpoint 2 at 0x4006a4: file threads_infcall.c, line 11.
(gdb) p new_thread ()
[New Thread 0x7ffff7fc1700 (LWP 4928)]
created thread 1
$1 = void
(gdb) info threads
  Id   Target Id         Frame
  2    Thread 0x7ffff7fc1700 (LWP 4928) "threads_infcall" (running)
* 1    Thread 0x7ffff7fc2740 (LWP 4924) "threads_infcall" main (argc=1, argv=0x7fffffffd858) at threads_infcall.c:39
(gdb) p new_thread ()
[New Thread 0x7ffff77c0700 (LWP 4929)]
created thread 2
$2 = void
(gdb) info threads
  Id   Target Id         Frame
  3    Thread 0x7ffff77c0700 (LWP 4929) "threads_infcall" (running)
  2    Thread 0x7ffff7fc1700 (LWP 4928) "threads_infcall" (running)
* 1    Thread 0x7ffff7fc2740 (LWP 4924) "threads_infcall" (running)
(gdb)
~~~

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-15 17:56                   ` Pedro Alves
@ 2015-06-15 19:07                     ` Eli Zaretskii
  2015-06-23 11:51                     ` Pedro Alves
  1 sibling, 0 replies; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-15 19:07 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb

> Date: Mon, 15 Jun 2015 18:56:30 +0100
> From: Pedro Alves <palves@redhat.com>
> CC: gdb@sourceware.org
> 
> On 06/15/2015 06:21 PM, Eli Zaretskii wrote:
> >> Date: Mon, 15 Jun 2015 16:28:14 +0100
> >> From: Pedro Alves <palves@redhat.com>
> >> CC: gdb@sourceware.org
> >>
> >>>> So that should mean that even for GNU/Linux, it should be possible
> >>>> to end in the exact same, when any thread other than the one that we
> >>>> had started the infcall in reports an event that doesn't cause a stop.
> >>>> E.g., a thread specific breakpoint, a "handle nostop" signal, etc.
> >>>
> >>> Does that involve minus_one_ptid on GNU/Linux as well?  If not, that
> >>> call will not mark all threads as running, will it?
> >>
> >> It does.  user_visible_resume_ptid returns the same irrespective
> >> of target_can_async.
> > 
> > Then how come your test program ended up showing just that additional
> > thread running?  You even said you couldn't explain why I saw all my
> > threads running on Windows.
> 
> Because linux-nat.c does not report any event to infrun when a
> thread is created, it just immediately goes back to waiting, unlike
> windows-nat.c, which reports TARGET_WAITKIND_SPURIOUS.  By previous
> test program did not have the new thread trip on any event after
> its creation.

Then perhaps the right solution is not to call discard_cleanups at
that point under any condition, always call do_cleanups.  After all,
all the threads are stopped at that point, so why not register that?

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-15 15:42                 ` Pedro Alves
@ 2015-06-23  4:07                   ` Doug Evans
  2015-06-23 12:19                     ` Pedro Alves
  2015-06-23 14:58                     ` Eli Zaretskii
  0 siblings, 2 replies; 36+ messages in thread
From: Doug Evans @ 2015-06-23  4:07 UTC (permalink / raw)
  To: Pedro Alves; +Cc: Eli Zaretskii, gdb

On Mon, Jun 15, 2015 at 10:42 AM, Pedro Alves <palves@redhat.com> wrote:
>...
> 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.

I dunno if it'd be confusing.
Maybe we could give up on trying to cover up the stopped/running state
of the thread and just let info threads report something closer to
what's actually going on?
An asterisk or some such accompanying the output of threads in
intermediate states may be a sufficient clue to the the user.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-15 17:56                   ` Pedro Alves
  2015-06-15 19:07                     ` Eli Zaretskii
@ 2015-06-23 11:51                     ` Pedro Alves
  1 sibling, 0 replies; 36+ messages in thread
From: Pedro Alves @ 2015-06-23 11:51 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb

On 06/15/2015 06:56 PM, Pedro Alves wrote:

> That's why I said:
> ~~~
> So that should mean that even for GNU/Linux, it should be possible
> to end in the exact same, when any thread other than the one that we
> had started the infcall in reports an event that doesn't cause a stop.
> E.g., a thread specific breakpoint, a "handle nostop" signal, etc.
> ~~~
> 
> And I just confirmed it, with a thread-specific breakpoint that
> trips on the wrong thread, thus, reporting a trap to the core,
> which does not cause a user-visible stop, and then ends up
> marking all threads running when we gdb internally re-resumes
> the program.  Like so:
> 

(...)

FYI, I've converted this to a proper testsuite test, and am
playing with potential fixes.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-23  4:07                   ` Doug Evans
@ 2015-06-23 12:19                     ` Pedro Alves
  2015-06-23 19:11                       ` Pedro Alves
  2015-06-23 14:58                     ` Eli Zaretskii
  1 sibling, 1 reply; 36+ messages in thread
From: Pedro Alves @ 2015-06-23 12:19 UTC (permalink / raw)
  To: Doug Evans; +Cc: Eli Zaretskii, gdb

On 06/23/2015 05:07 AM, Doug Evans wrote:

> Maybe we could give up on trying to cover up the stopped/running state
> of the thread and just let info threads report something closer to
> what's actually going on?
> An asterisk or some such accompanying the output of threads in
> intermediate states may be a sufficient clue to the the user.

I strongly disagree.

Plus, frontends also don't want to be flooded with useless
*running -> *stopped -> *running transitions.

Hiding internal stops isn't the complicated part.  It's the opposite
that is causing problems.  That is, the hiding that threads run at all
when doing an infcall:

 (gdb)
 p malloc (0)
 &"p malloc (0)\n"
 ~"$1 = (void *) 0x602010\n"
 ^done
 (gdb)

Note no *running/*stopped above.

The next question should be: if you do "print sleep (10000)", then
since the thread / threads was/were never marked running, does that mean that
the user/frontend can end up issuing another execution command
that corrupts the ongoing infcall?  The answer is no, but just because
infcalls are always synchronous, so there's no way to issue any command
while an infcall is ongoing anyway.  More about it here:

 https://sourceware.org/ml/gdb-patches/2014-05/msg00273.html

But fixing this bug may require removing the infcall-specific
(pretend-it-doesnt-run) suppressions, resulting in something like:

 (gdb)
 p malloc (0)
 *running,thread-id="all"
 &"p malloc (0)\n"
 ~"$1 = (void *) 0x602010\n"
 *stopped,frame={addr="0x000000000040071c",func="main",args=[{name="argc",value="1"}, (...) ,thread-id="1",stopped-threads="all",core="3" ^done
 (gdb)

I'm playing with tests and potential solutions.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-23  4:07                   ` Doug Evans
  2015-06-23 12:19                     ` Pedro Alves
@ 2015-06-23 14:58                     ` Eli Zaretskii
  1 sibling, 0 replies; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-23 14:58 UTC (permalink / raw)
  To: Doug Evans; +Cc: palves, gdb

> Date: Mon, 22 Jun 2015 23:07:52 -0500
> From: Doug Evans <dje@google.com>
> Cc: Eli Zaretskii <eliz@gnu.org>, gdb <gdb@sourceware.org>
> 
> Maybe we could give up on trying to cover up the stopped/running state
> of the thread and just let info threads report something closer to
> what's actually going on?

Those were my thoughts as well.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-23 12:19                     ` Pedro Alves
@ 2015-06-23 19:11                       ` Pedro Alves
  2015-06-23 19:52                         ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Pedro Alves @ 2015-06-23 19:11 UTC (permalink / raw)
  To: Doug Evans; +Cc: Eli Zaretskii, gdb

On 06/23/2015 01:19 PM, Pedro Alves wrote:
> On 06/23/2015 05:07 AM, Doug Evans wrote:
> 
>> Maybe we could give up on trying to cover up the stopped/running state
>> of the thread and just let info threads report something closer to
>> what's actually going on?
>> An asterisk or some such accompanying the output of threads in
>> intermediate states may be a sufficient clue to the the user.
> 
> I strongly disagree.
> 
> Plus, frontends also don't want to be flooded with useless
> *running -> *stopped -> *running transitions.
> 
> Hiding internal stops isn't the complicated part.  It's the opposite
> that is causing problems.  That is, the hiding that threads run at all
> when doing an infcall:
> 
>  (gdb)
>  p malloc (0)
>  &"p malloc (0)\n"
>  ~"$1 = (void *) 0x602010\n"
>  ^done
>  (gdb)
> 
> Note no *running/*stopped above.
> 
> The next question should be: if you do "print sleep (10000)", then
> since the thread / threads was/were never marked running, does that mean that
> the user/frontend can end up issuing another execution command
> that corrupts the ongoing infcall?  The answer is no, but just because
> infcalls are always synchronous, so there's no way to issue any command
> while an infcall is ongoing anyway.  More about it here:
> 
>  https://sourceware.org/ml/gdb-patches/2014-05/msg00273.html
> 
> But fixing this bug may require removing the infcall-specific
> (pretend-it-doesnt-run) suppressions, resulting in something like:
> 
>  (gdb)
>  p malloc (0)
>  *running,thread-id="all"
>  &"p malloc (0)\n"
>  ~"$1 = (void *) 0x602010\n"
>  *stopped,frame={addr="0x000000000040071c",func="main",args=[{name="argc",value="1"}, (...) ,thread-id="1",stopped-threads="all",core="3" ^done
>  (gdb)
> 
> I'm playing with tests and potential solutions.

This makes GDB mark threads as running while doing an infcall,
and sets them back to stopped when the call finishes.  The MI
event suppression is done elsewhere and isn't really affected.
So I'm leaving MI untouched for now.

Eli, could you give it try to check if this fixes your
case too, please?

(I'll audit for related comments that might need updating and
add an alarm call to the test.)

From 356f189ff985fa53a7ab347590b6ab3ad05c59e2 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Tue, 23 Jun 2015 20:06:26 +0100
Subject: [PATCH] Fix for stale "running" threads.

---
 gdb/infcall.c                                 | 22 ++++++++++
 gdb/infrun.c                                  | 32 +++++++--------
 gdb/testsuite/gdb.threads/threads-infcall.c   | 58 +++++++++++++++++++++++++++
 gdb/testsuite/gdb.threads/threads-infcall.exp | 56 ++++++++++++++++++++++++++
 4 files changed, 151 insertions(+), 17 deletions(-)
 create mode 100644 gdb/testsuite/gdb.threads/threads-infcall.c
 create mode 100644 gdb/testsuite/gdb.threads/threads-infcall.exp

diff --git a/gdb/infcall.c b/gdb/infcall.c
index f79afea..cfdfd3e 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -387,6 +387,7 @@ run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc)
   int saved_in_infcall = call_thread->control.in_infcall;
   ptid_t call_thread_ptid = call_thread->ptid;
   int saved_sync_execution = sync_execution;
+  int was_running = call_thread->state == THREAD_RUNNING;
 
   /* Infcalls run synchronously, in the foreground.  */
   if (target_can_async_p ())
@@ -433,6 +434,27 @@ run_inferior_call (struct thread_info *call_thread, CORE_ADDR real_pc)
      CALL_THREAD as it could be invalid if its thread has exited.  */
   call_thread = find_thread_ptid (call_thread_ptid);
 
+  /* If the infcall does NOT succeed, normal_stop will have already
+     finished the thread states.  However, on success, normal_stop
+     defers here, so that we can set back the thread states to what
+     they were before the call.  We use finish_thread_state instead of
+     set_running to also handle new threads that might have spawned
+     while the call was running -- if stopping, must mark them stopped
+     too.  The main cases to handle are:
+
+     - "(gdb) print foo ()", or any other command that evaluates an
+     expression at the prompt.  (The thread was marked stopped before.)
+
+     - "(gdb) break foo if return_false()" or similar cases where we
+     do an infcall while handling an event (while the thread is still
+     marked running).  In this example, whether the condition
+     evaluates true and thus we'll present a user-visible stop is
+     decided elsewhere.  */
+  if (!was_running
+      && ptid_equal (call_thread_ptid, inferior_ptid)
+      && stop_stack_dummy == STOP_STACK_DUMMY)
+    finish_thread_state (user_visible_resume_ptid (0));
+
   enable_watchpoints_after_interactive_call_stop ();
 
   /* Call breakpoint_auto_delete on the current contents of the bpstat
diff --git a/gdb/infrun.c b/gdb/infrun.c
index d8eb0b0..ca2e066 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -2264,11 +2264,8 @@ resume (enum gdb_signal sig)
 	     requests finish.  The thread is not executing at this
 	     point, and the call to set_executing will be made later.
 	     But we need to call set_running here, since from the
-	     user/frontend's point of view, threads were set running.
-	     Unless we're calling an inferior function, as in that
-	     case we pretend the inferior doesn't run at all.  */
-	  if (!tp->control.in_infcall)
-	    set_running (user_visible_resume_ptid (user_step), 1);
+	     user/frontend's point of view, threads were set running.  */
+	  set_running (user_visible_resume_ptid (user_step), 1);
 	  discard_cleanups (old_cleanups);
 	  return;
 	}
@@ -2346,10 +2343,8 @@ resume (enum gdb_signal sig)
   /* Even if RESUME_PTID is a wildcard, and we end up resuming less
      (e.g., we might need to step over a breakpoint), from the
      user/frontend's point of view, all threads in RESUME_PTID are now
-     running.  Unless we're calling an inferior function, as in that
-     case pretend we inferior doesn't run at all.  */
-  if (!tp->control.in_infcall)
-    set_running (resume_ptid, 1);
+     running.  */
+  set_running (resume_ptid, 1);
 
   /* Maybe resume a single thread after all.  */
   if ((step || thread_has_single_step_breakpoints_set (tp))
@@ -6672,7 +6667,9 @@ normal_stop (void)
      transition changes.  If this is actually a call command, then the
      thread was originally already stopped, so there's no state to
      finish either.  */
-  if (target_has_execution && inferior_thread ()->control.in_infcall)
+  if (target_has_execution
+      && inferior_thread ()->control.in_infcall
+      && stop_stack_dummy == STOP_STACK_DUMMY)
     discard_cleanups (old_chain);
   else
     do_cleanups (old_chain);
@@ -6730,16 +6727,17 @@ normal_stop (void)
 done:
   annotate_stopped ();
 
-  /* Suppress the stop observer if we're in the middle of:
+  /* Suppress the stop observer if an outer layer has special
+     processing for the event.  The possible cases are:
 
-     - a step n (n > 1), as there still more steps to be done.
+     - step n (n > 1), as there still more steps to be done.
 
-     - a "finish" command, as the observer will be called in
-       finish_command_continuation, so it can include the inferior
-       function's return value.
+     - The "finish" command.  The normal_stop observer will be called
+       in finish_command_continuation instead, so it can include the
+       inferior function's return value.
 
-     - calling an inferior function, as we pretend we inferior didn't
-       run at all.  The return value of the call is handled by the
+     - When calling an inferior function, which is always done
+       synchronously.  The return value of the call is handled by the
        expression evaluator, through call_function_by_hand.  */
 
   if (!target_has_execution
diff --git a/gdb/testsuite/gdb.threads/threads-infcall.c b/gdb/testsuite/gdb.threads/threads-infcall.c
new file mode 100644
index 0000000..62fd73b
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/threads-infcall.c
@@ -0,0 +1,58 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2015 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+
+volatile int count;
+
+static int
+foo (void)
+{
+  usleep (1);
+}
+
+static void *
+thread_function (void *arg)
+{
+  pthread_t thread;
+
+  printf ("created thread %d\n", ++count);
+  while (1)
+    {
+      foo ();
+    }
+}
+
+void
+new_thread (void)
+{
+  pthread_t thread;
+
+  pthread_create (&thread, NULL, thread_function, NULL);
+}
+
+int
+main (int argc, char **argv)
+{
+  while (1)
+    {
+      usleep (1);
+    }
+}
diff --git a/gdb/testsuite/gdb.threads/threads-infcall.exp b/gdb/testsuite/gdb.threads/threads-infcall.exp
new file mode 100644
index 0000000..d10c9bb
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/threads-infcall.exp
@@ -0,0 +1,56 @@
+# Copyright (C) 2015 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+standard_testfile
+set executable ${testfile}
+
+# This test verifies that a watchpoint is detected in a multithreaded
+# program so the test is only meaningful on a system with hardware
+# watchpoints.
+if {[skip_hw_watchpoint_tests]} {
+    return 0
+}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" \
+	 executable [list debug "incdir=${objdir}"]] != "" } {
+    return -1
+}
+
+clean_restart $executable
+
+if ![runto_main] {
+    continue
+}
+
+# Set a thread-specific breakpoint that the wrong thread trips on
+# while running the infcall.  Check that no thread ends up in stale
+# "running" state.
+gdb_test "b foo thread 1" "Breakpoint .*$srcfile.*"
+
+for {set i 0} { $i < 3} {incr i} {
+    with_test_prefix "iter $i" {
+	gdb_test "p new_thread ()" ".*"
+
+	set message "no thread marked running"
+	gdb_test_multiple "info threads" $message {
+	    -re ".*running.*$gdb_prompt $" {
+		fail $message
+	    }
+	    -re "$gdb_prompt $" {
+		pass $message
+	    }
+	}
+    }
+}
-- 
1.9.3


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-23 19:11                       ` Pedro Alves
@ 2015-06-23 19:52                         ` Eli Zaretskii
  2015-06-24 14:29                           ` Eli Zaretskii
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-23 19:52 UTC (permalink / raw)
  To: Pedro Alves; +Cc: dje, gdb

> Date: Tue, 23 Jun 2015 20:11:12 +0100
> From: Pedro Alves <palves@redhat.com>
> CC: Eli Zaretskii <eliz@gnu.org>, gdb <gdb@sourceware.org>
> 
> This makes GDB mark threads as running while doing an infcall,
> and sets them back to stopped when the call finishes.  The MI
> event suppression is done elsewhere and isn't really affected.
> So I'm leaving MI untouched for now.
> 
> Eli, could you give it try to check if this fixes your
> case too, please?

Thanks, will do ASAP.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-23 19:52                         ` Eli Zaretskii
@ 2015-06-24 14:29                           ` Eli Zaretskii
  2015-06-29 15:57                             ` Pedro Alves
  0 siblings, 1 reply; 36+ messages in thread
From: Eli Zaretskii @ 2015-06-24 14:29 UTC (permalink / raw)
  To: palves; +Cc: dje, gdb

> Date: Tue, 23 Jun 2015 22:51:52 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: dje@google.com, gdb@sourceware.org
> 
> > Date: Tue, 23 Jun 2015 20:11:12 +0100
> > From: Pedro Alves <palves@redhat.com>
> > CC: Eli Zaretskii <eliz@gnu.org>, gdb <gdb@sourceware.org>
> > 
> > This makes GDB mark threads as running while doing an infcall,
> > and sets them back to stopped when the call finishes.  The MI
> > event suppression is done elsewhere and isn't really affected.
> > So I'm leaving MI untouched for now.
> > 
> > Eli, could you give it try to check if this fixes your
> > case too, please?
> 
> Thanks, will do ASAP.

The patch fixes my case as well.  Thank you very much!

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: Inadvertently run inferior threads
  2015-06-24 14:29                           ` Eli Zaretskii
@ 2015-06-29 15:57                             ` Pedro Alves
  0 siblings, 0 replies; 36+ messages in thread
From: Pedro Alves @ 2015-06-29 15:57 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: dje, gdb

On 06/24/2015 03:28 PM, Eli Zaretskii wrote:

> The patch fixes my case as well.  Thank you very much!

Thanks.  I've pushed it in now:
 https://sourceware.org/ml/gdb-patches/2015-06/msg00607.html

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2015-06-29 15:57 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-12 17:11 Inadvertently run inferior threads 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
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).