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.
This commit is contained in:
parent
73f4030dfa
commit
93815fbfa5
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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. */
|
||||
|
@ -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 *,
|
||||
|
@ -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;
|
||||
}
|
||||
|
14
gdb/procfs.c
14
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));
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
55
gdb/testsuite/gdb.threads/thread_events.c
Normal file
55
gdb/testsuite/gdb.threads/thread_events.c
Normal file
@ -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;
|
||||
}
|
155
gdb/testsuite/gdb.threads/thread_events.exp
Normal file
155
gdb/testsuite/gdb.threads/thread_events.exp
Normal file
@ -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
|
35
gdb/thread.c
35
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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user