+2015-02-06  Pedro Alves  <palves@redhat.com>
+
+       * gdb.threads/attach-many-short-lived-threads.c (SECONDS): New
+       macro.
+       (seconds_left, again): New globals.
+       (main): Wait seconds_left in a 1-second sleep loop instead of
+       sleeping 180 seconds.  If 'again' is set, reset the seconds
+       counter.
+       * gdb.threads/attach-many-short-lived-threads.exp (test): Set
+       'again' in the inferior before detaching.  Print the seconds left.
+       (options): New global.
+       (top level): Build program with -DTIMEOUT=$timeout.
+
 2015-02-06  Pedro Alves  <palves@redhat.com>
 
        * gdb.base/gdb-sigterm.c (main): Use the TIMEOUT define to
 
   return NULL;
 }
 
+/* Allow for as much timeout as DejaGnu wants, plus a bit of
+   slack.  */
+#define SECONDS (TIMEOUT + 20)
+
+/* We'll exit after this many seconds.  */
+unsigned int seconds_left = SECONDS;
+
+/* GDB sets this whenever it's about to start a new detach/attach
+   sequence.  We react by resetting the seconds left counter.  */
+volatile int again = 0;
+
 int
 main (int argc, char *argv[])
 {
       create_thread (&detached_attr, detached_fn, NULL);
     }
 
-  /* Long enough for all the attach/detach sequences done by the .exp
-     file.  */
-  sleep (180);
+  /* Exit after a while if GDB is gone/crashes.  But wait long enough
+     for one attach/detach sequence done by the .exp file.  */
+  while (--seconds_left > 0)
+    {
+      sleep (1);
+
+      if (again)
+       {
+         /* GDB should be reattaching soon.  Restart the timer.  */
+         again = 0;
+         seconds_left = SECONDS;
+       }
+    }
+
+  printf ("timeout, exiting\n");
   return 0;
 }
 
            }
 
            if {$attempt < $attempts} {
+               # Kick the time out timer for another round.
+               gdb_test "print again = 1" " = 1" "reset timer in the inferior"
+               # Show the time we had left in the logs, in case
+               # something goes wrong.
+               gdb_test "print seconds_left" " = .*"
+
                gdb_test "detach" "Detaching from.*"
            } else {
                gdb_test "kill" "" "kill process" "Kill the program being debugged.*y or n. $" "y"
     remote_exec target "kill -9 ${testpid}"
 }
 
-if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug pthreads}] == -1} {
+# The test program exits after a while, in case GDB crashes.  Make it
+# wait at least as long as we may wait before declaring a time out
+# failure.
+set options { "additional_flags=-DTIMEOUT=$timeout" debug pthreads }
+
+if {[prepare_for_testing "failed to prepare" $testfile $srcfile $options] == -1} {
     return -1
 }