aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorVladimir Prus <vladimir@codesourcery.com>2008-01-23 11:26:29 +0000
committerVladimir Prus <vladimir@codesourcery.com>2008-01-23 11:26:29 +0000
commit93815fbfa5134025806e16f0897efc8424bf4586 (patch)
tree8c633b007b8b7fbc6d0363b951aec6670e65c7d8 /gdb
parent73f4030dfa279eb7afc5a6c93a752aefbdb0de35 (diff)
downloadgdb-93815fbfa5134025806e16f0897efc8424bf4586.zip
gdb-93815fbfa5134025806e16f0897efc8424bf4586.tar.gz
gdb-93815fbfa5134025806e16f0897efc8424bf4586.tar.bz2
Inform about new thread in a single place.
* thread.c (add_thread_silent): Renamed from add_thread. (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. (add_thread): Announce new thread. * gdbthread.h (add_thread_silent): Declare. (print_thread_events): New variable declaration. * inf-ttrace.c (inf_ttrace_wait): Don't inform about new thread, as add_thread is always called too, and will take care of that. * infrun.c (handle_inferior_event): Likewise. * procfs.c (procfs_wait): Likewise. * remote.c (remote_currthread): Likewise. * sol-thread.c (sol_thread_wait): Likewise. * win32-nat.c (get_win32_debug_event): Likewise. * linux-thread-db.c (attach_thread): Likewise. Remove the verbose parameter. (check_event): Make detach_thread be verbose only if print_thread_events is set. * linux-nat.c (lin_lwp_attach_lwp): Don't inform about new thread. This is called only from linux-thread-db.c:attach_thread, which will take care. Remove the verbose parameter. * linux-nat.h (lin_lwp_attach_lwp): Adjust prototype.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog30
-rw-r--r--gdb/bsd-uthread.c2
-rw-r--r--gdb/doc/ChangeLog5
-rw-r--r--gdb/doc/gdb.texinfo18
-rw-r--r--gdb/gdbthread.h15
-rw-r--r--gdb/inf-ttrace.c1
-rw-r--r--gdb/infrun.c8
-rw-r--r--gdb/linux-nat.c7
-rw-r--r--gdb/linux-nat.h2
-rw-r--r--gdb/linux-thread-db.c17
-rw-r--r--gdb/procfs.c14
-rw-r--r--gdb/remote.c7
-rw-r--r--gdb/sol-thread.c5
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.threads/thread_events.c55
-rw-r--r--gdb/testsuite/gdb.threads/thread_events.exp155
-rw-r--r--gdb/thread.c35
-rw-r--r--gdb/win32-nat.c4
-rw-r--r--gdb/windows-nat.c4
19 files changed, 327 insertions, 62 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 0b7b9b8..3468f04 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,33 @@
+2008-01-23 Vladimir Prus <vladimir@codesourcery.com>
+ Chris Demetriou <cgd@google.com>
+
+ * thread.c (add_thread_silent): Renamed
+ from add_thread.
+ (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.
+ (add_thread): Announce new thread.
+ * gdbthread.h (add_thread_silent): Declare.
+ (print_thread_events): New variable declaration.
+ * inf-ttrace.c (inf_ttrace_wait): Don't
+ inform about new thread, as add_thread is always
+ called too, and will take care of that.
+ * infrun.c (handle_inferior_event): Likewise.
+ * procfs.c (procfs_wait): Likewise.
+ * remote.c (remote_currthread): Likewise.
+ * sol-thread.c (sol_thread_wait): Likewise.
+ * win32-nat.c (get_win32_debug_event): Likewise.
+ * linux-thread-db.c (attach_thread): Likewise.
+ Remove the verbose parameter.
+ (check_event): Make detach_thread be verbose
+ only if print_thread_events is set.
+ * linux-nat.c (lin_lwp_attach_lwp): Don't inform
+ about new thread. This is called only from
+ linux-thread-db.c:attach_thread, which will take care.
+ Remove the verbose parameter.
+ * linux-nat.h (lin_lwp_attach_lwp): Adjust prototype.
+
2008-01-23 Nick Roberts <nickrob@snap.net.nz>
* mi/mi-cmd-var.c (mi_cmd_var_set_format): Add value field to output.
diff --git a/gdb/bsd-uthread.c b/gdb/bsd-uthread.c
index 074f06c..a15c78f 100644
--- a/gdb/bsd-uthread.c
+++ b/gdb/bsd-uthread.c
@@ -366,7 +366,7 @@ bsd_uthread_wait (ptid_t ptid, struct target_waitstatus *status)
if (ptid_get_tid (ptid) != 0 && !in_thread_list (ptid)
&& ptid_get_tid (inferior_ptid) == 0)
{
- add_thread (ptid);
+ add_thread_silent (ptid);
inferior_ptid = ptid;
}
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index e4ec2e2..37736a0 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2008-01-23 Chris Demetriou <cgd@google.com>
+
+ * gdb.texinfo (Threads): Document new "set print thread-events"
+ and "show print thread-events" commands.
+
2008-01-19 Eli Zaretskii <eliz@gnu.org>
* gdb.texinfo (Specify Location): New section.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 32562e5..434f48a 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -2238,6 +2238,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
@@ -2431,6 +2433,22 @@ threads that you want affected with the command argument
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-events} command allows you to enable or
+disable printing of messages when @value{GDBN} 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 @value{GDBN} detects that threads
+have started and exited.
@end table
@cindex automatic thread selection
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index 86646b3..dd4345a 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -69,11 +69,16 @@ struct thread_info
/* Create an empty thread list, or empty the existing one. */
extern void init_thread_list (void);
-/* Add a thread to the thread list.
- Note that add_thread now returns the handle of the new thread,
- so that the caller may initialize the private thread data. */
+/* Add a thread to the thread list, print a message
+ that a new thread is found, and return the pointer to
+ the new thread. Caller my use this pointer to
+ initialize the private thread data. */
extern struct thread_info *add_thread (ptid_t ptid);
+/* Same as add_thread, but does not print a message
+ about new thread. */
+extern struct thread_info *add_thread_silent (ptid_t ptid);
+
/* Delete an existing thread list entry. */
extern void delete_thread (ptid_t);
@@ -141,4 +146,8 @@ extern void switch_to_thread (ptid_t ptid);
/* 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 */
diff --git a/gdb/inf-ttrace.c b/gdb/inf-ttrace.c
index 03b3e7d..4f8b45f 100644
--- a/gdb/inf-ttrace.c
+++ b/gdb/inf-ttrace.c
@@ -962,7 +962,6 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
sizeof (struct inf_ttrace_private_thread_info));
inf_ttrace_num_lwps++;
}
- printf_filtered (_("[New %s]\n"), target_pid_to_str (ptid));
ti = add_thread (ptid);
ti->private =
xmalloc (sizeof (struct inf_ttrace_private_thread_info));
diff --git a/gdb/infrun.c b/gdb/infrun.c
index d28d43f..942fb7d 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1331,13 +1331,7 @@ handle_inferior_event (struct execution_control_state *ecs)
if (ecs->ws.kind != TARGET_WAITKIND_EXITED
&& ecs->ws.kind != TARGET_WAITKIND_SIGNALLED && ecs->new_thread_event)
- {
- add_thread (ecs->ptid);
-
- ui_out_text (uiout, "[New ");
- ui_out_text (uiout, target_pid_to_str (ecs->ptid));
- ui_out_text (uiout, "]\n");
- }
+ add_thread (ecs->ptid);
switch (ecs->ws.kind)
{
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index b79e40f..4f75ad9 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -871,7 +871,7 @@ exit_lwp (struct lwp_info *lp)
be attached. */
int
-lin_lwp_attach_lwp (ptid_t ptid, int verbose)
+lin_lwp_attach_lwp (ptid_t ptid)
{
struct lwp_info *lp;
@@ -956,9 +956,6 @@ lin_lwp_attach_lwp (ptid_t ptid, int verbose)
lp->stopped = 1;
}
- if (verbose)
- printf_filtered (_("[New %s]\n"), target_pid_to_str (ptid));
-
return 0;
}
@@ -2090,8 +2087,6 @@ retry:
}
add_thread (lp->ptid);
- printf_unfiltered (_("[New %s]\n"),
- target_pid_to_str (lp->ptid));
}
/* Save the trap's siginfo in case we need it later. */
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index d8389a7..8ae5ab3 100644
--- a/gdb/linux-nat.h
+++ b/gdb/linux-nat.h
@@ -95,7 +95,7 @@ void linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked,
/* linux-nat functions for handling fork events. */
extern void linux_enable_event_reporting (ptid_t ptid);
-extern int lin_lwp_attach_lwp (ptid_t ptid, int verbose);
+extern int lin_lwp_attach_lwp (ptid_t ptid);
/* Iterator function for lin-lwp's lwp list. */
struct lwp_info *iterate_over_lwps (int (*callback) (struct lwp_info *,
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index ba9da46..a653bed 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -118,7 +118,7 @@ static CORE_ADDR td_death_bp_addr;
/* Prototypes for local functions. */
static void thread_db_find_new_threads (void);
static void attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
- const td_thrinfo_t *ti_p, int verbose);
+ const td_thrinfo_t *ti_p);
static void detach_thread (ptid_t ptid, int verbose);
@@ -279,7 +279,7 @@ thread_get_info_callback (const td_thrhandle_t *thp, void *infop)
if (thread_info == NULL)
{
/* New thread. Attach to it now (why wait?). */
- attach_thread (thread_ptid, thp, &ti, 1);
+ attach_thread (thread_ptid, thp, &ti);
thread_info = find_thread_pid (thread_ptid);
gdb_assert (thread_info != NULL);
}
@@ -670,7 +670,7 @@ thread_db_new_objfile (struct objfile *objfile)
static void
attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
- const td_thrinfo_t *ti_p, int verbose)
+ const td_thrinfo_t *ti_p)
{
struct thread_info *tp;
td_err_e err;
@@ -702,7 +702,7 @@ attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
return; /* A zombie thread -- do not attach. */
/* Under GNU/Linux, we have to attach to each and every thread. */
- if (lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid)), 0) < 0)
+ if (lin_lwp_attach_lwp (BUILD_LWP (ti_p->ti_lid, GET_PID (ptid))) < 0)
return;
/* Add the thread to GDB's thread list. */
@@ -710,9 +710,6 @@ attach_thread (ptid_t ptid, const td_thrhandle_t *th_p,
tp->private = xmalloc (sizeof (struct private_thread_info));
memset (tp->private, 0, sizeof (struct private_thread_info));
- if (verbose)
- printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid));
-
/* Enable thread event reporting for this thread. */
err = td_thr_event_enable_p (th_p, 1);
if (err != TD_OK)
@@ -843,7 +840,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);
break;
@@ -852,7 +849,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;
@@ -976,7 +973,7 @@ find_new_threads_callback (const td_thrhandle_t *th_p, void *data)
}
if (!in_thread_list (ptid))
- attach_thread (ptid, th_p, &ti, 1);
+ attach_thread (ptid, th_p, &ti);
return 0;
}
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 3b6e599..1c80e19 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -4119,11 +4119,8 @@ wait_again:
temp_ptid = MERGEPID (pi->pid, temp_tid);
/* If not in GDB's thread list, add it. */
if (!in_thread_list (temp_ptid))
- {
- printf_filtered (_("[New %s]\n"),
- target_pid_to_str (temp_ptid));
- add_thread (temp_ptid);
- }
+ add_thread (temp_ptid);
+
/* Return to WFI, but tell it to immediately resume. */
status->kind = TARGET_WAITKIND_SPURIOUS;
return inferior_ptid;
@@ -4189,11 +4186,7 @@ wait_again:
/* If not in GDB's thread list, add it. */
temp_ptid = MERGEPID (pi->pid, temp_tid);
if (!in_thread_list (temp_ptid))
- {
- printf_filtered (_("[New %s]\n"),
- target_pid_to_str (temp_ptid));
- add_thread (temp_ptid);
- }
+ add_thread (temp_ptid);
status->kind = TARGET_WAITKIND_STOPPED;
status->value.sig = 0;
@@ -4280,7 +4273,6 @@ wait_again:
* If we don't create a procinfo, resume may be unhappy
* later.
*/
- printf_filtered (_("[New %s]\n"), target_pid_to_str (retval));
add_thread (retval);
if (find_procinfo (PIDGET (retval), TIDGET (retval)) == NULL)
create_procinfo (PIDGET (retval), TIDGET (retval));
diff --git a/gdb/remote.c b/gdb/remote.c
index 1ea5d55..eefea2e 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -1049,12 +1049,7 @@ record_currthread (int currthread)
/* If this is a new thread, add it to GDB's thread list.
If we leave it up to WFI to do this, bad things will happen. */
if (!in_thread_list (pid_to_ptid (currthread)))
- {
- add_thread (pid_to_ptid (currthread));
- ui_out_text (uiout, "[New ");
- ui_out_text (uiout, target_pid_to_str (pid_to_ptid (currthread)));
- ui_out_text (uiout, "]\n");
- }
+ add_thread (pid_to_ptid (currthread));
}
static char *last_pass_packet;
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index 3142b2a..796065d 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -461,10 +461,7 @@ sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
if (is_thread (rtnval)
&& !ptid_equal (rtnval, save_ptid)
&& !in_thread_list (rtnval))
- {
- printf_filtered ("[New %s]\n", target_pid_to_str (rtnval));
- add_thread (rtnval);
- }
+ add_thread (rtnval);
}
/* During process initialization, we may get here without the thread
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index f978277..bcbd355 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-01-23 Chris Demetriou <cgd@google.com>
+
+ * gdb.threads/thread_events.c: New testcase source file.
+ * gdb.threads/thread_events.exp: New testcase expect file.
+
2008-01-23 Nick Roberts <nickrob@snap.net.nz>
* lib/gdb.exp: Add the variable octal.
diff --git a/gdb/testsuite/gdb.threads/thread_events.c b/gdb/testsuite/gdb.threads/thread_events.c
new file mode 100644
index 0000000..9b7edcd
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/thread_events.c
@@ -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;
+}
diff --git a/gdb/testsuite/gdb.threads/thread_events.exp b/gdb/testsuite/gdb.threads/thread_events.exp
new file mode 100644
index 0000000..bd39b78
--- /dev/null
+++ b/gdb/testsuite/gdb.threads/thread_events.exp
@@ -0,0 +1,155 @@
+# 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
+}
+
+# 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
+}
+
+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
diff --git a/gdb/thread.c b/gdb/thread.c
index c4ce608..2fdfa77 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -116,11 +116,8 @@ init_thread_list (void)
thread_list = NULL;
}
-/* add_thread now returns a pointer to the new thread_info,
- so that back_ends can initialize their private data. */
-
struct thread_info *
-add_thread (ptid_t ptid)
+add_thread_silent (ptid_t ptid)
{
struct thread_info *tp;
@@ -133,6 +130,17 @@ add_thread (ptid_t ptid)
return tp;
}
+struct thread_info *
+add_thread (ptid_t ptid)
+{
+ struct thread_info *result = add_thread_silent (ptid);
+
+ if (print_thread_events)
+ printf_filtered (_("[New %s]\n"), target_pid_to_str (ptid));
+
+ return result;
+}
+
void
delete_thread (ptid_t ptid)
{
@@ -675,6 +683,17 @@ thread_command (char *tidstr, int from_tty)
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 +756,12 @@ The new thread ID must be currently known."),
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);
}
diff --git a/gdb/win32-nat.c b/gdb/win32-nat.c
index e8c2bed..061430b 100644
--- a/gdb/win32-nat.c
+++ b/gdb/win32-nat.c
@@ -1311,10 +1311,6 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus)
/* Record the existence of this thread */
th = win32_add_thread (current_event.dwThreadId,
current_event.u.CreateThread.hThread);
- if (info_verbose)
- printf_unfiltered ("[New %s]\n",
- target_pid_to_str (
- pid_to_ptid (current_event.dwThreadId)));
retval = current_event.dwThreadId;
break;
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index e8c2bed..061430b 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -1311,10 +1311,6 @@ get_win32_debug_event (int pid, struct target_waitstatus *ourstatus)
/* Record the existence of this thread */
th = win32_add_thread (current_event.dwThreadId,
current_event.u.CreateThread.hThread);
- if (info_verbose)
- printf_unfiltered ("[New %s]\n",
- target_pid_to_str (
- pid_to_ptid (current_event.dwThreadId)));
retval = current_event.dwThreadId;
break;