GDB (API)
/home/stan/gdb/src/gdb/thread.c
Go to the documentation of this file.
00001 /* Multi-process/thread control for GDB, the GNU debugger.
00002 
00003    Copyright (C) 1986-2013 Free Software Foundation, Inc.
00004 
00005    Contributed by Lynx Real-Time Systems, Inc.  Los Gatos, CA.
00006 
00007    This file is part of GDB.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 3 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 #include "defs.h"
00023 #include "symtab.h"
00024 #include "frame.h"
00025 #include "inferior.h"
00026 #include "environ.h"
00027 #include "value.h"
00028 #include "target.h"
00029 #include "gdbthread.h"
00030 #include "exceptions.h"
00031 #include "command.h"
00032 #include "gdbcmd.h"
00033 #include "regcache.h"
00034 #include "gdb.h"
00035 #include "gdb_string.h"
00036 #include "btrace.h"
00037 
00038 #include <ctype.h>
00039 #include <sys/types.h>
00040 #include <signal.h>
00041 #include "ui-out.h"
00042 #include "observer.h"
00043 #include "annotate.h"
00044 #include "cli/cli-decode.h"
00045 #include "gdb_regex.h"
00046 #include "cli/cli-utils.h"
00047 #include "continuations.h"
00048 
00049 /* Definition of struct thread_info exported to gdbthread.h.  */
00050 
00051 /* Prototypes for exported functions.  */
00052 
00053 void _initialize_thread (void);
00054 
00055 /* Prototypes for local functions.  */
00056 
00057 struct thread_info *thread_list = NULL;
00058 static int highest_thread_num;
00059 
00060 static void thread_command (char *tidstr, int from_tty);
00061 static void thread_apply_all_command (char *, int);
00062 static int thread_alive (struct thread_info *);
00063 static void info_threads_command (char *, int);
00064 static void thread_apply_command (char *, int);
00065 static void restore_current_thread (ptid_t);
00066 static void prune_threads (void);
00067 
00068 /* Data to cleanup thread array.  */
00069 
00070 struct thread_array_cleanup
00071 {
00072   /* Array of thread pointers used to set
00073      reference count.  */
00074   struct thread_info **tp_array;
00075 
00076   /* Thread count in the array.  */
00077   int count;
00078 };
00079 
00080 
00081 struct thread_info*
00082 inferior_thread (void)
00083 {
00084   struct thread_info *tp = find_thread_ptid (inferior_ptid);
00085   gdb_assert (tp);
00086   return tp;
00087 }
00088 
00089 void
00090 delete_step_resume_breakpoint (struct thread_info *tp)
00091 {
00092   if (tp && tp->control.step_resume_breakpoint)
00093     {
00094       delete_breakpoint (tp->control.step_resume_breakpoint);
00095       tp->control.step_resume_breakpoint = NULL;
00096     }
00097 }
00098 
00099 void
00100 delete_exception_resume_breakpoint (struct thread_info *tp)
00101 {
00102   if (tp && tp->control.exception_resume_breakpoint)
00103     {
00104       delete_breakpoint (tp->control.exception_resume_breakpoint);
00105       tp->control.exception_resume_breakpoint = NULL;
00106     }
00107 }
00108 
00109 static void
00110 clear_thread_inferior_resources (struct thread_info *tp)
00111 {
00112   /* NOTE: this will take care of any left-over step_resume breakpoints,
00113      but not any user-specified thread-specific breakpoints.  We can not
00114      delete the breakpoint straight-off, because the inferior might not
00115      be stopped at the moment.  */
00116   if (tp->control.step_resume_breakpoint)
00117     {
00118       tp->control.step_resume_breakpoint->disposition = disp_del_at_next_stop;
00119       tp->control.step_resume_breakpoint = NULL;
00120     }
00121 
00122   if (tp->control.exception_resume_breakpoint)
00123     {
00124       tp->control.exception_resume_breakpoint->disposition
00125         = disp_del_at_next_stop;
00126       tp->control.exception_resume_breakpoint = NULL;
00127     }
00128 
00129   delete_longjmp_breakpoint_at_next_stop (tp->num);
00130 
00131   bpstat_clear (&tp->control.stop_bpstat);
00132 
00133   btrace_teardown (tp);
00134 
00135   do_all_intermediate_continuations_thread (tp, 1);
00136   do_all_continuations_thread (tp, 1);
00137 }
00138 
00139 static void
00140 free_thread (struct thread_info *tp)
00141 {
00142   if (tp->private)
00143     {
00144       if (tp->private_dtor)
00145         tp->private_dtor (tp->private);
00146       else
00147         xfree (tp->private);
00148     }
00149 
00150   xfree (tp->name);
00151   xfree (tp);
00152 }
00153 
00154 void
00155 init_thread_list (void)
00156 {
00157   struct thread_info *tp, *tpnext;
00158 
00159   highest_thread_num = 0;
00160 
00161   if (!thread_list)
00162     return;
00163 
00164   for (tp = thread_list; tp; tp = tpnext)
00165     {
00166       tpnext = tp->next;
00167       free_thread (tp);
00168     }
00169 
00170   thread_list = NULL;
00171 }
00172 
00173 /* Allocate a new thread with target id PTID and add it to the thread
00174    list.  */
00175 
00176 static struct thread_info *
00177 new_thread (ptid_t ptid)
00178 {
00179   struct thread_info *tp;
00180 
00181   tp = xcalloc (1, sizeof (*tp));
00182 
00183   tp->ptid = ptid;
00184   tp->num = ++highest_thread_num;
00185   tp->next = thread_list;
00186   thread_list = tp;
00187 
00188   /* Nothing to follow yet.  */
00189   tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
00190   tp->state = THREAD_STOPPED;
00191 
00192   return tp;
00193 }
00194 
00195 struct thread_info *
00196 add_thread_silent (ptid_t ptid)
00197 {
00198   struct thread_info *tp;
00199 
00200   tp = find_thread_ptid (ptid);
00201   if (tp)
00202     /* Found an old thread with the same id.  It has to be dead,
00203        otherwise we wouldn't be adding a new thread with the same id.
00204        The OS is reusing this id --- delete it, and recreate a new
00205        one.  */
00206     {
00207       /* In addition to deleting the thread, if this is the current
00208          thread, then we need to take care that delete_thread doesn't
00209          really delete the thread if it is inferior_ptid.  Create a
00210          new template thread in the list with an invalid ptid, switch
00211          to it, delete the original thread, reset the new thread's
00212          ptid, and switch to it.  */
00213 
00214       if (ptid_equal (inferior_ptid, ptid))
00215         {
00216           tp = new_thread (null_ptid);
00217 
00218           /* Make switch_to_thread not read from the thread.  */
00219           tp->state = THREAD_EXITED;
00220           switch_to_thread (null_ptid);
00221 
00222           /* Now we can delete it.  */
00223           delete_thread (ptid);
00224 
00225           /* Now reset its ptid, and reswitch inferior_ptid to it.  */
00226           tp->ptid = ptid;
00227           tp->state = THREAD_STOPPED;
00228           switch_to_thread (ptid);
00229 
00230           observer_notify_new_thread (tp);
00231 
00232           /* All done.  */
00233           return tp;
00234         }
00235       else
00236         /* Just go ahead and delete it.  */
00237         delete_thread (ptid);
00238     }
00239 
00240   tp = new_thread (ptid);
00241   observer_notify_new_thread (tp);
00242 
00243   return tp;
00244 }
00245 
00246 struct thread_info *
00247 add_thread_with_info (ptid_t ptid, struct private_thread_info *private)
00248 {
00249   struct thread_info *result = add_thread_silent (ptid);
00250 
00251   result->private = private;
00252 
00253   if (print_thread_events)
00254     printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid));
00255 
00256   annotate_new_thread ();
00257   return result;
00258 }
00259 
00260 struct thread_info *
00261 add_thread (ptid_t ptid)
00262 {
00263   return add_thread_with_info (ptid, NULL);
00264 }
00265 
00266 /* Delete thread PTID.  If SILENT, don't notify the observer of this
00267    exit.  */
00268 static void
00269 delete_thread_1 (ptid_t ptid, int silent)
00270 {
00271   struct thread_info *tp, *tpprev;
00272 
00273   tpprev = NULL;
00274 
00275   for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
00276     if (ptid_equal (tp->ptid, ptid))
00277       break;
00278 
00279   if (!tp)
00280     return;
00281 
00282   /* If this is the current thread, or there's code out there that
00283      relies on it existing (refcount > 0) we can't delete yet.  Mark
00284      it as exited, and notify it.  */
00285   if (tp->refcount > 0
00286       || ptid_equal (tp->ptid, inferior_ptid))
00287     {
00288       if (tp->state != THREAD_EXITED)
00289         {
00290           observer_notify_thread_exit (tp, silent);
00291 
00292           /* Tag it as exited.  */
00293           tp->state = THREAD_EXITED;
00294 
00295           /* Clear breakpoints, etc. associated with this thread.  */
00296           clear_thread_inferior_resources (tp);
00297         }
00298 
00299        /* Will be really deleted some other time.  */
00300        return;
00301      }
00302 
00303   /* Notify thread exit, but only if we haven't already.  */
00304   if (tp->state != THREAD_EXITED)
00305     observer_notify_thread_exit (tp, silent);
00306 
00307   /* Tag it as exited.  */
00308   tp->state = THREAD_EXITED;
00309   clear_thread_inferior_resources (tp);
00310 
00311   if (tpprev)
00312     tpprev->next = tp->next;
00313   else
00314     thread_list = tp->next;
00315 
00316   free_thread (tp);
00317 }
00318 
00319 /* Delete thread PTID and notify of thread exit.  If this is
00320    inferior_ptid, don't actually delete it, but tag it as exited and
00321    do the notification.  If PTID is the user selected thread, clear
00322    it.  */
00323 void
00324 delete_thread (ptid_t ptid)
00325 {
00326   delete_thread_1 (ptid, 0 /* not silent */);
00327 }
00328 
00329 void
00330 delete_thread_silent (ptid_t ptid)
00331 {
00332   delete_thread_1 (ptid, 1 /* silent */);
00333 }
00334 
00335 struct thread_info *
00336 find_thread_id (int num)
00337 {
00338   struct thread_info *tp;
00339 
00340   for (tp = thread_list; tp; tp = tp->next)
00341     if (tp->num == num)
00342       return tp;
00343 
00344   return NULL;
00345 }
00346 
00347 /* Find a thread_info by matching PTID.  */
00348 struct thread_info *
00349 find_thread_ptid (ptid_t ptid)
00350 {
00351   struct thread_info *tp;
00352 
00353   for (tp = thread_list; tp; tp = tp->next)
00354     if (ptid_equal (tp->ptid, ptid))
00355       return tp;
00356 
00357   return NULL;
00358 }
00359 
00360 /*
00361  * Thread iterator function.
00362  *
00363  * Calls a callback function once for each thread, so long as
00364  * the callback function returns false.  If the callback function
00365  * returns true, the iteration will end and the current thread
00366  * will be returned.  This can be useful for implementing a 
00367  * search for a thread with arbitrary attributes, or for applying
00368  * some operation to every thread.
00369  *
00370  * FIXME: some of the existing functionality, such as 
00371  * "Thread apply all", might be rewritten using this functionality.
00372  */
00373 
00374 struct thread_info *
00375 iterate_over_threads (int (*callback) (struct thread_info *, void *),
00376                       void *data)
00377 {
00378   struct thread_info *tp, *next;
00379 
00380   for (tp = thread_list; tp; tp = next)
00381     {
00382       next = tp->next;
00383       if ((*callback) (tp, data))
00384         return tp;
00385     }
00386 
00387   return NULL;
00388 }
00389 
00390 int
00391 thread_count (void)
00392 {
00393   int result = 0;
00394   struct thread_info *tp;
00395 
00396   for (tp = thread_list; tp; tp = tp->next)
00397     ++result;
00398 
00399   return result;  
00400 }
00401 
00402 int
00403 valid_thread_id (int num)
00404 {
00405   struct thread_info *tp;
00406 
00407   for (tp = thread_list; tp; tp = tp->next)
00408     if (tp->num == num)
00409       return 1;
00410 
00411   return 0;
00412 }
00413 
00414 int
00415 pid_to_thread_id (ptid_t ptid)
00416 {
00417   struct thread_info *tp;
00418 
00419   for (tp = thread_list; tp; tp = tp->next)
00420     if (ptid_equal (tp->ptid, ptid))
00421       return tp->num;
00422 
00423   return 0;
00424 }
00425 
00426 ptid_t
00427 thread_id_to_pid (int num)
00428 {
00429   struct thread_info *thread = find_thread_id (num);
00430 
00431   if (thread)
00432     return thread->ptid;
00433   else
00434     return pid_to_ptid (-1);
00435 }
00436 
00437 int
00438 in_thread_list (ptid_t ptid)
00439 {
00440   struct thread_info *tp;
00441 
00442   for (tp = thread_list; tp; tp = tp->next)
00443     if (ptid_equal (tp->ptid, ptid))
00444       return 1;
00445 
00446   return 0;                     /* Never heard of 'im.  */
00447 }
00448 
00449 /* Finds the first thread of the inferior given by PID.  If PID is -1,
00450    return the first thread in the list.  */
00451 
00452 struct thread_info *
00453 first_thread_of_process (int pid)
00454 {
00455   struct thread_info *tp, *ret = NULL;
00456 
00457   for (tp = thread_list; tp; tp = tp->next)
00458     if (pid == -1 || ptid_get_pid (tp->ptid) == pid)
00459       if (ret == NULL || tp->num < ret->num)
00460         ret = tp;
00461 
00462   return ret;
00463 }
00464 
00465 struct thread_info *
00466 any_thread_of_process (int pid)
00467 {
00468   struct thread_info *tp;
00469 
00470   for (tp = thread_list; tp; tp = tp->next)
00471     if (ptid_get_pid (tp->ptid) == pid)
00472       return tp;
00473 
00474   return NULL;
00475 }
00476 
00477 struct thread_info *
00478 any_live_thread_of_process (int pid)
00479 {
00480   struct thread_info *tp;
00481   struct thread_info *tp_executing = NULL;
00482 
00483   for (tp = thread_list; tp; tp = tp->next)
00484     if (tp->state != THREAD_EXITED && ptid_get_pid (tp->ptid) == pid)
00485       {
00486         if (tp->executing)
00487           tp_executing = tp;
00488         else
00489           return tp;
00490       }
00491 
00492   return tp_executing;
00493 }
00494 
00495 /* Print a list of thread ids currently known, and the total number of
00496    threads.  To be used from within catch_errors.  */
00497 static int
00498 do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
00499 {
00500   struct thread_info *tp;
00501   int num = 0;
00502   struct cleanup *cleanup_chain;
00503   int current_thread = -1;
00504 
00505   update_thread_list ();
00506 
00507   cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids");
00508 
00509   for (tp = thread_list; tp; tp = tp->next)
00510     {
00511       if (tp->state == THREAD_EXITED)
00512         continue;
00513 
00514       if (ptid_equal (tp->ptid, inferior_ptid))
00515         current_thread = tp->num;
00516 
00517       num++;
00518       ui_out_field_int (uiout, "thread-id", tp->num);
00519     }
00520 
00521   do_cleanups (cleanup_chain);
00522 
00523   if (current_thread != -1)
00524     ui_out_field_int (uiout, "current-thread-id", current_thread);
00525   ui_out_field_int (uiout, "number-of-threads", num);
00526   return GDB_RC_OK;
00527 }
00528 
00529 /* Official gdblib interface function to get a list of thread ids and
00530    the total number.  */
00531 enum gdb_rc
00532 gdb_list_thread_ids (struct ui_out *uiout, char **error_message)
00533 {
00534   if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL,
00535                                  error_message, RETURN_MASK_ALL) < 0)
00536     return GDB_RC_FAIL;
00537   return GDB_RC_OK;
00538 }
00539 
00540 /* Return true if TP is an active thread.  */
00541 static int
00542 thread_alive (struct thread_info *tp)
00543 {
00544   if (tp->state == THREAD_EXITED)
00545     return 0;
00546   if (!target_thread_alive (tp->ptid))
00547     return 0;
00548   return 1;
00549 }
00550 
00551 static void
00552 prune_threads (void)
00553 {
00554   struct thread_info *tp, *next;
00555 
00556   for (tp = thread_list; tp; tp = next)
00557     {
00558       next = tp->next;
00559       if (!thread_alive (tp))
00560         delete_thread (tp->ptid);
00561     }
00562 }
00563 
00564 void
00565 thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid)
00566 {
00567   struct inferior *inf;
00568   struct thread_info *tp;
00569 
00570   /* It can happen that what we knew as the target inferior id
00571      changes.  E.g, target remote may only discover the remote process
00572      pid after adding the inferior to GDB's list.  */
00573   inf = find_inferior_pid (ptid_get_pid (old_ptid));
00574   inf->pid = ptid_get_pid (new_ptid);
00575 
00576   tp = find_thread_ptid (old_ptid);
00577   tp->ptid = new_ptid;
00578 
00579   observer_notify_thread_ptid_changed (old_ptid, new_ptid);
00580 }
00581 
00582 void
00583 set_running (ptid_t ptid, int running)
00584 {
00585   struct thread_info *tp;
00586   int all = ptid_equal (ptid, minus_one_ptid);
00587 
00588   /* We try not to notify the observer if no thread has actually changed 
00589      the running state -- merely to reduce the number of messages to 
00590      frontend.  Frontend is supposed to handle multiple *running just fine.  */
00591   if (all || ptid_is_pid (ptid))
00592     {
00593       int any_started = 0;
00594 
00595       for (tp = thread_list; tp; tp = tp->next)
00596         if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid))
00597           {
00598             if (tp->state == THREAD_EXITED)
00599               continue;
00600             if (running && tp->state == THREAD_STOPPED)
00601               any_started = 1;
00602             tp->state = running ? THREAD_RUNNING : THREAD_STOPPED;
00603           }
00604       if (any_started)
00605         observer_notify_target_resumed (ptid);
00606     }
00607   else
00608     {
00609       int started = 0;
00610 
00611       tp = find_thread_ptid (ptid);
00612       gdb_assert (tp);
00613       gdb_assert (tp->state != THREAD_EXITED);
00614       if (running && tp->state == THREAD_STOPPED)
00615         started = 1;
00616       tp->state = running ? THREAD_RUNNING : THREAD_STOPPED;
00617       if (started)
00618         observer_notify_target_resumed (ptid);
00619     }
00620 }
00621 
00622 static int
00623 is_thread_state (ptid_t ptid, enum thread_state state)
00624 {
00625   struct thread_info *tp;
00626 
00627   tp = find_thread_ptid (ptid);
00628   gdb_assert (tp);
00629   return tp->state == state;
00630 }
00631 
00632 int
00633 is_stopped (ptid_t ptid)
00634 {
00635   return is_thread_state (ptid, THREAD_STOPPED);
00636 }
00637 
00638 int
00639 is_exited (ptid_t ptid)
00640 {
00641   return is_thread_state (ptid, THREAD_EXITED);
00642 }
00643 
00644 int
00645 is_running (ptid_t ptid)
00646 {
00647   return is_thread_state (ptid, THREAD_RUNNING);
00648 }
00649 
00650 int
00651 any_running (void)
00652 {
00653   struct thread_info *tp;
00654 
00655   for (tp = thread_list; tp; tp = tp->next)
00656     if (tp->state == THREAD_RUNNING)
00657       return 1;
00658 
00659   return 0;
00660 }
00661 
00662 int
00663 is_executing (ptid_t ptid)
00664 {
00665   struct thread_info *tp;
00666 
00667   tp = find_thread_ptid (ptid);
00668   gdb_assert (tp);
00669   return tp->executing;
00670 }
00671 
00672 void
00673 set_executing (ptid_t ptid, int executing)
00674 {
00675   struct thread_info *tp;
00676   int all = ptid_equal (ptid, minus_one_ptid);
00677 
00678   if (all || ptid_is_pid (ptid))
00679     {
00680       for (tp = thread_list; tp; tp = tp->next)
00681         if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid))
00682           tp->executing = executing;
00683     }
00684   else
00685     {
00686       tp = find_thread_ptid (ptid);
00687       gdb_assert (tp);
00688       tp->executing = executing;
00689     }
00690 }
00691 
00692 void
00693 set_stop_requested (ptid_t ptid, int stop)
00694 {
00695   struct thread_info *tp;
00696   int all = ptid_equal (ptid, minus_one_ptid);
00697 
00698   if (all || ptid_is_pid (ptid))
00699     {
00700       for (tp = thread_list; tp; tp = tp->next)
00701         if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid))
00702           tp->stop_requested = stop;
00703     }
00704   else
00705     {
00706       tp = find_thread_ptid (ptid);
00707       gdb_assert (tp);
00708       tp->stop_requested = stop;
00709     }
00710 
00711   /* Call the stop requested observer so other components of GDB can
00712      react to this request.  */
00713   if (stop)
00714     observer_notify_thread_stop_requested (ptid);
00715 }
00716 
00717 void
00718 finish_thread_state (ptid_t ptid)
00719 {
00720   struct thread_info *tp;
00721   int all;
00722   int any_started = 0;
00723 
00724   all = ptid_equal (ptid, minus_one_ptid);
00725 
00726   if (all || ptid_is_pid (ptid))
00727     {
00728       for (tp = thread_list; tp; tp = tp->next)
00729         {
00730           if (tp->state == THREAD_EXITED)
00731             continue;
00732           if (all || ptid_get_pid (ptid) == ptid_get_pid (tp->ptid))
00733             {
00734               if (tp->executing && tp->state == THREAD_STOPPED)
00735                 any_started = 1;
00736               tp->state = tp->executing ? THREAD_RUNNING : THREAD_STOPPED;
00737             }
00738         }
00739     }
00740   else
00741     {
00742       tp = find_thread_ptid (ptid);
00743       gdb_assert (tp);
00744       if (tp->state != THREAD_EXITED)
00745         {
00746           if (tp->executing && tp->state == THREAD_STOPPED)
00747             any_started = 1;
00748           tp->state = tp->executing ? THREAD_RUNNING : THREAD_STOPPED;
00749         }
00750     }
00751 
00752   if (any_started)
00753     observer_notify_target_resumed (ptid);
00754 }
00755 
00756 void
00757 finish_thread_state_cleanup (void *arg)
00758 {
00759   ptid_t *ptid_p = arg;
00760 
00761   gdb_assert (arg);
00762 
00763   finish_thread_state (*ptid_p);
00764 }
00765 
00766 int
00767 pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread)
00768 {
00769   return (pc >= thread->control.step_range_start
00770           && pc < thread->control.step_range_end);
00771 }
00772 
00773 /* Prints the list of threads and their details on UIOUT.
00774    This is a version of 'info_threads_command' suitable for
00775    use from MI.
00776    If REQUESTED_THREAD is not -1, it's the GDB id of the thread
00777    that should be printed.  Otherwise, all threads are
00778    printed.
00779    If PID is not -1, only print threads from the process PID.
00780    Otherwise, threads from all attached PIDs are printed.
00781    If both REQUESTED_THREAD and PID are not -1, then the thread
00782    is printed if it belongs to the specified process.  Otherwise,
00783    an error is raised.  */
00784 void
00785 print_thread_info (struct ui_out *uiout, char *requested_threads, int pid)
00786 {
00787   struct thread_info *tp;
00788   ptid_t current_ptid;
00789   struct cleanup *old_chain;
00790   char *extra_info, *name, *target_id;
00791   int current_thread = -1;
00792 
00793   update_thread_list ();
00794   current_ptid = inferior_ptid;
00795 
00796   /* We'll be switching threads temporarily.  */
00797   old_chain = make_cleanup_restore_current_thread ();
00798 
00799   /* For backward compatibility, we make a list for MI.  A table is
00800      preferable for the CLI, though, because it shows table
00801      headers.  */
00802   if (ui_out_is_mi_like_p (uiout))
00803     make_cleanup_ui_out_list_begin_end (uiout, "threads");
00804   else
00805     {
00806       int n_threads = 0;
00807 
00808       for (tp = thread_list; tp; tp = tp->next)
00809         {
00810           if (!number_is_in_list (requested_threads, tp->num))
00811             continue;
00812 
00813           if (pid != -1 && ptid_get_pid (tp->ptid) != pid)
00814             continue;
00815 
00816           if (tp->state == THREAD_EXITED)
00817             continue;
00818 
00819           ++n_threads;
00820         }
00821 
00822       if (n_threads == 0)
00823         {
00824           if (requested_threads == NULL || *requested_threads == '\0')
00825             ui_out_message (uiout, 0, _("No threads.\n"));
00826           else
00827             ui_out_message (uiout, 0, _("No threads match '%s'.\n"),
00828                             requested_threads);
00829           do_cleanups (old_chain);
00830           return;
00831         }
00832 
00833       make_cleanup_ui_out_table_begin_end (uiout, 4, n_threads, "threads");
00834 
00835       ui_out_table_header (uiout, 1, ui_left, "current", "");
00836       ui_out_table_header (uiout, 4, ui_left, "id", "Id");
00837       ui_out_table_header (uiout, 17, ui_left, "target-id", "Target Id");
00838       ui_out_table_header (uiout, 1, ui_left, "frame", "Frame");
00839       ui_out_table_body (uiout);
00840     }
00841 
00842   for (tp = thread_list; tp; tp = tp->next)
00843     {
00844       struct cleanup *chain2;
00845       int core;
00846 
00847       if (!number_is_in_list (requested_threads, tp->num))
00848         continue;
00849 
00850       if (pid != -1 && ptid_get_pid (tp->ptid) != pid)
00851         {
00852           if (requested_threads != NULL && *requested_threads != '\0')
00853             error (_("Requested thread not found in requested process"));
00854           continue;
00855         }
00856 
00857       if (ptid_equal (tp->ptid, current_ptid))
00858         current_thread = tp->num;
00859 
00860       if (tp->state == THREAD_EXITED)
00861         continue;
00862 
00863       chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
00864 
00865       if (ui_out_is_mi_like_p (uiout))
00866         {
00867           /* Compatibility.  */
00868           if (ptid_equal (tp->ptid, current_ptid))
00869             ui_out_text (uiout, "* ");
00870           else
00871             ui_out_text (uiout, "  ");
00872         }
00873       else
00874         {
00875           if (ptid_equal (tp->ptid, current_ptid))
00876             ui_out_field_string (uiout, "current", "*");
00877           else
00878             ui_out_field_skip (uiout, "current");
00879         }
00880 
00881       ui_out_field_int (uiout, "id", tp->num);
00882 
00883       /* For the CLI, we stuff everything into the target-id field.
00884          This is a gross hack to make the output come out looking
00885          correct.  The underlying problem here is that ui-out has no
00886          way to specify that a field's space allocation should be
00887          shared by several fields.  For MI, we do the right thing
00888          instead.  */
00889 
00890       target_id = target_pid_to_str (tp->ptid);
00891       extra_info = target_extra_thread_info (tp);
00892       name = tp->name ? tp->name : target_thread_name (tp);
00893 
00894       if (ui_out_is_mi_like_p (uiout))
00895         {
00896           ui_out_field_string (uiout, "target-id", target_id);
00897           if (extra_info)
00898             ui_out_field_string (uiout, "details", extra_info);
00899           if (name)
00900             ui_out_field_string (uiout, "name", name);
00901         }
00902       else
00903         {
00904           struct cleanup *str_cleanup;
00905           char *contents;
00906 
00907           if (extra_info && name)
00908             contents = xstrprintf ("%s \"%s\" (%s)", target_id,
00909                                    name, extra_info);
00910           else if (extra_info)
00911             contents = xstrprintf ("%s (%s)", target_id, extra_info);
00912           else if (name)
00913             contents = xstrprintf ("%s \"%s\"", target_id, name);
00914           else
00915             contents = xstrdup (target_id);
00916           str_cleanup = make_cleanup (xfree, contents);
00917 
00918           ui_out_field_string (uiout, "target-id", contents);
00919           do_cleanups (str_cleanup);
00920         }
00921 
00922       if (tp->state == THREAD_RUNNING)
00923         ui_out_text (uiout, "(running)\n");
00924       else
00925         {
00926           /* The switch below puts us at the top of the stack (leaf
00927              frame).  */
00928           switch_to_thread (tp->ptid);
00929           print_stack_frame (get_selected_frame (NULL),
00930                              /* For MI output, print frame level.  */
00931                              ui_out_is_mi_like_p (uiout),
00932                              LOCATION, 0);
00933         }
00934 
00935       if (ui_out_is_mi_like_p (uiout))
00936         {
00937           char *state = "stopped";
00938 
00939           if (tp->state == THREAD_RUNNING)
00940             state = "running";
00941           ui_out_field_string (uiout, "state", state);
00942         }
00943 
00944       core = target_core_of_thread (tp->ptid);
00945       if (ui_out_is_mi_like_p (uiout) && core != -1)
00946         ui_out_field_int (uiout, "core", core);
00947 
00948       do_cleanups (chain2);
00949     }
00950 
00951   /* Restores the current thread and the frame selected before
00952      the "info threads" command.  */
00953   do_cleanups (old_chain);
00954 
00955   if (pid == -1 && requested_threads == NULL)
00956     {
00957       gdb_assert (current_thread != -1
00958                   || !thread_list
00959                   || ptid_equal (inferior_ptid, null_ptid));
00960       if (current_thread != -1 && ui_out_is_mi_like_p (uiout))
00961         ui_out_field_int (uiout, "current-thread-id", current_thread);
00962 
00963       if (current_thread != -1 && is_exited (current_ptid))
00964         ui_out_message (uiout, 0, "\n\
00965 The current thread <Thread ID %d> has terminated.  See `help thread'.\n",
00966                         current_thread);
00967       else if (thread_list
00968                && current_thread == -1
00969                && ptid_equal (current_ptid, null_ptid))
00970         ui_out_message (uiout, 0, "\n\
00971 No selected thread.  See `help thread'.\n");
00972     }
00973 }
00974 
00975 /* Print information about currently known threads 
00976 
00977    Optional ARG is a thread id, or list of thread ids.
00978 
00979    Note: this has the drawback that it _really_ switches
00980          threads, which frees the frame cache.  A no-side
00981          effects info-threads command would be nicer.  */
00982 
00983 static void
00984 info_threads_command (char *arg, int from_tty)
00985 {
00986   print_thread_info (current_uiout, arg, -1);
00987 }
00988 
00989 /* Switch from one thread to another.  */
00990 
00991 void
00992 switch_to_thread (ptid_t ptid)
00993 {
00994   /* Switch the program space as well, if we can infer it from the now
00995      current thread.  Otherwise, it's up to the caller to select the
00996      space it wants.  */
00997   if (!ptid_equal (ptid, null_ptid))
00998     {
00999       struct inferior *inf;
01000 
01001       inf = find_inferior_pid (ptid_get_pid (ptid));
01002       gdb_assert (inf != NULL);
01003       set_current_program_space (inf->pspace);
01004       set_current_inferior (inf);
01005     }
01006 
01007   if (ptid_equal (ptid, inferior_ptid))
01008     return;
01009 
01010   inferior_ptid = ptid;
01011   reinit_frame_cache ();
01012 
01013   /* We don't check for is_stopped, because we're called at times
01014      while in the TARGET_RUNNING state, e.g., while handling an
01015      internal event.  */
01016   if (!ptid_equal (inferior_ptid, null_ptid)
01017       && !is_exited (ptid)
01018       && !is_executing (ptid))
01019     stop_pc = regcache_read_pc (get_thread_regcache (ptid));
01020   else
01021     stop_pc = ~(CORE_ADDR) 0;
01022 }
01023 
01024 static void
01025 restore_current_thread (ptid_t ptid)
01026 {
01027   switch_to_thread (ptid);
01028 }
01029 
01030 static void
01031 restore_selected_frame (struct frame_id a_frame_id, int frame_level)
01032 {
01033   struct frame_info *frame = NULL;
01034   int count;
01035 
01036   /* This means there was no selected frame.  */
01037   if (frame_level == -1)
01038     {
01039       select_frame (NULL);
01040       return;
01041     }
01042 
01043   gdb_assert (frame_level >= 0);
01044 
01045   /* Restore by level first, check if the frame id is the same as
01046      expected.  If that fails, try restoring by frame id.  If that
01047      fails, nothing to do, just warn the user.  */
01048 
01049   count = frame_level;
01050   frame = find_relative_frame (get_current_frame (), &count);
01051   if (count == 0
01052       && frame != NULL
01053       /* The frame ids must match - either both valid or both outer_frame_id.
01054          The latter case is not failsafe, but since it's highly unlikely
01055          the search by level finds the wrong frame, it's 99.9(9)% of
01056          the time (for all practical purposes) safe.  */
01057       && frame_id_eq (get_frame_id (frame), a_frame_id))
01058     {
01059       /* Cool, all is fine.  */
01060       select_frame (frame);
01061       return;
01062     }
01063 
01064   frame = frame_find_by_id (a_frame_id);
01065   if (frame != NULL)
01066     {
01067       /* Cool, refound it.  */
01068       select_frame (frame);
01069       return;
01070     }
01071 
01072   /* Nothing else to do, the frame layout really changed.  Select the
01073      innermost stack frame.  */
01074   select_frame (get_current_frame ());
01075 
01076   /* Warn the user.  */
01077   if (frame_level > 0 && !ui_out_is_mi_like_p (current_uiout))
01078     {
01079       warning (_("Couldn't restore frame #%d in "
01080                  "current thread.  Bottom (innermost) frame selected:"),
01081                frame_level);
01082       /* For MI, we should probably have a notification about
01083          current frame change.  But this error is not very
01084          likely, so don't bother for now.  */
01085       print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
01086     }
01087 }
01088 
01089 struct current_thread_cleanup
01090 {
01091   ptid_t inferior_ptid;
01092   struct frame_id selected_frame_id;
01093   int selected_frame_level;
01094   int was_stopped;
01095   int inf_id;
01096   int was_removable;
01097 };
01098 
01099 static void
01100 do_restore_current_thread_cleanup (void *arg)
01101 {
01102   struct thread_info *tp;
01103   struct current_thread_cleanup *old = arg;
01104 
01105   tp = find_thread_ptid (old->inferior_ptid);
01106 
01107   /* If the previously selected thread belonged to a process that has
01108      in the mean time been deleted (due to normal exit, detach, etc.),
01109      then don't revert back to it, but instead simply drop back to no
01110      thread selected.  */
01111   if (tp
01112       && find_inferior_pid (ptid_get_pid (tp->ptid)) != NULL)
01113     restore_current_thread (old->inferior_ptid);
01114   else
01115     {
01116       restore_current_thread (null_ptid);
01117       set_current_inferior (find_inferior_id (old->inf_id));
01118     }
01119 
01120   /* The running state of the originally selected thread may have
01121      changed, so we have to recheck it here.  */
01122   if (!ptid_equal (inferior_ptid, null_ptid)
01123       && old->was_stopped
01124       && is_stopped (inferior_ptid)
01125       && target_has_registers
01126       && target_has_stack
01127       && target_has_memory)
01128     restore_selected_frame (old->selected_frame_id,
01129                             old->selected_frame_level);
01130 }
01131 
01132 static void
01133 restore_current_thread_cleanup_dtor (void *arg)
01134 {
01135   struct current_thread_cleanup *old = arg;
01136   struct thread_info *tp;
01137   struct inferior *inf;
01138 
01139   tp = find_thread_ptid (old->inferior_ptid);
01140   if (tp)
01141     tp->refcount--;
01142   inf = find_inferior_id (old->inf_id);
01143   if (inf != NULL)
01144     inf->removable = old->was_removable;
01145   xfree (old);
01146 }
01147 
01148 /* Set the thread reference count.  */
01149 
01150 static void
01151 set_thread_refcount (void *data)
01152 {
01153   int k;
01154   struct thread_array_cleanup *ta_cleanup = data;
01155 
01156   for (k = 0; k != ta_cleanup->count; k++)
01157     ta_cleanup->tp_array[k]->refcount--;
01158 }
01159 
01160 struct cleanup *
01161 make_cleanup_restore_current_thread (void)
01162 {
01163   struct thread_info *tp;
01164   struct frame_info *frame;
01165   struct current_thread_cleanup *old;
01166 
01167   old = xmalloc (sizeof (struct current_thread_cleanup));
01168   old->inferior_ptid = inferior_ptid;
01169   old->inf_id = current_inferior ()->num;
01170   old->was_removable = current_inferior ()->removable;
01171 
01172   if (!ptid_equal (inferior_ptid, null_ptid))
01173     {
01174       old->was_stopped = is_stopped (inferior_ptid);
01175       if (old->was_stopped
01176           && target_has_registers
01177           && target_has_stack
01178           && target_has_memory)
01179         {
01180           /* When processing internal events, there might not be a
01181              selected frame.  If we naively call get_selected_frame
01182              here, then we can end up reading debuginfo for the
01183              current frame, but we don't generally need the debuginfo
01184              at this point.  */
01185           frame = get_selected_frame_if_set ();
01186         }
01187       else
01188         frame = NULL;
01189 
01190       old->selected_frame_id = get_frame_id (frame);
01191       old->selected_frame_level = frame_relative_level (frame);
01192 
01193       tp = find_thread_ptid (inferior_ptid);
01194       if (tp)
01195         tp->refcount++;
01196     }
01197 
01198   current_inferior ()->removable = 0;
01199 
01200   return make_cleanup_dtor (do_restore_current_thread_cleanup, old,
01201                             restore_current_thread_cleanup_dtor);
01202 }
01203 
01204 /* Apply a GDB command to a list of threads.  List syntax is a whitespace
01205    seperated list of numbers, or ranges, or the keyword `all'.  Ranges consist
01206    of two numbers seperated by a hyphen.  Examples:
01207 
01208    thread apply 1 2 7 4 backtrace       Apply backtrace cmd to threads 1,2,7,4
01209    thread apply 2-7 9 p foo(1)  Apply p foo(1) cmd to threads 2->7 & 9
01210    thread apply all p x/i $pc   Apply x/i $pc cmd to all threads.  */
01211 
01212 static void
01213 thread_apply_all_command (char *cmd, int from_tty)
01214 {
01215   struct cleanup *old_chain;
01216   char *saved_cmd;
01217   int tc;
01218   struct thread_array_cleanup ta_cleanup;
01219 
01220   if (cmd == NULL || *cmd == '\000')
01221     error (_("Please specify a command following the thread ID list"));
01222 
01223   update_thread_list ();
01224 
01225   old_chain = make_cleanup_restore_current_thread ();
01226 
01227   /* Save a copy of the command in case it is clobbered by
01228      execute_command.  */
01229   saved_cmd = xstrdup (cmd);
01230   make_cleanup (xfree, saved_cmd);
01231   tc = thread_count ();
01232 
01233   if (tc)
01234     {
01235       struct thread_info **tp_array;
01236       struct thread_info *tp;
01237       int i = 0, k;
01238 
01239       /* Save a copy of the thread_list in case we execute detach
01240          command.  */
01241       tp_array = xmalloc (sizeof (struct thread_info *) * tc);
01242       make_cleanup (xfree, tp_array);
01243       ta_cleanup.tp_array = tp_array;
01244       ta_cleanup.count = tc;
01245 
01246       ALL_THREADS (tp)
01247         {
01248           tp_array[i] = tp;
01249           tp->refcount++;
01250           i++;
01251         }
01252 
01253       make_cleanup (set_thread_refcount, &ta_cleanup);
01254 
01255       for (k = 0; k != i; k++)
01256         if (thread_alive (tp_array[k]))
01257           {
01258             switch_to_thread (tp_array[k]->ptid);
01259             printf_filtered (_("\nThread %d (%s):\n"), 
01260                              tp_array[k]->num,
01261                              target_pid_to_str (inferior_ptid));
01262             execute_command (cmd, from_tty);
01263 
01264             /* Restore exact command used previously.  */
01265             strcpy (cmd, saved_cmd);
01266           }
01267     }
01268 
01269   do_cleanups (old_chain);
01270 }
01271 
01272 static void
01273 thread_apply_command (char *tidlist, int from_tty)
01274 {
01275   char *cmd;
01276   struct cleanup *old_chain;
01277   char *saved_cmd;
01278   struct get_number_or_range_state state;
01279 
01280   if (tidlist == NULL || *tidlist == '\000')
01281     error (_("Please specify a thread ID list"));
01282 
01283   for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);
01284 
01285   if (*cmd == '\000')
01286     error (_("Please specify a command following the thread ID list"));
01287 
01288   /* Save a copy of the command in case it is clobbered by
01289      execute_command.  */
01290   saved_cmd = xstrdup (cmd);
01291   old_chain = make_cleanup (xfree, saved_cmd);
01292 
01293   init_number_or_range (&state, tidlist);
01294   while (!state.finished && state.string < cmd)
01295     {
01296       struct thread_info *tp;
01297       int start;
01298 
01299       start = get_number_or_range (&state);
01300 
01301       make_cleanup_restore_current_thread ();
01302 
01303       tp = find_thread_id (start);
01304 
01305       if (!tp)
01306         warning (_("Unknown thread %d."), start);
01307       else if (!thread_alive (tp))
01308         warning (_("Thread %d has terminated."), start);
01309       else
01310         {
01311           switch_to_thread (tp->ptid);
01312 
01313           printf_filtered (_("\nThread %d (%s):\n"), tp->num,
01314                            target_pid_to_str (inferior_ptid));
01315           execute_command (cmd, from_tty);
01316 
01317           /* Restore exact command used previously.  */
01318           strcpy (cmd, saved_cmd);
01319         }
01320     }
01321 
01322   do_cleanups (old_chain);
01323 }
01324 
01325 /* Switch to the specified thread.  Will dispatch off to thread_apply_command
01326    if prefix of arg is `apply'.  */
01327 
01328 static void
01329 thread_command (char *tidstr, int from_tty)
01330 {
01331   if (!tidstr)
01332     {
01333       if (ptid_equal (inferior_ptid, null_ptid))
01334         error (_("No thread selected"));
01335 
01336       if (target_has_stack)
01337         {
01338           if (is_exited (inferior_ptid))
01339             printf_filtered (_("[Current thread is %d (%s) (exited)]\n"),
01340                              pid_to_thread_id (inferior_ptid),
01341                              target_pid_to_str (inferior_ptid));
01342           else
01343             printf_filtered (_("[Current thread is %d (%s)]\n"),
01344                              pid_to_thread_id (inferior_ptid),
01345                              target_pid_to_str (inferior_ptid));
01346         }
01347       else
01348         error (_("No stack."));
01349       return;
01350     }
01351 
01352   gdb_thread_select (current_uiout, tidstr, NULL);
01353 }
01354 
01355 /* Implementation of `thread name'.  */
01356 
01357 static void
01358 thread_name_command (char *arg, int from_tty)
01359 {
01360   struct thread_info *info;
01361 
01362   if (ptid_equal (inferior_ptid, null_ptid))
01363     error (_("No thread selected"));
01364 
01365   arg = skip_spaces (arg);
01366 
01367   info = inferior_thread ();
01368   xfree (info->name);
01369   info->name = arg ? xstrdup (arg) : NULL;
01370 }
01371 
01372 /* Find thread ids with a name, target pid, or extra info matching ARG.  */
01373 
01374 static void
01375 thread_find_command (char *arg, int from_tty)
01376 {
01377   struct thread_info *tp;
01378   char *tmp;
01379   unsigned long match = 0;
01380 
01381   if (arg == NULL || *arg == '\0')
01382     error (_("Command requires an argument."));
01383 
01384   tmp = re_comp (arg);
01385   if (tmp != 0)
01386     error (_("Invalid regexp (%s): %s"), tmp, arg);
01387 
01388   update_thread_list ();
01389   for (tp = thread_list; tp; tp = tp->next)
01390     {
01391       if (tp->name != NULL && re_exec (tp->name))
01392         {
01393           printf_filtered (_("Thread %d has name '%s'\n"),
01394                            tp->num, tp->name);
01395           match++;
01396         }
01397 
01398       tmp = target_thread_name (tp);
01399       if (tmp != NULL && re_exec (tmp))
01400         {
01401           printf_filtered (_("Thread %d has target name '%s'\n"),
01402                            tp->num, tmp);
01403           match++;
01404         }
01405 
01406       tmp = target_pid_to_str (tp->ptid);
01407       if (tmp != NULL && re_exec (tmp))
01408         {
01409           printf_filtered (_("Thread %d has target id '%s'\n"),
01410                            tp->num, tmp);
01411           match++;
01412         }
01413 
01414       tmp = target_extra_thread_info (tp);
01415       if (tmp != NULL && re_exec (tmp))
01416         {
01417           printf_filtered (_("Thread %d has extra info '%s'\n"),
01418                            tp->num, tmp);
01419           match++;
01420         }
01421     }
01422   if (!match)
01423     printf_filtered (_("No threads match '%s'\n"), arg);
01424 }
01425 
01426 /* Print notices when new threads are attached and detached.  */
01427 int print_thread_events = 1;
01428 static void
01429 show_print_thread_events (struct ui_file *file, int from_tty,
01430                           struct cmd_list_element *c, const char *value)
01431 {
01432   fprintf_filtered (file,
01433                     _("Printing of thread events is %s.\n"),
01434                     value);
01435 }
01436 
01437 static int
01438 do_captured_thread_select (struct ui_out *uiout, void *tidstr)
01439 {
01440   int num;
01441   struct thread_info *tp;
01442 
01443   num = value_as_long (parse_and_eval (tidstr));
01444 
01445   tp = find_thread_id (num);
01446 
01447   if (!tp)
01448     error (_("Thread ID %d not known."), num);
01449 
01450   if (!thread_alive (tp))
01451     error (_("Thread ID %d has terminated."), num);
01452 
01453   switch_to_thread (tp->ptid);
01454 
01455   annotate_thread_changed ();
01456 
01457   ui_out_text (uiout, "[Switching to thread ");
01458   ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
01459   ui_out_text (uiout, " (");
01460   ui_out_text (uiout, target_pid_to_str (inferior_ptid));
01461   ui_out_text (uiout, ")]");
01462 
01463   /* Note that we can't reach this with an exited thread, due to the
01464      thread_alive check above.  */
01465   if (tp->state == THREAD_RUNNING)
01466     ui_out_text (uiout, "(running)\n");
01467   else
01468     {
01469       ui_out_text (uiout, "\n");
01470       print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
01471     }
01472 
01473   /* Since the current thread may have changed, see if there is any
01474      exited thread we can now delete.  */
01475   prune_threads ();
01476 
01477   return GDB_RC_OK;
01478 }
01479 
01480 enum gdb_rc
01481 gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
01482 {
01483   if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
01484                                  error_message, RETURN_MASK_ALL) < 0)
01485     return GDB_RC_FAIL;
01486   return GDB_RC_OK;
01487 }
01488 
01489 void
01490 update_thread_list (void)
01491 {
01492   prune_threads ();
01493   target_find_new_threads ();
01494 }
01495 
01496 /* Return a new value for the selected thread's id.  Return a value of 0 if
01497    no thread is selected, or no threads exist.  */
01498 
01499 static struct value *
01500 thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var,
01501                       void *ignore)
01502 {
01503   struct thread_info *tp = find_thread_ptid (inferior_ptid);
01504 
01505   return value_from_longest (builtin_type (gdbarch)->builtin_int,
01506                              (tp ? tp->num : 0));
01507 }
01508 
01509 /* Commands with a prefix of `thread'.  */
01510 struct cmd_list_element *thread_cmd_list = NULL;
01511 
01512 /* Implementation of `thread' variable.  */
01513 
01514 static const struct internalvar_funcs thread_funcs =
01515 {
01516   thread_id_make_value,
01517   NULL,
01518   NULL
01519 };
01520 
01521 void
01522 _initialize_thread (void)
01523 {
01524   static struct cmd_list_element *thread_apply_list = NULL;
01525 
01526   add_info ("threads", info_threads_command, 
01527             _("Display currently known threads.\n\
01528 Usage: info threads [ID]...\n\
01529 Optional arguments are thread IDs with spaces between.\n\
01530 If no arguments, all threads are displayed."));
01531 
01532   add_prefix_cmd ("thread", class_run, thread_command, _("\
01533 Use this command to switch between threads.\n\
01534 The new thread ID must be currently known."),
01535                   &thread_cmd_list, "thread ", 1, &cmdlist);
01536 
01537   add_prefix_cmd ("apply", class_run, thread_apply_command,
01538                   _("Apply a command to a list of threads."),
01539                   &thread_apply_list, "thread apply ", 1, &thread_cmd_list);
01540 
01541   add_cmd ("all", class_run, thread_apply_all_command,
01542            _("Apply a command to all threads."), &thread_apply_list);
01543 
01544   add_cmd ("name", class_run, thread_name_command,
01545            _("Set the current thread's name.\n\
01546 Usage: thread name [NAME]\n\
01547 If NAME is not given, then any existing name is removed."), &thread_cmd_list);
01548 
01549   add_cmd ("find", class_run, thread_find_command, _("\
01550 Find threads that match a regular expression.\n\
01551 Usage: thread find REGEXP\n\
01552 Will display thread ids whose name, target ID, or extra info matches REGEXP."),
01553            &thread_cmd_list);
01554 
01555   if (!xdb_commands)
01556     add_com_alias ("t", "thread", class_run, 1);
01557 
01558   add_setshow_boolean_cmd ("thread-events", no_class,
01559          &print_thread_events, _("\
01560 Set printing of thread events (such as thread start and exit)."), _("\
01561 Show printing of thread events (such as thread start and exit)."), NULL,
01562          NULL,
01563          show_print_thread_events,
01564          &setprintlist, &showprintlist);
01565 
01566   create_internalvar_type_lazy ("_thread", &thread_funcs, NULL);
01567 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines