[gdb/ChangeLog]
2007-12-19  Chris Demetriou  <cgd@google.com>

        * gdbthread.h (print_thread_events): New variable declaration.
        * thread.c (print_thread_events): New variable definition.
        (show_print_thread_events): New function.
        (_initialize_thread): Add "set print thread-events" and
        "show print thread-events" commands.
        * linux-thread-db.c (check_event): Make attach_thread and
        detach_thread be verbose only if print_thread_events is set.

[gdb/doc/ChangeLog]
2007-12-19  Chris Demetriou  <cgd@google.com>

        * gdb.texinfo (Threads): Document new "set print thread-events"
        and "show print thread-events" commands.

[gdb/testsuite/ChangeLog]
2007-12-19  Chris Demetriou  <cgd@google.com>

        * gdb.threads/thread_events.c: New testcase source file.
        * gdb.threads/thread_events.exp: New testcase expect file.


Index: gdbthread.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbthread.h,v
retrieving revision 1.17
diff -u -u -p -r1.17 gdbthread.h
--- gdbthread.h	6 Dec 2007 12:57:51 -0000	1.17
+++ gdbthread.h	20 Dec 2007 00:05:56 -0000
@@ -141,4 +141,8 @@ extern void switch_to_thread (ptid_t pti
 /* Commands with a prefix of `thread'.  */
 extern struct cmd_list_element *thread_cmd_list;
 
+/* Print notices on thread events (attach, detach, etc.), set with
+   `set print thread-events'.  */
+extern int print_thread_events;
+
 #endif /* GDBTHREAD_H */
Index: linux-thread-db.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-thread-db.c,v
retrieving revision 1.35
diff -u -u -p -r1.35 linux-thread-db.c
--- linux-thread-db.c	25 Oct 2007 22:09:34 -0000	1.35
+++ linux-thread-db.c	20 Dec 2007 00:05:56 -0000
@@ -843,7 +843,7 @@ check_event (ptid_t ptid)
 	case TD_CREATE:
 	  /* Call attach_thread whether or not we already know about a
 	     thread with this thread ID.  */
-	  attach_thread (ptid, msg.th_p, &ti, 1);
+	  attach_thread (ptid, msg.th_p, &ti, print_thread_events);
 
 	  break;
 
@@ -852,7 +852,7 @@ check_event (ptid_t ptid)
 	  if (!in_thread_list (ptid))
 	    error (_("Spurious thread death event."));
 
-	  detach_thread (ptid, 1);
+	  detach_thread (ptid, print_thread_events);
 
 	  break;
 
Index: thread.c
===================================================================
RCS file: /cvs/src/src/gdb/thread.c,v
retrieving revision 1.57
diff -u -u -p -r1.57 thread.c
--- thread.c	6 Dec 2007 12:57:51 -0000	1.57
+++ thread.c	20 Dec 2007 00:05:56 -0000
@@ -675,6 +675,17 @@ thread_command (char *tidstr, int from_t
   gdb_thread_select (uiout, tidstr, NULL);
 }
 
+/* Print notices when new threads are attached and detached.  */
+int print_thread_events = 1;
+static void
+show_print_thread_events (struct ui_file *file, int from_tty,
+                          struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("\
+Printing of thread events is %s.\n"),
+                    value);
+}
+
 static int
 do_captured_thread_select (struct ui_out *uiout, void *tidstr)
 {
@@ -737,4 +748,12 @@ The new thread ID must be currently know
 
   if (!xdb_commands)
     add_com_alias ("t", "thread", class_run, 1);
+
+  add_setshow_boolean_cmd ("thread-events", no_class,
+         &print_thread_events, _("\
+Set printing of thread events (e.g., thread start and exit)."), _("\
+Show printing of thread events (e.g., thread start and exit)."), NULL,
+         NULL,
+         show_print_thread_events,
+         &setprintlist, &showprintlist);
 }
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.453
diff -u -u -p -r1.453 gdb.texinfo
--- doc/gdb.texinfo	18 Dec 2007 18:11:09 -0000	1.453
+++ doc/gdb.texinfo	20 Dec 2007 00:05:56 -0000
@@ -2241,6 +2241,8 @@ programs:
 @item @samp{thread apply [@var{threadno}] [@var{all}] @var{args}},
 a command to apply a command to a list of threads
 @item thread-specific breakpoints
+@item @samp{set print thread-events}, which controls printing of 
+messages on thread start and exit.
 @end itemize
 
 @quotation
@@ -2434,6 +2436,22 @@ threads that you want affected with the 
 shown in the first field of the @samp{info threads} display; or it
 could be a range of thread numbers, as in @code{2-4}.  To apply a
 command to all threads, type @kbd{thread apply all @var{command}}.
+
+@kindex set print thread-events
+@cindex print messages on thread start and exit
+@item set print thread-events
+@itemx set print thread-events on
+@itemx set print thread-events off
+The @code{set print thread-attach} command allows you to enable or
+disable printing of messages when GDB notices that new threads have
+started or that threads have exited.  By default, these messages will
+be printed if detection of these events is supported by the target.
+Note that these messages cannot be disabled on all targets.
+
+@kindex show print thread-events
+@item show print thread-events
+Show whether messages will be printed when GDB detects that threads
+have started and exited.
 @end table
 
 @cindex automatic thread selection
