1*5796c8dcSSimon Schubert /* Multi-process/thread control for GDB, the GNU debugger. 2*5796c8dcSSimon Schubert 3*5796c8dcSSimon Schubert Copyright (C) 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 4*5796c8dcSSimon Schubert 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009 5*5796c8dcSSimon Schubert Free Software Foundation, Inc. 6*5796c8dcSSimon Schubert 7*5796c8dcSSimon Schubert Contributed by Lynx Real-Time Systems, Inc. Los Gatos, CA. 8*5796c8dcSSimon Schubert 9*5796c8dcSSimon Schubert This file is part of GDB. 10*5796c8dcSSimon Schubert 11*5796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify 12*5796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by 13*5796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or 14*5796c8dcSSimon Schubert (at your option) any later version. 15*5796c8dcSSimon Schubert 16*5796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 17*5796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 18*5796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19*5796c8dcSSimon Schubert GNU General Public License for more details. 20*5796c8dcSSimon Schubert 21*5796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 22*5796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */ 23*5796c8dcSSimon Schubert 24*5796c8dcSSimon Schubert #include "defs.h" 25*5796c8dcSSimon Schubert #include "symtab.h" 26*5796c8dcSSimon Schubert #include "frame.h" 27*5796c8dcSSimon Schubert #include "inferior.h" 28*5796c8dcSSimon Schubert #include "environ.h" 29*5796c8dcSSimon Schubert #include "value.h" 30*5796c8dcSSimon Schubert #include "target.h" 31*5796c8dcSSimon Schubert #include "gdbthread.h" 32*5796c8dcSSimon Schubert #include "exceptions.h" 33*5796c8dcSSimon Schubert #include "command.h" 34*5796c8dcSSimon Schubert #include "gdbcmd.h" 35*5796c8dcSSimon Schubert #include "regcache.h" 36*5796c8dcSSimon Schubert #include "gdb.h" 37*5796c8dcSSimon Schubert #include "gdb_string.h" 38*5796c8dcSSimon Schubert 39*5796c8dcSSimon Schubert #include <ctype.h> 40*5796c8dcSSimon Schubert #include <sys/types.h> 41*5796c8dcSSimon Schubert #include <signal.h> 42*5796c8dcSSimon Schubert #include "ui-out.h" 43*5796c8dcSSimon Schubert #include "observer.h" 44*5796c8dcSSimon Schubert #include "annotate.h" 45*5796c8dcSSimon Schubert #include "cli/cli-decode.h" 46*5796c8dcSSimon Schubert 47*5796c8dcSSimon Schubert /* Definition of struct thread_info exported to gdbthread.h */ 48*5796c8dcSSimon Schubert 49*5796c8dcSSimon Schubert /* Prototypes for exported functions. */ 50*5796c8dcSSimon Schubert 51*5796c8dcSSimon Schubert void _initialize_thread (void); 52*5796c8dcSSimon Schubert 53*5796c8dcSSimon Schubert /* Prototypes for local functions. */ 54*5796c8dcSSimon Schubert 55*5796c8dcSSimon Schubert static struct thread_info *thread_list = NULL; 56*5796c8dcSSimon Schubert static int highest_thread_num; 57*5796c8dcSSimon Schubert 58*5796c8dcSSimon Schubert static void thread_command (char *tidstr, int from_tty); 59*5796c8dcSSimon Schubert static void thread_apply_all_command (char *, int); 60*5796c8dcSSimon Schubert static int thread_alive (struct thread_info *); 61*5796c8dcSSimon Schubert static void info_threads_command (char *, int); 62*5796c8dcSSimon Schubert static void thread_apply_command (char *, int); 63*5796c8dcSSimon Schubert static void restore_current_thread (ptid_t); 64*5796c8dcSSimon Schubert static void prune_threads (void); 65*5796c8dcSSimon Schubert 66*5796c8dcSSimon Schubert /* Frontend view of the thread state. Possible extensions: stepping, 67*5796c8dcSSimon Schubert finishing, until(ling),... */ 68*5796c8dcSSimon Schubert enum thread_state 69*5796c8dcSSimon Schubert { 70*5796c8dcSSimon Schubert THREAD_STOPPED, 71*5796c8dcSSimon Schubert THREAD_RUNNING, 72*5796c8dcSSimon Schubert THREAD_EXITED, 73*5796c8dcSSimon Schubert }; 74*5796c8dcSSimon Schubert 75*5796c8dcSSimon Schubert struct thread_info* 76*5796c8dcSSimon Schubert inferior_thread (void) 77*5796c8dcSSimon Schubert { 78*5796c8dcSSimon Schubert struct thread_info *tp = find_thread_ptid (inferior_ptid); 79*5796c8dcSSimon Schubert gdb_assert (tp); 80*5796c8dcSSimon Schubert return tp; 81*5796c8dcSSimon Schubert } 82*5796c8dcSSimon Schubert 83*5796c8dcSSimon Schubert void 84*5796c8dcSSimon Schubert delete_step_resume_breakpoint (struct thread_info *tp) 85*5796c8dcSSimon Schubert { 86*5796c8dcSSimon Schubert if (tp && tp->step_resume_breakpoint) 87*5796c8dcSSimon Schubert { 88*5796c8dcSSimon Schubert delete_breakpoint (tp->step_resume_breakpoint); 89*5796c8dcSSimon Schubert tp->step_resume_breakpoint = NULL; 90*5796c8dcSSimon Schubert } 91*5796c8dcSSimon Schubert } 92*5796c8dcSSimon Schubert 93*5796c8dcSSimon Schubert static void 94*5796c8dcSSimon Schubert clear_thread_inferior_resources (struct thread_info *tp) 95*5796c8dcSSimon Schubert { 96*5796c8dcSSimon Schubert /* NOTE: this will take care of any left-over step_resume breakpoints, 97*5796c8dcSSimon Schubert but not any user-specified thread-specific breakpoints. We can not 98*5796c8dcSSimon Schubert delete the breakpoint straight-off, because the inferior might not 99*5796c8dcSSimon Schubert be stopped at the moment. */ 100*5796c8dcSSimon Schubert if (tp->step_resume_breakpoint) 101*5796c8dcSSimon Schubert { 102*5796c8dcSSimon Schubert tp->step_resume_breakpoint->disposition = disp_del_at_next_stop; 103*5796c8dcSSimon Schubert tp->step_resume_breakpoint = NULL; 104*5796c8dcSSimon Schubert } 105*5796c8dcSSimon Schubert 106*5796c8dcSSimon Schubert bpstat_clear (&tp->stop_bpstat); 107*5796c8dcSSimon Schubert 108*5796c8dcSSimon Schubert discard_all_intermediate_continuations_thread (tp); 109*5796c8dcSSimon Schubert discard_all_continuations_thread (tp); 110*5796c8dcSSimon Schubert } 111*5796c8dcSSimon Schubert 112*5796c8dcSSimon Schubert static void 113*5796c8dcSSimon Schubert free_thread (struct thread_info *tp) 114*5796c8dcSSimon Schubert { 115*5796c8dcSSimon Schubert clear_thread_inferior_resources (tp); 116*5796c8dcSSimon Schubert 117*5796c8dcSSimon Schubert /* FIXME: do I ever need to call the back-end to give it a 118*5796c8dcSSimon Schubert chance at this private data before deleting the thread? */ 119*5796c8dcSSimon Schubert if (tp->private) 120*5796c8dcSSimon Schubert xfree (tp->private); 121*5796c8dcSSimon Schubert 122*5796c8dcSSimon Schubert xfree (tp); 123*5796c8dcSSimon Schubert } 124*5796c8dcSSimon Schubert 125*5796c8dcSSimon Schubert void 126*5796c8dcSSimon Schubert init_thread_list (void) 127*5796c8dcSSimon Schubert { 128*5796c8dcSSimon Schubert struct thread_info *tp, *tpnext; 129*5796c8dcSSimon Schubert 130*5796c8dcSSimon Schubert highest_thread_num = 0; 131*5796c8dcSSimon Schubert 132*5796c8dcSSimon Schubert if (!thread_list) 133*5796c8dcSSimon Schubert return; 134*5796c8dcSSimon Schubert 135*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tpnext) 136*5796c8dcSSimon Schubert { 137*5796c8dcSSimon Schubert tpnext = tp->next; 138*5796c8dcSSimon Schubert free_thread (tp); 139*5796c8dcSSimon Schubert } 140*5796c8dcSSimon Schubert 141*5796c8dcSSimon Schubert thread_list = NULL; 142*5796c8dcSSimon Schubert } 143*5796c8dcSSimon Schubert 144*5796c8dcSSimon Schubert /* Allocate a new thread with target id PTID and add it to the thread 145*5796c8dcSSimon Schubert list. */ 146*5796c8dcSSimon Schubert 147*5796c8dcSSimon Schubert static struct thread_info * 148*5796c8dcSSimon Schubert new_thread (ptid_t ptid) 149*5796c8dcSSimon Schubert { 150*5796c8dcSSimon Schubert struct thread_info *tp; 151*5796c8dcSSimon Schubert 152*5796c8dcSSimon Schubert tp = xcalloc (1, sizeof (*tp)); 153*5796c8dcSSimon Schubert 154*5796c8dcSSimon Schubert tp->ptid = ptid; 155*5796c8dcSSimon Schubert tp->num = ++highest_thread_num; 156*5796c8dcSSimon Schubert tp->next = thread_list; 157*5796c8dcSSimon Schubert thread_list = tp; 158*5796c8dcSSimon Schubert 159*5796c8dcSSimon Schubert /* Nothing to follow yet. */ 160*5796c8dcSSimon Schubert tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS; 161*5796c8dcSSimon Schubert tp->state_ = THREAD_STOPPED; 162*5796c8dcSSimon Schubert 163*5796c8dcSSimon Schubert return tp; 164*5796c8dcSSimon Schubert } 165*5796c8dcSSimon Schubert 166*5796c8dcSSimon Schubert struct thread_info * 167*5796c8dcSSimon Schubert add_thread_silent (ptid_t ptid) 168*5796c8dcSSimon Schubert { 169*5796c8dcSSimon Schubert struct thread_info *tp; 170*5796c8dcSSimon Schubert 171*5796c8dcSSimon Schubert tp = find_thread_ptid (ptid); 172*5796c8dcSSimon Schubert if (tp) 173*5796c8dcSSimon Schubert /* Found an old thread with the same id. It has to be dead, 174*5796c8dcSSimon Schubert otherwise we wouldn't be adding a new thread with the same id. 175*5796c8dcSSimon Schubert The OS is reusing this id --- delete it, and recreate a new 176*5796c8dcSSimon Schubert one. */ 177*5796c8dcSSimon Schubert { 178*5796c8dcSSimon Schubert /* In addition to deleting the thread, if this is the current 179*5796c8dcSSimon Schubert thread, then we need to take care that delete_thread doesn't 180*5796c8dcSSimon Schubert really delete the thread if it is inferior_ptid. Create a 181*5796c8dcSSimon Schubert new template thread in the list with an invalid ptid, switch 182*5796c8dcSSimon Schubert to it, delete the original thread, reset the new thread's 183*5796c8dcSSimon Schubert ptid, and switch to it. */ 184*5796c8dcSSimon Schubert 185*5796c8dcSSimon Schubert if (ptid_equal (inferior_ptid, ptid)) 186*5796c8dcSSimon Schubert { 187*5796c8dcSSimon Schubert tp = new_thread (ptid); 188*5796c8dcSSimon Schubert 189*5796c8dcSSimon Schubert /* Make switch_to_thread not read from the thread. */ 190*5796c8dcSSimon Schubert tp->state_ = THREAD_EXITED; 191*5796c8dcSSimon Schubert switch_to_thread (minus_one_ptid); 192*5796c8dcSSimon Schubert 193*5796c8dcSSimon Schubert /* Now we can delete it. */ 194*5796c8dcSSimon Schubert delete_thread (ptid); 195*5796c8dcSSimon Schubert 196*5796c8dcSSimon Schubert /* Now reset its ptid, and reswitch inferior_ptid to it. */ 197*5796c8dcSSimon Schubert tp->ptid = ptid; 198*5796c8dcSSimon Schubert tp->state_ = THREAD_STOPPED; 199*5796c8dcSSimon Schubert switch_to_thread (ptid); 200*5796c8dcSSimon Schubert 201*5796c8dcSSimon Schubert observer_notify_new_thread (tp); 202*5796c8dcSSimon Schubert 203*5796c8dcSSimon Schubert /* All done. */ 204*5796c8dcSSimon Schubert return tp; 205*5796c8dcSSimon Schubert } 206*5796c8dcSSimon Schubert else 207*5796c8dcSSimon Schubert /* Just go ahead and delete it. */ 208*5796c8dcSSimon Schubert delete_thread (ptid); 209*5796c8dcSSimon Schubert } 210*5796c8dcSSimon Schubert 211*5796c8dcSSimon Schubert tp = new_thread (ptid); 212*5796c8dcSSimon Schubert observer_notify_new_thread (tp); 213*5796c8dcSSimon Schubert 214*5796c8dcSSimon Schubert return tp; 215*5796c8dcSSimon Schubert } 216*5796c8dcSSimon Schubert 217*5796c8dcSSimon Schubert struct thread_info * 218*5796c8dcSSimon Schubert add_thread_with_info (ptid_t ptid, struct private_thread_info *private) 219*5796c8dcSSimon Schubert { 220*5796c8dcSSimon Schubert struct thread_info *result = add_thread_silent (ptid); 221*5796c8dcSSimon Schubert 222*5796c8dcSSimon Schubert result->private = private; 223*5796c8dcSSimon Schubert 224*5796c8dcSSimon Schubert if (print_thread_events) 225*5796c8dcSSimon Schubert printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid)); 226*5796c8dcSSimon Schubert 227*5796c8dcSSimon Schubert annotate_new_thread (); 228*5796c8dcSSimon Schubert return result; 229*5796c8dcSSimon Schubert } 230*5796c8dcSSimon Schubert 231*5796c8dcSSimon Schubert struct thread_info * 232*5796c8dcSSimon Schubert add_thread (ptid_t ptid) 233*5796c8dcSSimon Schubert { 234*5796c8dcSSimon Schubert return add_thread_with_info (ptid, NULL); 235*5796c8dcSSimon Schubert } 236*5796c8dcSSimon Schubert 237*5796c8dcSSimon Schubert /* Delete thread PTID. If SILENT, don't notify the observer of this 238*5796c8dcSSimon Schubert exit. */ 239*5796c8dcSSimon Schubert static void 240*5796c8dcSSimon Schubert delete_thread_1 (ptid_t ptid, int silent) 241*5796c8dcSSimon Schubert { 242*5796c8dcSSimon Schubert struct thread_info *tp, *tpprev; 243*5796c8dcSSimon Schubert 244*5796c8dcSSimon Schubert tpprev = NULL; 245*5796c8dcSSimon Schubert 246*5796c8dcSSimon Schubert for (tp = thread_list; tp; tpprev = tp, tp = tp->next) 247*5796c8dcSSimon Schubert if (ptid_equal (tp->ptid, ptid)) 248*5796c8dcSSimon Schubert break; 249*5796c8dcSSimon Schubert 250*5796c8dcSSimon Schubert if (!tp) 251*5796c8dcSSimon Schubert return; 252*5796c8dcSSimon Schubert 253*5796c8dcSSimon Schubert /* If this is the current thread, or there's code out there that 254*5796c8dcSSimon Schubert relies on it existing (refcount > 0) we can't delete yet. Mark 255*5796c8dcSSimon Schubert it as exited, and notify it. */ 256*5796c8dcSSimon Schubert if (tp->refcount > 0 257*5796c8dcSSimon Schubert || ptid_equal (tp->ptid, inferior_ptid)) 258*5796c8dcSSimon Schubert { 259*5796c8dcSSimon Schubert if (tp->state_ != THREAD_EXITED) 260*5796c8dcSSimon Schubert { 261*5796c8dcSSimon Schubert observer_notify_thread_exit (tp, silent); 262*5796c8dcSSimon Schubert 263*5796c8dcSSimon Schubert /* Tag it as exited. */ 264*5796c8dcSSimon Schubert tp->state_ = THREAD_EXITED; 265*5796c8dcSSimon Schubert 266*5796c8dcSSimon Schubert /* Clear breakpoints, etc. associated with this thread. */ 267*5796c8dcSSimon Schubert clear_thread_inferior_resources (tp); 268*5796c8dcSSimon Schubert } 269*5796c8dcSSimon Schubert 270*5796c8dcSSimon Schubert /* Will be really deleted some other time. */ 271*5796c8dcSSimon Schubert return; 272*5796c8dcSSimon Schubert } 273*5796c8dcSSimon Schubert 274*5796c8dcSSimon Schubert if (tpprev) 275*5796c8dcSSimon Schubert tpprev->next = tp->next; 276*5796c8dcSSimon Schubert else 277*5796c8dcSSimon Schubert thread_list = tp->next; 278*5796c8dcSSimon Schubert 279*5796c8dcSSimon Schubert /* Notify thread exit, but only if we haven't already. */ 280*5796c8dcSSimon Schubert if (tp->state_ != THREAD_EXITED) 281*5796c8dcSSimon Schubert observer_notify_thread_exit (tp, silent); 282*5796c8dcSSimon Schubert 283*5796c8dcSSimon Schubert free_thread (tp); 284*5796c8dcSSimon Schubert } 285*5796c8dcSSimon Schubert 286*5796c8dcSSimon Schubert /* Delete thread PTID and notify of thread exit. If this is 287*5796c8dcSSimon Schubert inferior_ptid, don't actually delete it, but tag it as exited and 288*5796c8dcSSimon Schubert do the notification. If PTID is the user selected thread, clear 289*5796c8dcSSimon Schubert it. */ 290*5796c8dcSSimon Schubert void 291*5796c8dcSSimon Schubert delete_thread (ptid_t ptid) 292*5796c8dcSSimon Schubert { 293*5796c8dcSSimon Schubert delete_thread_1 (ptid, 0 /* not silent */); 294*5796c8dcSSimon Schubert } 295*5796c8dcSSimon Schubert 296*5796c8dcSSimon Schubert void 297*5796c8dcSSimon Schubert delete_thread_silent (ptid_t ptid) 298*5796c8dcSSimon Schubert { 299*5796c8dcSSimon Schubert delete_thread_1 (ptid, 1 /* silent */); 300*5796c8dcSSimon Schubert } 301*5796c8dcSSimon Schubert 302*5796c8dcSSimon Schubert struct thread_info * 303*5796c8dcSSimon Schubert find_thread_id (int num) 304*5796c8dcSSimon Schubert { 305*5796c8dcSSimon Schubert struct thread_info *tp; 306*5796c8dcSSimon Schubert 307*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 308*5796c8dcSSimon Schubert if (tp->num == num) 309*5796c8dcSSimon Schubert return tp; 310*5796c8dcSSimon Schubert 311*5796c8dcSSimon Schubert return NULL; 312*5796c8dcSSimon Schubert } 313*5796c8dcSSimon Schubert 314*5796c8dcSSimon Schubert /* Find a thread_info by matching PTID. */ 315*5796c8dcSSimon Schubert struct thread_info * 316*5796c8dcSSimon Schubert find_thread_ptid (ptid_t ptid) 317*5796c8dcSSimon Schubert { 318*5796c8dcSSimon Schubert struct thread_info *tp; 319*5796c8dcSSimon Schubert 320*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 321*5796c8dcSSimon Schubert if (ptid_equal (tp->ptid, ptid)) 322*5796c8dcSSimon Schubert return tp; 323*5796c8dcSSimon Schubert 324*5796c8dcSSimon Schubert return NULL; 325*5796c8dcSSimon Schubert } 326*5796c8dcSSimon Schubert 327*5796c8dcSSimon Schubert /* 328*5796c8dcSSimon Schubert * Thread iterator function. 329*5796c8dcSSimon Schubert * 330*5796c8dcSSimon Schubert * Calls a callback function once for each thread, so long as 331*5796c8dcSSimon Schubert * the callback function returns false. If the callback function 332*5796c8dcSSimon Schubert * returns true, the iteration will end and the current thread 333*5796c8dcSSimon Schubert * will be returned. This can be useful for implementing a 334*5796c8dcSSimon Schubert * search for a thread with arbitrary attributes, or for applying 335*5796c8dcSSimon Schubert * some operation to every thread. 336*5796c8dcSSimon Schubert * 337*5796c8dcSSimon Schubert * FIXME: some of the existing functionality, such as 338*5796c8dcSSimon Schubert * "Thread apply all", might be rewritten using this functionality. 339*5796c8dcSSimon Schubert */ 340*5796c8dcSSimon Schubert 341*5796c8dcSSimon Schubert struct thread_info * 342*5796c8dcSSimon Schubert iterate_over_threads (int (*callback) (struct thread_info *, void *), 343*5796c8dcSSimon Schubert void *data) 344*5796c8dcSSimon Schubert { 345*5796c8dcSSimon Schubert struct thread_info *tp, *next; 346*5796c8dcSSimon Schubert 347*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = next) 348*5796c8dcSSimon Schubert { 349*5796c8dcSSimon Schubert next = tp->next; 350*5796c8dcSSimon Schubert if ((*callback) (tp, data)) 351*5796c8dcSSimon Schubert return tp; 352*5796c8dcSSimon Schubert } 353*5796c8dcSSimon Schubert 354*5796c8dcSSimon Schubert return NULL; 355*5796c8dcSSimon Schubert } 356*5796c8dcSSimon Schubert 357*5796c8dcSSimon Schubert int 358*5796c8dcSSimon Schubert thread_count (void) 359*5796c8dcSSimon Schubert { 360*5796c8dcSSimon Schubert int result = 0; 361*5796c8dcSSimon Schubert struct thread_info *tp; 362*5796c8dcSSimon Schubert 363*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 364*5796c8dcSSimon Schubert ++result; 365*5796c8dcSSimon Schubert 366*5796c8dcSSimon Schubert return result; 367*5796c8dcSSimon Schubert } 368*5796c8dcSSimon Schubert 369*5796c8dcSSimon Schubert int 370*5796c8dcSSimon Schubert valid_thread_id (int num) 371*5796c8dcSSimon Schubert { 372*5796c8dcSSimon Schubert struct thread_info *tp; 373*5796c8dcSSimon Schubert 374*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 375*5796c8dcSSimon Schubert if (tp->num == num) 376*5796c8dcSSimon Schubert return 1; 377*5796c8dcSSimon Schubert 378*5796c8dcSSimon Schubert return 0; 379*5796c8dcSSimon Schubert } 380*5796c8dcSSimon Schubert 381*5796c8dcSSimon Schubert int 382*5796c8dcSSimon Schubert pid_to_thread_id (ptid_t ptid) 383*5796c8dcSSimon Schubert { 384*5796c8dcSSimon Schubert struct thread_info *tp; 385*5796c8dcSSimon Schubert 386*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 387*5796c8dcSSimon Schubert if (ptid_equal (tp->ptid, ptid)) 388*5796c8dcSSimon Schubert return tp->num; 389*5796c8dcSSimon Schubert 390*5796c8dcSSimon Schubert return 0; 391*5796c8dcSSimon Schubert } 392*5796c8dcSSimon Schubert 393*5796c8dcSSimon Schubert ptid_t 394*5796c8dcSSimon Schubert thread_id_to_pid (int num) 395*5796c8dcSSimon Schubert { 396*5796c8dcSSimon Schubert struct thread_info *thread = find_thread_id (num); 397*5796c8dcSSimon Schubert if (thread) 398*5796c8dcSSimon Schubert return thread->ptid; 399*5796c8dcSSimon Schubert else 400*5796c8dcSSimon Schubert return pid_to_ptid (-1); 401*5796c8dcSSimon Schubert } 402*5796c8dcSSimon Schubert 403*5796c8dcSSimon Schubert int 404*5796c8dcSSimon Schubert in_thread_list (ptid_t ptid) 405*5796c8dcSSimon Schubert { 406*5796c8dcSSimon Schubert struct thread_info *tp; 407*5796c8dcSSimon Schubert 408*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 409*5796c8dcSSimon Schubert if (ptid_equal (tp->ptid, ptid)) 410*5796c8dcSSimon Schubert return 1; 411*5796c8dcSSimon Schubert 412*5796c8dcSSimon Schubert return 0; /* Never heard of 'im */ 413*5796c8dcSSimon Schubert } 414*5796c8dcSSimon Schubert 415*5796c8dcSSimon Schubert /* Finds the first thread of the inferior given by PID. If PID is -1, 416*5796c8dcSSimon Schubert return the first thread in the list. */ 417*5796c8dcSSimon Schubert 418*5796c8dcSSimon Schubert struct thread_info * 419*5796c8dcSSimon Schubert first_thread_of_process (int pid) 420*5796c8dcSSimon Schubert { 421*5796c8dcSSimon Schubert struct thread_info *tp, *ret = NULL; 422*5796c8dcSSimon Schubert 423*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 424*5796c8dcSSimon Schubert if (pid == -1 || ptid_get_pid (tp->ptid) == pid) 425*5796c8dcSSimon Schubert if (ret == NULL || tp->num < ret->num) 426*5796c8dcSSimon Schubert ret = tp; 427*5796c8dcSSimon Schubert 428*5796c8dcSSimon Schubert return ret; 429*5796c8dcSSimon Schubert } 430*5796c8dcSSimon Schubert 431*5796c8dcSSimon Schubert struct thread_info * 432*5796c8dcSSimon Schubert any_thread_of_process (int pid) 433*5796c8dcSSimon Schubert { 434*5796c8dcSSimon Schubert struct thread_info *tp; 435*5796c8dcSSimon Schubert 436*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 437*5796c8dcSSimon Schubert if (ptid_get_pid (tp->ptid) == pid) 438*5796c8dcSSimon Schubert return tp; 439*5796c8dcSSimon Schubert 440*5796c8dcSSimon Schubert return NULL; 441*5796c8dcSSimon Schubert } 442*5796c8dcSSimon Schubert 443*5796c8dcSSimon Schubert /* Print a list of thread ids currently known, and the total number of 444*5796c8dcSSimon Schubert threads. To be used from within catch_errors. */ 445*5796c8dcSSimon Schubert static int 446*5796c8dcSSimon Schubert do_captured_list_thread_ids (struct ui_out *uiout, void *arg) 447*5796c8dcSSimon Schubert { 448*5796c8dcSSimon Schubert struct thread_info *tp; 449*5796c8dcSSimon Schubert int num = 0; 450*5796c8dcSSimon Schubert struct cleanup *cleanup_chain; 451*5796c8dcSSimon Schubert int current_thread = -1; 452*5796c8dcSSimon Schubert 453*5796c8dcSSimon Schubert prune_threads (); 454*5796c8dcSSimon Schubert target_find_new_threads (); 455*5796c8dcSSimon Schubert 456*5796c8dcSSimon Schubert cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids"); 457*5796c8dcSSimon Schubert 458*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 459*5796c8dcSSimon Schubert { 460*5796c8dcSSimon Schubert if (tp->state_ == THREAD_EXITED) 461*5796c8dcSSimon Schubert continue; 462*5796c8dcSSimon Schubert 463*5796c8dcSSimon Schubert if (ptid_equal (tp->ptid, inferior_ptid)) 464*5796c8dcSSimon Schubert current_thread = tp->num; 465*5796c8dcSSimon Schubert 466*5796c8dcSSimon Schubert num++; 467*5796c8dcSSimon Schubert ui_out_field_int (uiout, "thread-id", tp->num); 468*5796c8dcSSimon Schubert } 469*5796c8dcSSimon Schubert 470*5796c8dcSSimon Schubert do_cleanups (cleanup_chain); 471*5796c8dcSSimon Schubert 472*5796c8dcSSimon Schubert if (current_thread != -1) 473*5796c8dcSSimon Schubert ui_out_field_int (uiout, "current-thread-id", current_thread); 474*5796c8dcSSimon Schubert ui_out_field_int (uiout, "number-of-threads", num); 475*5796c8dcSSimon Schubert return GDB_RC_OK; 476*5796c8dcSSimon Schubert } 477*5796c8dcSSimon Schubert 478*5796c8dcSSimon Schubert /* Official gdblib interface function to get a list of thread ids and 479*5796c8dcSSimon Schubert the total number. */ 480*5796c8dcSSimon Schubert enum gdb_rc 481*5796c8dcSSimon Schubert gdb_list_thread_ids (struct ui_out *uiout, char **error_message) 482*5796c8dcSSimon Schubert { 483*5796c8dcSSimon Schubert if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL, 484*5796c8dcSSimon Schubert error_message, RETURN_MASK_ALL) < 0) 485*5796c8dcSSimon Schubert return GDB_RC_FAIL; 486*5796c8dcSSimon Schubert return GDB_RC_OK; 487*5796c8dcSSimon Schubert } 488*5796c8dcSSimon Schubert 489*5796c8dcSSimon Schubert /* Return true if TP is an active thread. */ 490*5796c8dcSSimon Schubert static int 491*5796c8dcSSimon Schubert thread_alive (struct thread_info *tp) 492*5796c8dcSSimon Schubert { 493*5796c8dcSSimon Schubert if (tp->state_ == THREAD_EXITED) 494*5796c8dcSSimon Schubert return 0; 495*5796c8dcSSimon Schubert if (!target_thread_alive (tp->ptid)) 496*5796c8dcSSimon Schubert return 0; 497*5796c8dcSSimon Schubert return 1; 498*5796c8dcSSimon Schubert } 499*5796c8dcSSimon Schubert 500*5796c8dcSSimon Schubert static void 501*5796c8dcSSimon Schubert prune_threads (void) 502*5796c8dcSSimon Schubert { 503*5796c8dcSSimon Schubert struct thread_info *tp, *next; 504*5796c8dcSSimon Schubert 505*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = next) 506*5796c8dcSSimon Schubert { 507*5796c8dcSSimon Schubert next = tp->next; 508*5796c8dcSSimon Schubert if (!thread_alive (tp)) 509*5796c8dcSSimon Schubert delete_thread (tp->ptid); 510*5796c8dcSSimon Schubert } 511*5796c8dcSSimon Schubert } 512*5796c8dcSSimon Schubert 513*5796c8dcSSimon Schubert void 514*5796c8dcSSimon Schubert thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid) 515*5796c8dcSSimon Schubert { 516*5796c8dcSSimon Schubert struct inferior *inf; 517*5796c8dcSSimon Schubert struct thread_info *tp; 518*5796c8dcSSimon Schubert 519*5796c8dcSSimon Schubert /* It can happen that what we knew as the target inferior id 520*5796c8dcSSimon Schubert changes. E.g, target remote may only discover the remote process 521*5796c8dcSSimon Schubert pid after adding the inferior to GDB's list. */ 522*5796c8dcSSimon Schubert inf = find_inferior_pid (ptid_get_pid (old_ptid)); 523*5796c8dcSSimon Schubert inf->pid = ptid_get_pid (new_ptid); 524*5796c8dcSSimon Schubert 525*5796c8dcSSimon Schubert tp = find_thread_ptid (old_ptid); 526*5796c8dcSSimon Schubert tp->ptid = new_ptid; 527*5796c8dcSSimon Schubert 528*5796c8dcSSimon Schubert observer_notify_thread_ptid_changed (old_ptid, new_ptid); 529*5796c8dcSSimon Schubert } 530*5796c8dcSSimon Schubert 531*5796c8dcSSimon Schubert void 532*5796c8dcSSimon Schubert set_running (ptid_t ptid, int running) 533*5796c8dcSSimon Schubert { 534*5796c8dcSSimon Schubert struct thread_info *tp; 535*5796c8dcSSimon Schubert int all = ptid_equal (ptid, minus_one_ptid); 536*5796c8dcSSimon Schubert 537*5796c8dcSSimon Schubert /* We try not to notify the observer if no thread has actually changed 538*5796c8dcSSimon Schubert the running state -- merely to reduce the number of messages to 539*5796c8dcSSimon Schubert frontend. Frontend is supposed to handle multiple *running just fine. */ 540*5796c8dcSSimon Schubert if (all || ptid_is_pid (ptid)) 541*5796c8dcSSimon Schubert { 542*5796c8dcSSimon Schubert int any_started = 0; 543*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 544*5796c8dcSSimon Schubert if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid)) 545*5796c8dcSSimon Schubert { 546*5796c8dcSSimon Schubert if (tp->state_ == THREAD_EXITED) 547*5796c8dcSSimon Schubert continue; 548*5796c8dcSSimon Schubert if (running && tp->state_ == THREAD_STOPPED) 549*5796c8dcSSimon Schubert any_started = 1; 550*5796c8dcSSimon Schubert tp->state_ = running ? THREAD_RUNNING : THREAD_STOPPED; 551*5796c8dcSSimon Schubert } 552*5796c8dcSSimon Schubert if (any_started) 553*5796c8dcSSimon Schubert observer_notify_target_resumed (ptid); 554*5796c8dcSSimon Schubert } 555*5796c8dcSSimon Schubert else 556*5796c8dcSSimon Schubert { 557*5796c8dcSSimon Schubert int started = 0; 558*5796c8dcSSimon Schubert tp = find_thread_ptid (ptid); 559*5796c8dcSSimon Schubert gdb_assert (tp); 560*5796c8dcSSimon Schubert gdb_assert (tp->state_ != THREAD_EXITED); 561*5796c8dcSSimon Schubert if (running && tp->state_ == THREAD_STOPPED) 562*5796c8dcSSimon Schubert started = 1; 563*5796c8dcSSimon Schubert tp->state_ = running ? THREAD_RUNNING : THREAD_STOPPED; 564*5796c8dcSSimon Schubert if (started) 565*5796c8dcSSimon Schubert observer_notify_target_resumed (ptid); 566*5796c8dcSSimon Schubert } 567*5796c8dcSSimon Schubert } 568*5796c8dcSSimon Schubert 569*5796c8dcSSimon Schubert static int 570*5796c8dcSSimon Schubert is_thread_state (ptid_t ptid, enum thread_state state) 571*5796c8dcSSimon Schubert { 572*5796c8dcSSimon Schubert struct thread_info *tp; 573*5796c8dcSSimon Schubert 574*5796c8dcSSimon Schubert tp = find_thread_ptid (ptid); 575*5796c8dcSSimon Schubert gdb_assert (tp); 576*5796c8dcSSimon Schubert return tp->state_ == state; 577*5796c8dcSSimon Schubert } 578*5796c8dcSSimon Schubert 579*5796c8dcSSimon Schubert int 580*5796c8dcSSimon Schubert is_stopped (ptid_t ptid) 581*5796c8dcSSimon Schubert { 582*5796c8dcSSimon Schubert return is_thread_state (ptid, THREAD_STOPPED); 583*5796c8dcSSimon Schubert } 584*5796c8dcSSimon Schubert 585*5796c8dcSSimon Schubert int 586*5796c8dcSSimon Schubert is_exited (ptid_t ptid) 587*5796c8dcSSimon Schubert { 588*5796c8dcSSimon Schubert return is_thread_state (ptid, THREAD_EXITED); 589*5796c8dcSSimon Schubert } 590*5796c8dcSSimon Schubert 591*5796c8dcSSimon Schubert int 592*5796c8dcSSimon Schubert is_running (ptid_t ptid) 593*5796c8dcSSimon Schubert { 594*5796c8dcSSimon Schubert return is_thread_state (ptid, THREAD_RUNNING); 595*5796c8dcSSimon Schubert } 596*5796c8dcSSimon Schubert 597*5796c8dcSSimon Schubert int 598*5796c8dcSSimon Schubert any_running (void) 599*5796c8dcSSimon Schubert { 600*5796c8dcSSimon Schubert struct thread_info *tp; 601*5796c8dcSSimon Schubert 602*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 603*5796c8dcSSimon Schubert if (tp->state_ == THREAD_RUNNING) 604*5796c8dcSSimon Schubert return 1; 605*5796c8dcSSimon Schubert 606*5796c8dcSSimon Schubert return 0; 607*5796c8dcSSimon Schubert } 608*5796c8dcSSimon Schubert 609*5796c8dcSSimon Schubert int 610*5796c8dcSSimon Schubert is_executing (ptid_t ptid) 611*5796c8dcSSimon Schubert { 612*5796c8dcSSimon Schubert struct thread_info *tp; 613*5796c8dcSSimon Schubert 614*5796c8dcSSimon Schubert tp = find_thread_ptid (ptid); 615*5796c8dcSSimon Schubert gdb_assert (tp); 616*5796c8dcSSimon Schubert return tp->executing_; 617*5796c8dcSSimon Schubert } 618*5796c8dcSSimon Schubert 619*5796c8dcSSimon Schubert void 620*5796c8dcSSimon Schubert set_executing (ptid_t ptid, int executing) 621*5796c8dcSSimon Schubert { 622*5796c8dcSSimon Schubert struct thread_info *tp; 623*5796c8dcSSimon Schubert int all = ptid_equal (ptid, minus_one_ptid); 624*5796c8dcSSimon Schubert 625*5796c8dcSSimon Schubert if (all || ptid_is_pid (ptid)) 626*5796c8dcSSimon Schubert { 627*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 628*5796c8dcSSimon Schubert if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid)) 629*5796c8dcSSimon Schubert tp->executing_ = executing; 630*5796c8dcSSimon Schubert } 631*5796c8dcSSimon Schubert else 632*5796c8dcSSimon Schubert { 633*5796c8dcSSimon Schubert tp = find_thread_ptid (ptid); 634*5796c8dcSSimon Schubert gdb_assert (tp); 635*5796c8dcSSimon Schubert tp->executing_ = executing; 636*5796c8dcSSimon Schubert } 637*5796c8dcSSimon Schubert } 638*5796c8dcSSimon Schubert 639*5796c8dcSSimon Schubert void 640*5796c8dcSSimon Schubert set_stop_requested (ptid_t ptid, int stop) 641*5796c8dcSSimon Schubert { 642*5796c8dcSSimon Schubert struct thread_info *tp; 643*5796c8dcSSimon Schubert int all = ptid_equal (ptid, minus_one_ptid); 644*5796c8dcSSimon Schubert 645*5796c8dcSSimon Schubert if (all || ptid_is_pid (ptid)) 646*5796c8dcSSimon Schubert { 647*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 648*5796c8dcSSimon Schubert if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid)) 649*5796c8dcSSimon Schubert tp->stop_requested = stop; 650*5796c8dcSSimon Schubert } 651*5796c8dcSSimon Schubert else 652*5796c8dcSSimon Schubert { 653*5796c8dcSSimon Schubert tp = find_thread_ptid (ptid); 654*5796c8dcSSimon Schubert gdb_assert (tp); 655*5796c8dcSSimon Schubert tp->stop_requested = stop; 656*5796c8dcSSimon Schubert } 657*5796c8dcSSimon Schubert 658*5796c8dcSSimon Schubert /* Call the stop requested observer so other components of GDB can 659*5796c8dcSSimon Schubert react to this request. */ 660*5796c8dcSSimon Schubert if (stop) 661*5796c8dcSSimon Schubert observer_notify_thread_stop_requested (ptid); 662*5796c8dcSSimon Schubert } 663*5796c8dcSSimon Schubert 664*5796c8dcSSimon Schubert void 665*5796c8dcSSimon Schubert finish_thread_state (ptid_t ptid) 666*5796c8dcSSimon Schubert { 667*5796c8dcSSimon Schubert struct thread_info *tp; 668*5796c8dcSSimon Schubert int all; 669*5796c8dcSSimon Schubert int any_started = 0; 670*5796c8dcSSimon Schubert 671*5796c8dcSSimon Schubert all = ptid_equal (ptid, minus_one_ptid); 672*5796c8dcSSimon Schubert 673*5796c8dcSSimon Schubert if (all || ptid_is_pid (ptid)) 674*5796c8dcSSimon Schubert { 675*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 676*5796c8dcSSimon Schubert { 677*5796c8dcSSimon Schubert if (tp->state_ == THREAD_EXITED) 678*5796c8dcSSimon Schubert continue; 679*5796c8dcSSimon Schubert if (all || ptid_get_pid (ptid) == ptid_get_pid (tp->ptid)) 680*5796c8dcSSimon Schubert { 681*5796c8dcSSimon Schubert if (tp->executing_ && tp->state_ == THREAD_STOPPED) 682*5796c8dcSSimon Schubert any_started = 1; 683*5796c8dcSSimon Schubert tp->state_ = tp->executing_ ? THREAD_RUNNING : THREAD_STOPPED; 684*5796c8dcSSimon Schubert } 685*5796c8dcSSimon Schubert } 686*5796c8dcSSimon Schubert } 687*5796c8dcSSimon Schubert else 688*5796c8dcSSimon Schubert { 689*5796c8dcSSimon Schubert tp = find_thread_ptid (ptid); 690*5796c8dcSSimon Schubert gdb_assert (tp); 691*5796c8dcSSimon Schubert if (tp->state_ != THREAD_EXITED) 692*5796c8dcSSimon Schubert { 693*5796c8dcSSimon Schubert if (tp->executing_ && tp->state_ == THREAD_STOPPED) 694*5796c8dcSSimon Schubert any_started = 1; 695*5796c8dcSSimon Schubert tp->state_ = tp->executing_ ? THREAD_RUNNING : THREAD_STOPPED; 696*5796c8dcSSimon Schubert } 697*5796c8dcSSimon Schubert } 698*5796c8dcSSimon Schubert 699*5796c8dcSSimon Schubert if (any_started) 700*5796c8dcSSimon Schubert observer_notify_target_resumed (ptid); 701*5796c8dcSSimon Schubert } 702*5796c8dcSSimon Schubert 703*5796c8dcSSimon Schubert void 704*5796c8dcSSimon Schubert finish_thread_state_cleanup (void *arg) 705*5796c8dcSSimon Schubert { 706*5796c8dcSSimon Schubert ptid_t *ptid_p = arg; 707*5796c8dcSSimon Schubert 708*5796c8dcSSimon Schubert gdb_assert (arg); 709*5796c8dcSSimon Schubert 710*5796c8dcSSimon Schubert finish_thread_state (*ptid_p); 711*5796c8dcSSimon Schubert } 712*5796c8dcSSimon Schubert 713*5796c8dcSSimon Schubert /* Prints the list of threads and their details on UIOUT. 714*5796c8dcSSimon Schubert This is a version of 'info_thread_command' suitable for 715*5796c8dcSSimon Schubert use from MI. 716*5796c8dcSSimon Schubert If REQUESTED_THREAD is not -1, it's the GDB id of the thread 717*5796c8dcSSimon Schubert that should be printed. Otherwise, all threads are 718*5796c8dcSSimon Schubert printed. 719*5796c8dcSSimon Schubert If PID is not -1, only print threads from the process PID. 720*5796c8dcSSimon Schubert Otherwise, threads from all attached PIDs are printed. 721*5796c8dcSSimon Schubert If both REQUESTED_THREAD and PID are not -1, then the thread 722*5796c8dcSSimon Schubert is printed if it belongs to the specified process. Otherwise, 723*5796c8dcSSimon Schubert an error is raised. */ 724*5796c8dcSSimon Schubert void 725*5796c8dcSSimon Schubert print_thread_info (struct ui_out *uiout, int requested_thread, int pid) 726*5796c8dcSSimon Schubert { 727*5796c8dcSSimon Schubert struct thread_info *tp; 728*5796c8dcSSimon Schubert ptid_t current_ptid; 729*5796c8dcSSimon Schubert struct cleanup *old_chain; 730*5796c8dcSSimon Schubert char *extra_info; 731*5796c8dcSSimon Schubert int current_thread = -1; 732*5796c8dcSSimon Schubert 733*5796c8dcSSimon Schubert prune_threads (); 734*5796c8dcSSimon Schubert target_find_new_threads (); 735*5796c8dcSSimon Schubert current_ptid = inferior_ptid; 736*5796c8dcSSimon Schubert 737*5796c8dcSSimon Schubert /* We'll be switching threads temporarily. */ 738*5796c8dcSSimon Schubert old_chain = make_cleanup_restore_current_thread (); 739*5796c8dcSSimon Schubert 740*5796c8dcSSimon Schubert make_cleanup_ui_out_list_begin_end (uiout, "threads"); 741*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 742*5796c8dcSSimon Schubert { 743*5796c8dcSSimon Schubert struct cleanup *chain2; 744*5796c8dcSSimon Schubert 745*5796c8dcSSimon Schubert if (requested_thread != -1 && tp->num != requested_thread) 746*5796c8dcSSimon Schubert continue; 747*5796c8dcSSimon Schubert 748*5796c8dcSSimon Schubert if (pid != -1 && PIDGET (tp->ptid) != pid) 749*5796c8dcSSimon Schubert { 750*5796c8dcSSimon Schubert if (requested_thread != -1) 751*5796c8dcSSimon Schubert error (_("Requested thread not found in requested process")); 752*5796c8dcSSimon Schubert continue; 753*5796c8dcSSimon Schubert } 754*5796c8dcSSimon Schubert 755*5796c8dcSSimon Schubert if (ptid_equal (tp->ptid, current_ptid)) 756*5796c8dcSSimon Schubert current_thread = tp->num; 757*5796c8dcSSimon Schubert 758*5796c8dcSSimon Schubert if (tp->state_ == THREAD_EXITED) 759*5796c8dcSSimon Schubert continue; 760*5796c8dcSSimon Schubert 761*5796c8dcSSimon Schubert chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); 762*5796c8dcSSimon Schubert 763*5796c8dcSSimon Schubert if (ptid_equal (tp->ptid, current_ptid)) 764*5796c8dcSSimon Schubert ui_out_text (uiout, "* "); 765*5796c8dcSSimon Schubert else 766*5796c8dcSSimon Schubert ui_out_text (uiout, " "); 767*5796c8dcSSimon Schubert 768*5796c8dcSSimon Schubert ui_out_field_int (uiout, "id", tp->num); 769*5796c8dcSSimon Schubert ui_out_text (uiout, " "); 770*5796c8dcSSimon Schubert ui_out_field_string (uiout, "target-id", target_pid_to_str (tp->ptid)); 771*5796c8dcSSimon Schubert 772*5796c8dcSSimon Schubert extra_info = target_extra_thread_info (tp); 773*5796c8dcSSimon Schubert if (extra_info) 774*5796c8dcSSimon Schubert { 775*5796c8dcSSimon Schubert ui_out_text (uiout, " ("); 776*5796c8dcSSimon Schubert ui_out_field_string (uiout, "details", extra_info); 777*5796c8dcSSimon Schubert ui_out_text (uiout, ")"); 778*5796c8dcSSimon Schubert } 779*5796c8dcSSimon Schubert ui_out_text (uiout, " "); 780*5796c8dcSSimon Schubert 781*5796c8dcSSimon Schubert if (tp->state_ == THREAD_RUNNING) 782*5796c8dcSSimon Schubert ui_out_text (uiout, "(running)\n"); 783*5796c8dcSSimon Schubert else 784*5796c8dcSSimon Schubert { 785*5796c8dcSSimon Schubert /* The switch below puts us at the top of the stack (leaf 786*5796c8dcSSimon Schubert frame). */ 787*5796c8dcSSimon Schubert switch_to_thread (tp->ptid); 788*5796c8dcSSimon Schubert print_stack_frame (get_selected_frame (NULL), 789*5796c8dcSSimon Schubert /* For MI output, print frame level. */ 790*5796c8dcSSimon Schubert ui_out_is_mi_like_p (uiout), 791*5796c8dcSSimon Schubert LOCATION); 792*5796c8dcSSimon Schubert } 793*5796c8dcSSimon Schubert 794*5796c8dcSSimon Schubert if (ui_out_is_mi_like_p (uiout)) 795*5796c8dcSSimon Schubert { 796*5796c8dcSSimon Schubert char *state = "stopped"; 797*5796c8dcSSimon Schubert if (tp->state_ == THREAD_RUNNING) 798*5796c8dcSSimon Schubert state = "running"; 799*5796c8dcSSimon Schubert ui_out_field_string (uiout, "state", state); 800*5796c8dcSSimon Schubert } 801*5796c8dcSSimon Schubert 802*5796c8dcSSimon Schubert do_cleanups (chain2); 803*5796c8dcSSimon Schubert } 804*5796c8dcSSimon Schubert 805*5796c8dcSSimon Schubert /* Restores the current thread and the frame selected before 806*5796c8dcSSimon Schubert the "info threads" command. */ 807*5796c8dcSSimon Schubert do_cleanups (old_chain); 808*5796c8dcSSimon Schubert 809*5796c8dcSSimon Schubert if (pid == -1 && requested_thread == -1) 810*5796c8dcSSimon Schubert { 811*5796c8dcSSimon Schubert gdb_assert (current_thread != -1 812*5796c8dcSSimon Schubert || !thread_list 813*5796c8dcSSimon Schubert || ptid_equal (inferior_ptid, null_ptid)); 814*5796c8dcSSimon Schubert if (current_thread != -1 && ui_out_is_mi_like_p (uiout)) 815*5796c8dcSSimon Schubert ui_out_field_int (uiout, "current-thread-id", current_thread); 816*5796c8dcSSimon Schubert 817*5796c8dcSSimon Schubert if (current_thread != -1 && is_exited (current_ptid)) 818*5796c8dcSSimon Schubert ui_out_message (uiout, 0, "\n\ 819*5796c8dcSSimon Schubert The current thread <Thread ID %d> has terminated. See `help thread'.\n", 820*5796c8dcSSimon Schubert current_thread); 821*5796c8dcSSimon Schubert else if (thread_list 822*5796c8dcSSimon Schubert && current_thread == -1 823*5796c8dcSSimon Schubert && ptid_equal (current_ptid, null_ptid)) 824*5796c8dcSSimon Schubert ui_out_message (uiout, 0, "\n\ 825*5796c8dcSSimon Schubert No selected thread. See `help thread'.\n"); 826*5796c8dcSSimon Schubert } 827*5796c8dcSSimon Schubert } 828*5796c8dcSSimon Schubert 829*5796c8dcSSimon Schubert 830*5796c8dcSSimon Schubert /* Print information about currently known threads 831*5796c8dcSSimon Schubert 832*5796c8dcSSimon Schubert * Note: this has the drawback that it _really_ switches 833*5796c8dcSSimon Schubert * threads, which frees the frame cache. A no-side 834*5796c8dcSSimon Schubert * effects info-threads command would be nicer. 835*5796c8dcSSimon Schubert */ 836*5796c8dcSSimon Schubert 837*5796c8dcSSimon Schubert static void 838*5796c8dcSSimon Schubert info_threads_command (char *arg, int from_tty) 839*5796c8dcSSimon Schubert { 840*5796c8dcSSimon Schubert print_thread_info (uiout, -1, -1); 841*5796c8dcSSimon Schubert } 842*5796c8dcSSimon Schubert 843*5796c8dcSSimon Schubert /* Switch from one thread to another. */ 844*5796c8dcSSimon Schubert 845*5796c8dcSSimon Schubert void 846*5796c8dcSSimon Schubert switch_to_thread (ptid_t ptid) 847*5796c8dcSSimon Schubert { 848*5796c8dcSSimon Schubert if (ptid_equal (ptid, inferior_ptid)) 849*5796c8dcSSimon Schubert return; 850*5796c8dcSSimon Schubert 851*5796c8dcSSimon Schubert inferior_ptid = ptid; 852*5796c8dcSSimon Schubert reinit_frame_cache (); 853*5796c8dcSSimon Schubert registers_changed (); 854*5796c8dcSSimon Schubert 855*5796c8dcSSimon Schubert /* We don't check for is_stopped, because we're called at times 856*5796c8dcSSimon Schubert while in the TARGET_RUNNING state, e.g., while handling an 857*5796c8dcSSimon Schubert internal event. */ 858*5796c8dcSSimon Schubert if (!ptid_equal (inferior_ptid, null_ptid) 859*5796c8dcSSimon Schubert && !is_exited (ptid) 860*5796c8dcSSimon Schubert && !is_executing (ptid)) 861*5796c8dcSSimon Schubert stop_pc = regcache_read_pc (get_thread_regcache (ptid)); 862*5796c8dcSSimon Schubert else 863*5796c8dcSSimon Schubert stop_pc = ~(CORE_ADDR) 0; 864*5796c8dcSSimon Schubert } 865*5796c8dcSSimon Schubert 866*5796c8dcSSimon Schubert static void 867*5796c8dcSSimon Schubert restore_current_thread (ptid_t ptid) 868*5796c8dcSSimon Schubert { 869*5796c8dcSSimon Schubert switch_to_thread (ptid); 870*5796c8dcSSimon Schubert } 871*5796c8dcSSimon Schubert 872*5796c8dcSSimon Schubert static void 873*5796c8dcSSimon Schubert restore_selected_frame (struct frame_id a_frame_id, int frame_level) 874*5796c8dcSSimon Schubert { 875*5796c8dcSSimon Schubert struct frame_info *frame = NULL; 876*5796c8dcSSimon Schubert int count; 877*5796c8dcSSimon Schubert 878*5796c8dcSSimon Schubert gdb_assert (frame_level >= 0); 879*5796c8dcSSimon Schubert 880*5796c8dcSSimon Schubert /* Restore by level first, check if the frame id is the same as 881*5796c8dcSSimon Schubert expected. If that fails, try restoring by frame id. If that 882*5796c8dcSSimon Schubert fails, nothing to do, just warn the user. */ 883*5796c8dcSSimon Schubert 884*5796c8dcSSimon Schubert count = frame_level; 885*5796c8dcSSimon Schubert frame = find_relative_frame (get_current_frame (), &count); 886*5796c8dcSSimon Schubert if (count == 0 887*5796c8dcSSimon Schubert && frame != NULL 888*5796c8dcSSimon Schubert /* The frame ids must match - either both valid or both outer_frame_id. 889*5796c8dcSSimon Schubert The latter case is not failsafe, but since it's highly unlikely 890*5796c8dcSSimon Schubert the search by level finds the wrong frame, it's 99.9(9)% of 891*5796c8dcSSimon Schubert the time (for all practical purposes) safe. */ 892*5796c8dcSSimon Schubert && frame_id_eq (get_frame_id (frame), a_frame_id)) 893*5796c8dcSSimon Schubert { 894*5796c8dcSSimon Schubert /* Cool, all is fine. */ 895*5796c8dcSSimon Schubert select_frame (frame); 896*5796c8dcSSimon Schubert return; 897*5796c8dcSSimon Schubert } 898*5796c8dcSSimon Schubert 899*5796c8dcSSimon Schubert frame = frame_find_by_id (a_frame_id); 900*5796c8dcSSimon Schubert if (frame != NULL) 901*5796c8dcSSimon Schubert { 902*5796c8dcSSimon Schubert /* Cool, refound it. */ 903*5796c8dcSSimon Schubert select_frame (frame); 904*5796c8dcSSimon Schubert return; 905*5796c8dcSSimon Schubert } 906*5796c8dcSSimon Schubert 907*5796c8dcSSimon Schubert /* Nothing else to do, the frame layout really changed. Select the 908*5796c8dcSSimon Schubert innermost stack frame. */ 909*5796c8dcSSimon Schubert select_frame (get_current_frame ()); 910*5796c8dcSSimon Schubert 911*5796c8dcSSimon Schubert /* Warn the user. */ 912*5796c8dcSSimon Schubert if (!ui_out_is_mi_like_p (uiout)) 913*5796c8dcSSimon Schubert { 914*5796c8dcSSimon Schubert warning (_("\ 915*5796c8dcSSimon Schubert Couldn't restore frame #%d in current thread, at reparsed frame #0\n"), 916*5796c8dcSSimon Schubert frame_level); 917*5796c8dcSSimon Schubert /* For MI, we should probably have a notification about 918*5796c8dcSSimon Schubert current frame change. But this error is not very 919*5796c8dcSSimon Schubert likely, so don't bother for now. */ 920*5796c8dcSSimon Schubert print_stack_frame (get_selected_frame (NULL), 1, SRC_LINE); 921*5796c8dcSSimon Schubert } 922*5796c8dcSSimon Schubert } 923*5796c8dcSSimon Schubert 924*5796c8dcSSimon Schubert struct current_thread_cleanup 925*5796c8dcSSimon Schubert { 926*5796c8dcSSimon Schubert ptid_t inferior_ptid; 927*5796c8dcSSimon Schubert struct frame_id selected_frame_id; 928*5796c8dcSSimon Schubert int selected_frame_level; 929*5796c8dcSSimon Schubert int was_stopped; 930*5796c8dcSSimon Schubert }; 931*5796c8dcSSimon Schubert 932*5796c8dcSSimon Schubert static void 933*5796c8dcSSimon Schubert do_restore_current_thread_cleanup (void *arg) 934*5796c8dcSSimon Schubert { 935*5796c8dcSSimon Schubert struct thread_info *tp; 936*5796c8dcSSimon Schubert struct current_thread_cleanup *old = arg; 937*5796c8dcSSimon Schubert 938*5796c8dcSSimon Schubert tp = find_thread_ptid (old->inferior_ptid); 939*5796c8dcSSimon Schubert 940*5796c8dcSSimon Schubert /* If the previously selected thread belonged to a process that has 941*5796c8dcSSimon Schubert in the mean time been deleted (due to normal exit, detach, etc.), 942*5796c8dcSSimon Schubert then don't revert back to it, but instead simply drop back to no 943*5796c8dcSSimon Schubert thread selected. */ 944*5796c8dcSSimon Schubert if (tp 945*5796c8dcSSimon Schubert && find_inferior_pid (ptid_get_pid (tp->ptid)) != NULL) 946*5796c8dcSSimon Schubert restore_current_thread (old->inferior_ptid); 947*5796c8dcSSimon Schubert else 948*5796c8dcSSimon Schubert restore_current_thread (null_ptid); 949*5796c8dcSSimon Schubert 950*5796c8dcSSimon Schubert /* The running state of the originally selected thread may have 951*5796c8dcSSimon Schubert changed, so we have to recheck it here. */ 952*5796c8dcSSimon Schubert if (!ptid_equal (inferior_ptid, null_ptid) 953*5796c8dcSSimon Schubert && old->was_stopped 954*5796c8dcSSimon Schubert && is_stopped (inferior_ptid) 955*5796c8dcSSimon Schubert && target_has_registers 956*5796c8dcSSimon Schubert && target_has_stack 957*5796c8dcSSimon Schubert && target_has_memory) 958*5796c8dcSSimon Schubert restore_selected_frame (old->selected_frame_id, 959*5796c8dcSSimon Schubert old->selected_frame_level); 960*5796c8dcSSimon Schubert } 961*5796c8dcSSimon Schubert 962*5796c8dcSSimon Schubert static void 963*5796c8dcSSimon Schubert restore_current_thread_cleanup_dtor (void *arg) 964*5796c8dcSSimon Schubert { 965*5796c8dcSSimon Schubert struct current_thread_cleanup *old = arg; 966*5796c8dcSSimon Schubert struct thread_info *tp; 967*5796c8dcSSimon Schubert tp = find_thread_ptid (old->inferior_ptid); 968*5796c8dcSSimon Schubert if (tp) 969*5796c8dcSSimon Schubert tp->refcount--; 970*5796c8dcSSimon Schubert xfree (old); 971*5796c8dcSSimon Schubert } 972*5796c8dcSSimon Schubert 973*5796c8dcSSimon Schubert struct cleanup * 974*5796c8dcSSimon Schubert make_cleanup_restore_current_thread (void) 975*5796c8dcSSimon Schubert { 976*5796c8dcSSimon Schubert struct thread_info *tp; 977*5796c8dcSSimon Schubert struct frame_info *frame; 978*5796c8dcSSimon Schubert struct current_thread_cleanup *old; 979*5796c8dcSSimon Schubert 980*5796c8dcSSimon Schubert old = xmalloc (sizeof (struct current_thread_cleanup)); 981*5796c8dcSSimon Schubert old->inferior_ptid = inferior_ptid; 982*5796c8dcSSimon Schubert 983*5796c8dcSSimon Schubert if (!ptid_equal (inferior_ptid, null_ptid)) 984*5796c8dcSSimon Schubert { 985*5796c8dcSSimon Schubert old->was_stopped = is_stopped (inferior_ptid); 986*5796c8dcSSimon Schubert if (old->was_stopped 987*5796c8dcSSimon Schubert && target_has_registers 988*5796c8dcSSimon Schubert && target_has_stack 989*5796c8dcSSimon Schubert && target_has_memory) 990*5796c8dcSSimon Schubert frame = get_selected_frame (NULL); 991*5796c8dcSSimon Schubert else 992*5796c8dcSSimon Schubert frame = NULL; 993*5796c8dcSSimon Schubert 994*5796c8dcSSimon Schubert old->selected_frame_id = get_frame_id (frame); 995*5796c8dcSSimon Schubert old->selected_frame_level = frame_relative_level (frame); 996*5796c8dcSSimon Schubert 997*5796c8dcSSimon Schubert tp = find_thread_ptid (inferior_ptid); 998*5796c8dcSSimon Schubert if (tp) 999*5796c8dcSSimon Schubert tp->refcount++; 1000*5796c8dcSSimon Schubert } 1001*5796c8dcSSimon Schubert 1002*5796c8dcSSimon Schubert return make_cleanup_dtor (do_restore_current_thread_cleanup, old, 1003*5796c8dcSSimon Schubert restore_current_thread_cleanup_dtor); 1004*5796c8dcSSimon Schubert } 1005*5796c8dcSSimon Schubert 1006*5796c8dcSSimon Schubert /* Apply a GDB command to a list of threads. List syntax is a whitespace 1007*5796c8dcSSimon Schubert seperated list of numbers, or ranges, or the keyword `all'. Ranges consist 1008*5796c8dcSSimon Schubert of two numbers seperated by a hyphen. Examples: 1009*5796c8dcSSimon Schubert 1010*5796c8dcSSimon Schubert thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4 1011*5796c8dcSSimon Schubert thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9 1012*5796c8dcSSimon Schubert thread apply all p x/i $pc Apply x/i $pc cmd to all threads 1013*5796c8dcSSimon Schubert */ 1014*5796c8dcSSimon Schubert 1015*5796c8dcSSimon Schubert static void 1016*5796c8dcSSimon Schubert thread_apply_all_command (char *cmd, int from_tty) 1017*5796c8dcSSimon Schubert { 1018*5796c8dcSSimon Schubert struct thread_info *tp; 1019*5796c8dcSSimon Schubert struct cleanup *old_chain; 1020*5796c8dcSSimon Schubert char *saved_cmd; 1021*5796c8dcSSimon Schubert 1022*5796c8dcSSimon Schubert if (cmd == NULL || *cmd == '\000') 1023*5796c8dcSSimon Schubert error (_("Please specify a command following the thread ID list")); 1024*5796c8dcSSimon Schubert 1025*5796c8dcSSimon Schubert prune_threads (); 1026*5796c8dcSSimon Schubert target_find_new_threads (); 1027*5796c8dcSSimon Schubert 1028*5796c8dcSSimon Schubert old_chain = make_cleanup_restore_current_thread (); 1029*5796c8dcSSimon Schubert 1030*5796c8dcSSimon Schubert /* Save a copy of the command in case it is clobbered by 1031*5796c8dcSSimon Schubert execute_command */ 1032*5796c8dcSSimon Schubert saved_cmd = xstrdup (cmd); 1033*5796c8dcSSimon Schubert make_cleanup (xfree, saved_cmd); 1034*5796c8dcSSimon Schubert for (tp = thread_list; tp; tp = tp->next) 1035*5796c8dcSSimon Schubert if (thread_alive (tp)) 1036*5796c8dcSSimon Schubert { 1037*5796c8dcSSimon Schubert switch_to_thread (tp->ptid); 1038*5796c8dcSSimon Schubert 1039*5796c8dcSSimon Schubert printf_filtered (_("\nThread %d (%s):\n"), 1040*5796c8dcSSimon Schubert tp->num, target_pid_to_str (inferior_ptid)); 1041*5796c8dcSSimon Schubert execute_command (cmd, from_tty); 1042*5796c8dcSSimon Schubert strcpy (cmd, saved_cmd); /* Restore exact command used previously */ 1043*5796c8dcSSimon Schubert } 1044*5796c8dcSSimon Schubert 1045*5796c8dcSSimon Schubert do_cleanups (old_chain); 1046*5796c8dcSSimon Schubert } 1047*5796c8dcSSimon Schubert 1048*5796c8dcSSimon Schubert static void 1049*5796c8dcSSimon Schubert thread_apply_command (char *tidlist, int from_tty) 1050*5796c8dcSSimon Schubert { 1051*5796c8dcSSimon Schubert char *cmd; 1052*5796c8dcSSimon Schubert char *p; 1053*5796c8dcSSimon Schubert struct cleanup *old_chain; 1054*5796c8dcSSimon Schubert char *saved_cmd; 1055*5796c8dcSSimon Schubert 1056*5796c8dcSSimon Schubert if (tidlist == NULL || *tidlist == '\000') 1057*5796c8dcSSimon Schubert error (_("Please specify a thread ID list")); 1058*5796c8dcSSimon Schubert 1059*5796c8dcSSimon Schubert for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++); 1060*5796c8dcSSimon Schubert 1061*5796c8dcSSimon Schubert if (*cmd == '\000') 1062*5796c8dcSSimon Schubert error (_("Please specify a command following the thread ID list")); 1063*5796c8dcSSimon Schubert 1064*5796c8dcSSimon Schubert /* Save a copy of the command in case it is clobbered by 1065*5796c8dcSSimon Schubert execute_command */ 1066*5796c8dcSSimon Schubert saved_cmd = xstrdup (cmd); 1067*5796c8dcSSimon Schubert old_chain = make_cleanup (xfree, saved_cmd); 1068*5796c8dcSSimon Schubert while (tidlist < cmd) 1069*5796c8dcSSimon Schubert { 1070*5796c8dcSSimon Schubert struct thread_info *tp; 1071*5796c8dcSSimon Schubert int start, end; 1072*5796c8dcSSimon Schubert 1073*5796c8dcSSimon Schubert start = strtol (tidlist, &p, 10); 1074*5796c8dcSSimon Schubert if (p == tidlist) 1075*5796c8dcSSimon Schubert error (_("Error parsing %s"), tidlist); 1076*5796c8dcSSimon Schubert tidlist = p; 1077*5796c8dcSSimon Schubert 1078*5796c8dcSSimon Schubert while (*tidlist == ' ' || *tidlist == '\t') 1079*5796c8dcSSimon Schubert tidlist++; 1080*5796c8dcSSimon Schubert 1081*5796c8dcSSimon Schubert if (*tidlist == '-') /* Got a range of IDs? */ 1082*5796c8dcSSimon Schubert { 1083*5796c8dcSSimon Schubert tidlist++; /* Skip the - */ 1084*5796c8dcSSimon Schubert end = strtol (tidlist, &p, 10); 1085*5796c8dcSSimon Schubert if (p == tidlist) 1086*5796c8dcSSimon Schubert error (_("Error parsing %s"), tidlist); 1087*5796c8dcSSimon Schubert tidlist = p; 1088*5796c8dcSSimon Schubert 1089*5796c8dcSSimon Schubert while (*tidlist == ' ' || *tidlist == '\t') 1090*5796c8dcSSimon Schubert tidlist++; 1091*5796c8dcSSimon Schubert } 1092*5796c8dcSSimon Schubert else 1093*5796c8dcSSimon Schubert end = start; 1094*5796c8dcSSimon Schubert 1095*5796c8dcSSimon Schubert make_cleanup_restore_current_thread (); 1096*5796c8dcSSimon Schubert 1097*5796c8dcSSimon Schubert for (; start <= end; start++) 1098*5796c8dcSSimon Schubert { 1099*5796c8dcSSimon Schubert tp = find_thread_id (start); 1100*5796c8dcSSimon Schubert 1101*5796c8dcSSimon Schubert if (!tp) 1102*5796c8dcSSimon Schubert warning (_("Unknown thread %d."), start); 1103*5796c8dcSSimon Schubert else if (!thread_alive (tp)) 1104*5796c8dcSSimon Schubert warning (_("Thread %d has terminated."), start); 1105*5796c8dcSSimon Schubert else 1106*5796c8dcSSimon Schubert { 1107*5796c8dcSSimon Schubert switch_to_thread (tp->ptid); 1108*5796c8dcSSimon Schubert 1109*5796c8dcSSimon Schubert printf_filtered (_("\nThread %d (%s):\n"), tp->num, 1110*5796c8dcSSimon Schubert target_pid_to_str (inferior_ptid)); 1111*5796c8dcSSimon Schubert execute_command (cmd, from_tty); 1112*5796c8dcSSimon Schubert 1113*5796c8dcSSimon Schubert /* Restore exact command used previously. */ 1114*5796c8dcSSimon Schubert strcpy (cmd, saved_cmd); 1115*5796c8dcSSimon Schubert } 1116*5796c8dcSSimon Schubert } 1117*5796c8dcSSimon Schubert } 1118*5796c8dcSSimon Schubert 1119*5796c8dcSSimon Schubert do_cleanups (old_chain); 1120*5796c8dcSSimon Schubert } 1121*5796c8dcSSimon Schubert 1122*5796c8dcSSimon Schubert /* Switch to the specified thread. Will dispatch off to thread_apply_command 1123*5796c8dcSSimon Schubert if prefix of arg is `apply'. */ 1124*5796c8dcSSimon Schubert 1125*5796c8dcSSimon Schubert static void 1126*5796c8dcSSimon Schubert thread_command (char *tidstr, int from_tty) 1127*5796c8dcSSimon Schubert { 1128*5796c8dcSSimon Schubert if (!tidstr) 1129*5796c8dcSSimon Schubert { 1130*5796c8dcSSimon Schubert if (ptid_equal (inferior_ptid, null_ptid)) 1131*5796c8dcSSimon Schubert error (_("No thread selected")); 1132*5796c8dcSSimon Schubert 1133*5796c8dcSSimon Schubert if (target_has_stack) 1134*5796c8dcSSimon Schubert { 1135*5796c8dcSSimon Schubert if (is_exited (inferior_ptid)) 1136*5796c8dcSSimon Schubert printf_filtered (_("[Current thread is %d (%s) (exited)]\n"), 1137*5796c8dcSSimon Schubert pid_to_thread_id (inferior_ptid), 1138*5796c8dcSSimon Schubert target_pid_to_str (inferior_ptid)); 1139*5796c8dcSSimon Schubert else 1140*5796c8dcSSimon Schubert printf_filtered (_("[Current thread is %d (%s)]\n"), 1141*5796c8dcSSimon Schubert pid_to_thread_id (inferior_ptid), 1142*5796c8dcSSimon Schubert target_pid_to_str (inferior_ptid)); 1143*5796c8dcSSimon Schubert } 1144*5796c8dcSSimon Schubert else 1145*5796c8dcSSimon Schubert error (_("No stack.")); 1146*5796c8dcSSimon Schubert return; 1147*5796c8dcSSimon Schubert } 1148*5796c8dcSSimon Schubert 1149*5796c8dcSSimon Schubert gdb_thread_select (uiout, tidstr, NULL); 1150*5796c8dcSSimon Schubert } 1151*5796c8dcSSimon Schubert 1152*5796c8dcSSimon Schubert /* Print notices when new threads are attached and detached. */ 1153*5796c8dcSSimon Schubert int print_thread_events = 1; 1154*5796c8dcSSimon Schubert static void 1155*5796c8dcSSimon Schubert show_print_thread_events (struct ui_file *file, int from_tty, 1156*5796c8dcSSimon Schubert struct cmd_list_element *c, const char *value) 1157*5796c8dcSSimon Schubert { 1158*5796c8dcSSimon Schubert fprintf_filtered (file, _("\ 1159*5796c8dcSSimon Schubert Printing of thread events is %s.\n"), 1160*5796c8dcSSimon Schubert value); 1161*5796c8dcSSimon Schubert } 1162*5796c8dcSSimon Schubert 1163*5796c8dcSSimon Schubert static int 1164*5796c8dcSSimon Schubert do_captured_thread_select (struct ui_out *uiout, void *tidstr) 1165*5796c8dcSSimon Schubert { 1166*5796c8dcSSimon Schubert int num; 1167*5796c8dcSSimon Schubert struct thread_info *tp; 1168*5796c8dcSSimon Schubert 1169*5796c8dcSSimon Schubert num = value_as_long (parse_and_eval (tidstr)); 1170*5796c8dcSSimon Schubert 1171*5796c8dcSSimon Schubert tp = find_thread_id (num); 1172*5796c8dcSSimon Schubert 1173*5796c8dcSSimon Schubert if (!tp) 1174*5796c8dcSSimon Schubert error (_("Thread ID %d not known."), num); 1175*5796c8dcSSimon Schubert 1176*5796c8dcSSimon Schubert if (!thread_alive (tp)) 1177*5796c8dcSSimon Schubert error (_("Thread ID %d has terminated."), num); 1178*5796c8dcSSimon Schubert 1179*5796c8dcSSimon Schubert switch_to_thread (tp->ptid); 1180*5796c8dcSSimon Schubert 1181*5796c8dcSSimon Schubert annotate_thread_changed (); 1182*5796c8dcSSimon Schubert 1183*5796c8dcSSimon Schubert ui_out_text (uiout, "[Switching to thread "); 1184*5796c8dcSSimon Schubert ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid)); 1185*5796c8dcSSimon Schubert ui_out_text (uiout, " ("); 1186*5796c8dcSSimon Schubert ui_out_text (uiout, target_pid_to_str (inferior_ptid)); 1187*5796c8dcSSimon Schubert ui_out_text (uiout, ")]"); 1188*5796c8dcSSimon Schubert 1189*5796c8dcSSimon Schubert /* Note that we can't reach this with an exited thread, due to the 1190*5796c8dcSSimon Schubert thread_alive check above. */ 1191*5796c8dcSSimon Schubert if (tp->state_ == THREAD_RUNNING) 1192*5796c8dcSSimon Schubert ui_out_text (uiout, "(running)\n"); 1193*5796c8dcSSimon Schubert else 1194*5796c8dcSSimon Schubert print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC); 1195*5796c8dcSSimon Schubert 1196*5796c8dcSSimon Schubert /* Since the current thread may have changed, see if there is any 1197*5796c8dcSSimon Schubert exited thread we can now delete. */ 1198*5796c8dcSSimon Schubert prune_threads (); 1199*5796c8dcSSimon Schubert 1200*5796c8dcSSimon Schubert return GDB_RC_OK; 1201*5796c8dcSSimon Schubert } 1202*5796c8dcSSimon Schubert 1203*5796c8dcSSimon Schubert enum gdb_rc 1204*5796c8dcSSimon Schubert gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message) 1205*5796c8dcSSimon Schubert { 1206*5796c8dcSSimon Schubert if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr, 1207*5796c8dcSSimon Schubert error_message, RETURN_MASK_ALL) < 0) 1208*5796c8dcSSimon Schubert return GDB_RC_FAIL; 1209*5796c8dcSSimon Schubert return GDB_RC_OK; 1210*5796c8dcSSimon Schubert } 1211*5796c8dcSSimon Schubert 1212*5796c8dcSSimon Schubert /* Commands with a prefix of `thread'. */ 1213*5796c8dcSSimon Schubert struct cmd_list_element *thread_cmd_list = NULL; 1214*5796c8dcSSimon Schubert 1215*5796c8dcSSimon Schubert void 1216*5796c8dcSSimon Schubert _initialize_thread (void) 1217*5796c8dcSSimon Schubert { 1218*5796c8dcSSimon Schubert static struct cmd_list_element *thread_apply_list = NULL; 1219*5796c8dcSSimon Schubert 1220*5796c8dcSSimon Schubert add_info ("threads", info_threads_command, 1221*5796c8dcSSimon Schubert _("IDs of currently known threads.")); 1222*5796c8dcSSimon Schubert 1223*5796c8dcSSimon Schubert add_prefix_cmd ("thread", class_run, thread_command, _("\ 1224*5796c8dcSSimon Schubert Use this command to switch between threads.\n\ 1225*5796c8dcSSimon Schubert The new thread ID must be currently known."), 1226*5796c8dcSSimon Schubert &thread_cmd_list, "thread ", 1, &cmdlist); 1227*5796c8dcSSimon Schubert 1228*5796c8dcSSimon Schubert add_prefix_cmd ("apply", class_run, thread_apply_command, 1229*5796c8dcSSimon Schubert _("Apply a command to a list of threads."), 1230*5796c8dcSSimon Schubert &thread_apply_list, "thread apply ", 1, &thread_cmd_list); 1231*5796c8dcSSimon Schubert 1232*5796c8dcSSimon Schubert add_cmd ("all", class_run, thread_apply_all_command, 1233*5796c8dcSSimon Schubert _("Apply a command to all threads."), &thread_apply_list); 1234*5796c8dcSSimon Schubert 1235*5796c8dcSSimon Schubert if (!xdb_commands) 1236*5796c8dcSSimon Schubert add_com_alias ("t", "thread", class_run, 1); 1237*5796c8dcSSimon Schubert 1238*5796c8dcSSimon Schubert add_setshow_boolean_cmd ("thread-events", no_class, 1239*5796c8dcSSimon Schubert &print_thread_events, _("\ 1240*5796c8dcSSimon Schubert Set printing of thread events (such as thread start and exit)."), _("\ 1241*5796c8dcSSimon Schubert Show printing of thread events (such as thread start and exit)."), NULL, 1242*5796c8dcSSimon Schubert NULL, 1243*5796c8dcSSimon Schubert show_print_thread_events, 1244*5796c8dcSSimon Schubert &setprintlist, &showprintlist); 1245*5796c8dcSSimon Schubert } 1246