Re: Inadvertently run inferior threads

Pedro Alves <[email protected]>
Newsgroups gmane.comp.gdb.devel
Message-ID <[email protected]>
On 06/15/2015 06:21 PM, Eli Zaretskii wrote:
>> Date: Mon, 15 Jun 2015 16:28:14 +0100
>> From: Pedro Alves <[email protected]>
>> CC: [email protected]
>>
>>>> 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.