Index: testsuite/gdb.threads/thread_events.c
===================================================================
RCS file: testsuite/gdb.threads/thread_events.c
diff -N testsuite/gdb.threads/thread_events.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.threads/thread_events.c	20 Dec 2007 00:05:56 -0000
@@ -0,0 +1,55 @@
+/* Copyright (C) 2007 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/>.
+
+   This file was written by Chris Demetriou (cgd@google.com).  */
+
+/* Simple test to trigger thread events (thread start, thread exit).  */
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static void *
+threadfunc (void *arg)
+{
+  printf ("in threadfunc\n");
+  return NULL;
+}
+
+static void
+after_join_func (void)
+{
+  printf ("finished\n");
+}
+
+int main (int argc, char *argv[])
+{
+  pthread_t thread;
+
+  if (pthread_create(&thread, NULL, threadfunc, NULL) != 0)
+    {
+      printf ("pthread_create failed\n");
+      exit (1);
+    }
+
+  if (pthread_join (thread, NULL) != 0)
+    {
+      printf ("pthread_join failed\n");
+      exit (1);
+    }
+
+  after_join_func();
+  return 0;
+}
Index: testsuite/gdb.threads/thread_events.exp
===================================================================
RCS file: testsuite/gdb.threads/thread_events.exp
diff -N testsuite/gdb.threads/thread_events.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.threads/thread_events.exp	20 Dec 2007 00:05:56 -0000
@@ -0,0 +1,149 @@
+# Copyright (C) 2007 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/>.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Chris Demetriou (cgd@google.com).
+# It tests printing of thread event (start, exit) information, and
+# disabling of those messages.
+#
+# Note: the format of thread event messages (and also whether or not
+# messages are printed and can be disabled) is dependent on the target
+# thread support code.
+
+# This test has only been verified with Linux targets, and would need
+# to be generalized to support other targets
+if ![istarget *-*-linux*] then {
+    return
+}
+
+if $tracelevel then {
+        strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "thread_events"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } {
+    return -1
+}
+
+proc gdb_test_thread_start {messages_enabled command pattern message} {
+  global gdb_prompt
+
+  if { $messages_enabled } {
+    set events_expected 1
+  } else {
+    set events_expected 0
+  }
+  set events_seen 0
+
+  return [gdb_test_multiple $command $message {
+    -re "\\\[New Thread \[^\]\]*\\\]\r\n" {
+      incr events_seen;
+      exp_continue;
+    }
+    -re "\[\r\n\]*($pattern)\[\r\n\]+$gdb_prompt $" {
+      if { $events_seen != $events_expected } {
+        fail "$message (saw $events_seen, expected $events_expected)"
+      } else {
+        pass "$message"
+      }
+    }
+  }]
+}
+
+proc gdb_test_thread_exit {messages_enabled command pattern message} {
+  global gdb_prompt
+
+  if { $messages_enabled } {
+    set events_expected 1
+  } else {
+    set events_expected 0
+  }
+  set events_seen 0
+
+  return [gdb_test_multiple $command $message {
+    -re "\\\[Thread \[^\]\]* exited\\\]\r\n" {
+      incr events_seen
+      exp_continue;
+    }
+    -re "\[\r\n\]*($pattern)\[\r\n\]+$gdb_prompt $" {
+      if { $events_seen != $events_expected } {
+        fail "$message (saw $events_seen, expected $events_expected)"
+      } else {
+        pass "$message"
+      }
+    }
+  }]
+}
+
+proc test_thread_messages {enabled} {
+  global srcdir subdir binfile srcfile
+
+  if { $enabled } {
+    set enabled_string "with messages enabled"
+  } else {
+    set enabled_string "with messages disabled"
+  }
+
+  gdb_start
+  gdb_reinitialize_dir $srcdir/$subdir
+  gdb_load ${binfile}
+
+  if { $enabled } {
+     gdb_test "set print thread-events on"
+  } else {
+     gdb_test "set print thread-events off"
+  }
+
+  # The initial thread may log a 'New Thread' message, but we don't
+  # check for it.
+  if ![runto_main] then {
+     fail "Can't run to main $enabled_string"
+     return 1
+  }
+
+  gdb_test "break threadfunc" \
+      "Breakpoint.*at.* file .*$srcfile, line.*" \
+      "breakpoint at threadfunc $enabled_string"
+  gdb_test "break after_join_func" \
+      "Breakpoint.*at.* file .*$srcfile, line.*" \
+      "breakpoint at after_join_func $enabled_string"
+
+  # continue to threadfunc breakpoint.  A thread will start.
+  # Expect to see a thread start message, if messages are enabled.
+  gdb_test_thread_start $enabled "continue" \
+       ".*Breakpoint .*,.*threadfunc.*at.*$srcfile:.*" \
+       "continue to threadfunc $enabled_string"
+
+  # continue to after_join_func breakpoint.  A thread will exit.
+  # Expect to see a thread exit message, if messages are enabled.
+  gdb_test_thread_exit $enabled "continue" \
+       ".*Breakpoint .*,.*after_join_func.*at.*$srcfile:.*" \
+       "continue to after_join_func $enabled_string"
+
+  delete_breakpoints
+
+  gdb_exit
+}
+
+test_thread_messages 0
+test_thread_messages 1
