This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix threads left stopped after fork+thread spawn (PR threads/18600)


On 07/23/2015 12:04 PM, Pedro Alves wrote:

> Thanks Simon.  I'm playing with this.  I made the test run run against
> extended-remote gdbserver, and that caught several issues with
> non-stop + the new remote follow-fork support.

So one of the changes I had done was to run to a breakpoint at the end
of main instead of letting inferior 1 exit.  That exposes gdbserver
crashes.  I have fixes for that, but I'm a bit reluctant to put them
in 7.10, so I'll post them for master only.  Reverting that change to
use a breakpoint still shows other bogus things against gdbserver, but the
test still passes.  E.g., all the "[Thread FOO] #NN stopped." below are bogus
(it's a gdbserver bug), and note the "Cannot remove breakpoints because
program is no longer writable." too:

(gdb) PASS: gdb.threads/fork-plus-threads.exp: set detach-on-fork off
continue &
Continuing.
(gdb) PASS: gdb.threads/fork-plus-threads.exp: continue &
[New Thread 28092.28092]

[Thread 28092.28092] #2 stopped.
[New Thread 28094.28094]
[Inferior 2 (process 28092) exited normally]
[New Thread 28094.28105]
[New Thread 28094.28109]

[Thread 28094.28094] #3 stopped.
[New Thread 28106.28106]
[Inferior 3 (process 28094) exited normally]
[New Thread 28106.28117]

[Thread 28106.28106] #6 stopped.
[New Thread 28118.28118]
[Inferior 4 (process 28106) exited normally]
[New Thread 28118.28132]

[Thread 28118.28118] #8 stopped.
[New Thread 28128.28128]
[Inferior 5 (process 28118) exited normally]
[New Thread 28128.28145]

[Thread 28128.28128] #10 stopped.
[New Thread 28141.28141]
[Inferior 6 (process 28128) exited normally]
[New Thread 28141.28159]

[Thread 28141.28141] #12 stopped.
[New Thread 28151.28151]
[Inferior 7 (process 28141) exited normally]
[New Thread 28151.28165]

[Thread 28151.28151] #14 stopped.
[New Thread 28162.28162]
[Inferior 8 (process 28151) exited normally]
[New Thread 28162.28162]

[Thread 28162.28162] #17 stopped.
[New Thread 28174.28174]
[Inferior 9 (process 28162) exited normally]
[New Thread 28174.28191]

[Thread 28174.28174] #18 stopped.
[New Thread 28185.28185]
[Inferior 10 (process 28174) exited normally]
[New Thread 28185.28196]

[Thread 28185.28185] #20 stopped.
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
[Inferior 11 (process 28185) exited normally]
[Inferior 1 (process 28091) exited normally]
PASS: gdb.threads/fork-plus-threads.exp: reached breakpoint
info threads
No threads.
(gdb) PASS: gdb.threads/fork-plus-threads.exp: no threads left
info inferiors
  Num  Description       Executable
* 1    <null>            /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.threads/fork-plus-threads
(gdb) PASS: gdb.threads/fork-plus-threads.exp: only inferior 1 left


So that we're in the same page, I'm replying with a few comments to the
original patch below, and then I'll post updated patches with the
points I raise addressed, but split in separate patches, one for each
of the problems identified.  That will include a test for the second
issue as well.

Many thanks for the test, and writing ChangeLogs, etc.!


On 07/21/2015 04:35 PM, Simon Marchi wrote:
 I tried to make a test for this situation, but it's been a bit more
> difficult than I expected.  The idea is that the inferior forks a
> certain number of times and waits for all children to exit.  Each fork
> child spawns a number of threads that do nothing and joins them
> immediately.  Normally, the program should run unimpeded (from the point
> of view of the user) and exit very quickly.  Without this fix, it
> doesn't because of some threads left stopped by gdb.  My only problem is
> that the prompt comes back as soon as any inferior (even a child) exits,
> and that moment is too early to say if the test passed or not.  I had to
> resort to make it sleep for a second and then check that no thread is
> left.  If you have suggestions on how to make the test more robust, they
> are very welcome.

We can instead wait for the "inferior 1 exited normally" output.
On a buggy gdb, inferior 1 won't ever exit, stuck waiting for the
children to exit.

> +++ b/gdb/testsuite/gdb.threads/fork-plus-threads.c
> @@ -0,0 +1,94 @@
> +#include <assert.h>
> +#include <pthread.h>

Missing copyright header.

> +#include <stdio.h>
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +
> +


> +int
> +main (void)
> +{
> +  pid_t childs[NFORKS];
> +  int i;
> +  int status;
> +  int num_exited = 0;


We should have an "alarm()" call here, so that if something goes
wrong, the process eventually kills itself.


> +# The problem was originally seen on Linux, but the test could be
> +# generalized to all targets that support forks and threads.
> +if ![istarget *-*-linux*] then {
> +    return
> +}

The problem with these checks is that most probably nobody will
ever relax them.  Targets that don't support fork or threads at all
will fail to compile the test, which results in the test being
skipped already.  So I think we should just start by running the
test everywhere.

> +
> +# When using gdbserver, even on Linux, we don't get notifications
> +# about new threads.  This is expected, so don't test for that.
> +if [is_remote target] then {
> +    return
> +}

I'm not seeing why thread notifications would be required,
but in any case, extended-remote supports follow fork
nowadays, so I think we should remove this check too.

> +
> +standard_testfile
> +
> +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable debug] != "" } {
> +    return -1
> +}
> +
> +clean_restart ${binfile}
> +
> +gdb_test_no_output "set non-stop on"

The native-extended-gdbserver board starts gdbserver
and connects to with from within clean_restart, so this
"set non-stop on" here is too late, though.  The easy fix
is to push '-ex "set non-stop on"' in GDBFLAGS instead.

Thanks,
Pedro Alves


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]