xref: /dflybsd-src/contrib/gdb-7/gdb/thread.c (revision 5796c8dc12c637f18a1740c26afd8d40ffa9b719)
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