/* Multi-process/thread control for GDB, the GNU debugger.

   Copyright (C) 1986-2014 Free Software Foundation, Inc.

   Contributed by Lynx Real-Time Systems, Inc.  Los Gatos, CA.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "symtab.h"
#include "frame.h"
#include "inferior.h"
#include "environ.h"
#include "value.h"
#include "target.h"
#include "gdbthread.h"
#include "exceptions.h"
#include "command.h"
#include "gdbcmd.h"
#include "regcache.h"
#include "gdb.h"
#include <string.h>
#include "btrace.h"

#include <ctype.h>
#include <sys/types.h>
#include <signal.h>
#include "ui-out.h"
#include "observer.h"
#include "annotate.h"
#include "cli/cli-decode.h"
#include "gdb_regex.h"
#include "cli/cli-utils.h"
#include "continuations.h"

/* Definition of struct thread_info exported to gdbthread.h.  */

/* Prototypes for exported functions.  */

void _initialize_thread (void);

/* Prototypes for local functions.  */

struct thread_info *thread_list = NULL;
static int highest_thread_num;

static void thread_command (char *tidstr, int from_tty);
static void thread_apply_all_command (char *, int);
static int thread_alive (struct thread_info *);
static void info_threads_command (char *, int);
static void thread_apply_command (char *, int);
static void restore_current_thread (ptid_t);
static void prune_threads (void);

/* Data to cleanup thread array.  */

struct thread_array_cleanup
{
  /* Array of thread pointers used to set
     reference count.  */
  struct thread_info **tp_array;

  /* Thread count in the array.  */
  int count;
};


struct thread_info*
inferior_thread (void)
{
  struct thread_info *tp = find_thread_ptid (inferior_ptid);
  gdb_assert (tp);
  return tp;
}

void
delete_step_resume_breakpoint (struct thread_info *tp)
{
  if (tp && tp->control.step_resume_breakpoint)
    {
      delete_breakpoint (tp->control.step_resume_breakpoint);
      tp->control.step_resume_breakpoint = NULL;
    }
}

void
delete_exception_resume_breakpoint (struct thread_info *tp)
{
  if (tp && tp->control.exception_resume_breakpoint)
    {
      delete_breakpoint (tp->control.exception_resume_breakpoint);
      tp->control.exception_resume_breakpoint = NULL;
    }
}

static void
clear_thread_inferior_resources (struct thread_info *tp)
{
  /* NOTE: this will take care of any left-over step_resume breakpoints,
     but not any user-specified thread-specific breakpoints.  We can not
     delete the breakpoint straight-off, because the inferior might not
     be stopped at the moment.  */
  if (tp->control.step_resume_breakpoint)
    {
      tp->control.step_resume_breakpoint->disposition = disp_del_at_next_stop;
      tp->control.step_resume_breakpoint = NULL;
    }

  if (tp->control.exception_resume_breakpoint)
    {
      tp->control.exception_resume_breakpoint->disposition
	= disp_del_at_next_stop;
      tp->control.exception_resume_breakpoint = NULL;
    }

  delete_longjmp_breakpoint_at_next_stop (tp->num);

  bpstat_clear (&tp->control.stop_bpstat);

  btrace_teardown (tp);

  do_all_intermediate_continuations_thread (tp, 1);
  do_all_continuations_thread (tp, 1);
}

static void
free_thread (struct thread_info *tp)
{
  if (tp->private)
    {
      if (tp->private_dtor)
	tp->private_dtor (tp->private);
      else
	xfree (tp->private);
    }

  xfree (tp->name);
  xfree (tp);
}

void
init_thread_list (void)
{
  struct thread_info *tp, *tpnext;

  highest_thread_num = 0;

  if (!thread_list)
    return;

  for (tp = thread_list; tp; tp = tpnext)
    {
      tpnext = tp->next;
      free_thread (tp);
    }

  thread_list = NULL;
}

/* Allocate a new thread with target id PTID and add it to the thread
   list.  */

static struct thread_info *
new_thread (ptid_t ptid)
{
  struct thread_info *tp;

  tp = xcalloc (1, sizeof (*tp));

  tp->ptid = ptid;
  tp->num = ++highest_thread_num;
  tp->next = thread_list;
  thread_list = tp;

  /* Nothing to follow yet.  */
  tp->pending_follow.kind = TARGET_WAITKIND_SPURIOUS;
  tp->state = THREAD_STOPPED;

  return tp;
}

struct thread_info *
add_thread_silent (ptid_t ptid)
{
  struct thread_info *tp;

  tp = find_thread_ptid (ptid);
  if (tp)
    /* Found an old thread with the same id.  It has to be dead,
       otherwise we wouldn't be adding a new thread with the same id.
       The OS is reusing this id --- delete it, and recreate a new
       one.  */
    {
      /* In addition to deleting the thread, if this is the current
	 thread, then we need to take care that delete_thread doesn't
	 really delete the thread if it is inferior_ptid.  Create a
	 new template thread in the list with an invalid ptid, switch
	 to it, delete the original thread, reset the new thread's
	 ptid, and switch to it.  */

      if (ptid_equal (inferior_ptid, ptid))
	{
	  tp = new_thread (null_ptid);

	  /* Make switch_to_thread not read from the thread.  */
	  tp->state = THREAD_EXITED;
	  switch_to_thread (null_ptid);

	  /* Now we can delete it.  */
	  delete_thread (ptid);

	  /* Now reset its ptid, and reswitch inferior_ptid to it.  */
	  tp->ptid = ptid;
	  tp->state = THREAD_STOPPED;
	  switch_to_thread (ptid);

	  observer_notify_new_thread (tp);

	  /* All done.  */
	  return tp;
	}
      else
	/* Just go ahead and delete it.  */
	delete_thread (ptid);
    }

  tp = new_thread (ptid);
  observer_notify_new_thread (tp);

  return tp;
}

struct thread_info *
add_thread_with_info (ptid_t ptid, struct private_thread_info *private)
{
  struct thread_info *result = add_thread_silent (ptid);

  result->private = private;

  if (print_thread_events)
    printf_unfiltered (_("[New %s]\n"), target_pid_to_str (ptid));

  annotate_new_thread ();
  return result;
}

struct thread_info *
add_thread (ptid_t ptid)
{
  return add_thread_with_info (ptid, NULL);
}

/* Delete thread PTID.  If SILENT, don't notify the observer of this
   exit.  */
static void
delete_thread_1 (ptid_t ptid, int silent)
{
  struct thread_info *tp, *tpprev;

  tpprev = NULL;

  for (tp = thread_list; tp; tpprev = tp, tp = tp->next)
    if (ptid_equal (tp->ptid, ptid))
      break;

  if (!tp)
    return;

  /* If this is the current thread, or there's code out there that
     relies on it existing (refcount > 0) we can't delete yet.  Mark
     it as exited, and notify it.  */
  if (tp->refcount > 0
      || ptid_equal (tp->ptid, inferior_ptid))
    {
      if (tp->state != THREAD_EXITED)
	{
	  observer_notify_thread_exit (tp, silent);

	  /* Tag it as exited.  */
	  tp->state = THREAD_EXITED;

	  /* Clear breakpoints, etc. associated with this thread.  */
	  clear_thread_inferior_resources (tp);
	}

       /* Will be really deleted some other time.  */
       return;
     }

  /* Notify thread exit, but only if we haven't already.  */
  if (tp->state != THREAD_EXITED)
    observer_notify_thread_exit (tp, silent);

  /* Tag it as exited.  */
  tp->state = THREAD_EXITED;
  clear_thread_inferior_resources (tp);

  if (tpprev)
    tpprev->next = tp->next;
  else
    thread_list = tp->next;

  free_thread (tp);
}

/* Delete thread PTID and notify of thread exit.  If this is
   inferior_ptid, don't actually delete it, but tag it as exited and
   do the notification.  If PTID is the user selected thread, clear
   it.  */
void
delete_thread (ptid_t ptid)
{
  delete_thread_1 (ptid, 0 /* not silent */);
}

void
delete_thread_silent (ptid_t ptid)
{
  delete_thread_1 (ptid, 1 /* silent */);
}

struct thread_info *
find_thread_id (int num)
{
  struct thread_info *tp;

  for (tp = thread_list; tp; tp = tp->next)
    if (tp->num == num)
      return tp;

  return NULL;
}

/* Find a thread_info by matching PTID.  */
struct thread_info *
find_thread_ptid (ptid_t ptid)
{
  struct thread_info *tp;

  for (tp = thread_list; tp; tp = tp->next)
    if (ptid_equal (tp->ptid, ptid))
      return tp;

  return NULL;
}

/*
 * Thread iterator function.
 *
 * Calls a callback function once for each thread, so long as
 * the callback function returns false.  If the callback function
 * returns true, the iteration will end and the current thread
 * will be returned.  This can be useful for implementing a 
 * search for a thread with arbitrary attributes, or for applying
 * some operation to every thread.
 *
 * FIXME: some of the existing functionality, such as 
 * "Thread apply all", might be rewritten using this functionality.
 */

struct thread_info *
iterate_over_threads (int (*callback) (struct thread_info *, void *),
		      void *data)
{
  struct thread_info *tp, *next;

  for (tp = thread_list; tp; tp = next)
    {
      next = tp->next;
      if ((*callback) (tp, data))
	return tp;
    }

  return NULL;
}

int
thread_count (void)
{
  int result = 0;
  struct thread_info *tp;

  for (tp = thread_list; tp; tp = tp->next)
    ++result;

  return result;  
}

int
valid_thread_id (int num)
{
  struct thread_info *tp;

  for (tp = thread_list; tp; tp = tp->next)
    if (tp->num == num)
      return 1;

  return 0;
}

int
pid_to_thread_id (ptid_t ptid)
{
  struct thread_info *tp;

  for (tp = thread_list; tp; tp = tp->next)
    if (ptid_equal (tp->ptid, ptid))
      return tp->num;

  return 0;
}

ptid_t
thread_id_to_pid (int num)
{
  struct thread_info *thread = find_thread_id (num);

  if (thread)
    return thread->ptid;
  else
    return pid_to_ptid (-1);
}

int
in_thread_list (ptid_t ptid)
{
  struct thread_info *tp;

  for (tp = thread_list; tp; tp = tp->next)
    if (ptid_equal (tp->ptid, ptid))
      return 1;

  return 0;			/* Never heard of 'im.  */
}

/* Finds the first thread of the inferior given by PID.  If PID is -1,
   return the first thread in the list.  */

struct thread_info *
first_thread_of_process (int pid)
{
  struct thread_info *tp, *ret = NULL;

  for (tp = thread_list; tp; tp = tp->next)
    if (pid == -1 || ptid_get_pid (tp->ptid) == pid)
      if (ret == NULL || tp->num < ret->num)
	ret = tp;

  return ret;
}

struct thread_info *
any_thread_of_process (int pid)
{
  struct thread_info *tp;

  for (tp = thread_list; tp; tp = tp->next)
    if (ptid_get_pid (tp->ptid) == pid)
      return tp;

  return NULL;
}

struct thread_info *
any_live_thread_of_process (int pid)
{
  struct thread_info *tp;
  struct thread_info *tp_executing = NULL;

  for (tp = thread_list; tp; tp = tp->next)
    if (tp->state != THREAD_EXITED && ptid_get_pid (tp->ptid) == pid)
      {
	if (tp->executing)
	  tp_executing = tp;
	else
	  return tp;
      }

  return tp_executing;
}

/* Print a list of thread ids currently known, and the total number of
   threads.  To be used from within catch_errors.  */
static int
do_captured_list_thread_ids (struct ui_out *uiout, void *arg)
{
  struct thread_info *tp;
  int num = 0;
  struct cleanup *cleanup_chain;
  int current_thread = -1;

  update_thread_list ();

  cleanup_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "thread-ids");

  for (tp = thread_list; tp; tp = tp->next)
    {
      if (tp->state == THREAD_EXITED)
	continue;

      if (ptid_equal (tp->ptid, inferior_ptid))
	current_thread = tp->num;

      num++;
      ui_out_field_int (uiout, "thread-id", tp->num);
    }

  do_cleanups (cleanup_chain);

  if (current_thread != -1)
    ui_out_field_int (uiout, "current-thread-id", current_thread);
  ui_out_field_int (uiout, "number-of-threads", num);
  return GDB_RC_OK;
}

/* Official gdblib interface function to get a list of thread ids and
   the total number.  */
enum gdb_rc
gdb_list_thread_ids (struct ui_out *uiout, char **error_message)
{
  if (catch_exceptions_with_msg (uiout, do_captured_list_thread_ids, NULL,
				 error_message, RETURN_MASK_ALL) < 0)
    return GDB_RC_FAIL;
  return GDB_RC_OK;
}

/* Return true if TP is an active thread.  */
static int
thread_alive (struct thread_info *tp)
{
  if (tp->state == THREAD_EXITED)
    return 0;
  if (!target_thread_alive (tp->ptid))
    return 0;
  return 1;
}

static void
prune_threads (void)
{
  struct thread_info *tp, *next;

  for (tp = thread_list; tp; tp = next)
    {
      next = tp->next;
      if (!thread_alive (tp))
	delete_thread (tp->ptid);
    }
}

void
thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid)
{
  struct inferior *inf;
  struct thread_info *tp;

  /* It can happen that what we knew as the target inferior id
     changes.  E.g, target remote may only discover the remote process
     pid after adding the inferior to GDB's list.  */
  inf = find_inferior_pid (ptid_get_pid (old_ptid));
  inf->pid = ptid_get_pid (new_ptid);

  tp = find_thread_ptid (old_ptid);
  tp->ptid = new_ptid;

  observer_notify_thread_ptid_changed (old_ptid, new_ptid);
}

void
set_running (ptid_t ptid, int running)
{
  struct thread_info *tp;
  int all = ptid_equal (ptid, minus_one_ptid);

  /* We try not to notify the observer if no thread has actually changed 
     the running state -- merely to reduce the number of messages to 
     frontend.  Frontend is supposed to handle multiple *running just fine.  */
  if (all || ptid_is_pid (ptid))
    {
      int any_started = 0;

      for (tp = thread_list; tp; tp = tp->next)
	if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid))
	  {
	    if (tp->state == THREAD_EXITED)
	      continue;
	    if (running && tp->state == THREAD_STOPPED)
	      any_started = 1;
	    tp->state = running ? THREAD_RUNNING : THREAD_STOPPED;
	  }
      if (any_started)
	observer_notify_target_resumed (ptid);
    }
  else
    {
      int started = 0;

      tp = find_thread_ptid (ptid);
      gdb_assert (tp);
      gdb_assert (tp->state != THREAD_EXITED);
      if (running && tp->state == THREAD_STOPPED)
 	started = 1;
      tp->state = running ? THREAD_RUNNING : THREAD_STOPPED;
      if (started)
  	observer_notify_target_resumed (ptid);
    }
}

static int
is_thread_state (ptid_t ptid, enum thread_state state)
{
  struct thread_info *tp;

  tp = find_thread_ptid (ptid);
  gdb_assert (tp);
  return tp->state == state;
}

int
is_stopped (ptid_t ptid)
{
  return is_thread_state (ptid, THREAD_STOPPED);
}

int
is_exited (ptid_t ptid)
{
  return is_thread_state (ptid, THREAD_EXITED);
}

int
is_running (ptid_t ptid)
{
  return is_thread_state (ptid, THREAD_RUNNING);
}

int
any_running (void)
{
  struct thread_info *tp;

  for (tp = thread_list; tp; tp = tp->next)
    if (tp->state == THREAD_RUNNING)
      return 1;

  return 0;
}

int
is_executing (ptid_t ptid)
{
  struct thread_info *tp;

  tp = find_thread_ptid (ptid);
  gdb_assert (tp);
  return tp->executing;
}

void
set_executing (ptid_t ptid, int executing)
{
  struct thread_info *tp;
  int all = ptid_equal (ptid, minus_one_ptid);

  if (all || ptid_is_pid (ptid))
    {
      for (tp = thread_list; tp; tp = tp->next)
	if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid))
	  tp->executing = executing;
    }
  else
    {
      tp = find_thread_ptid (ptid);
      gdb_assert (tp);
      tp->executing = executing;
    }
}

void
set_stop_requested (ptid_t ptid, int stop)
{
  struct thread_info *tp;
  int all = ptid_equal (ptid, minus_one_ptid);

  if (all || ptid_is_pid (ptid))
    {
      for (tp = thread_list; tp; tp = tp->next)
	if (all || ptid_get_pid (tp->ptid) == ptid_get_pid (ptid))
	  tp->stop_requested = stop;
    }
  else
    {
      tp = find_thread_ptid (ptid);
      gdb_assert (tp);
      tp->stop_requested = stop;
    }

  /* Call the stop requested observer so other components of GDB can
     react to this request.  */
  if (stop)
    observer_notify_thread_stop_requested (ptid);
}

void
finish_thread_state (ptid_t ptid)
{
  struct thread_info *tp;
  int all;
  int any_started = 0;

  all = ptid_equal (ptid, minus_one_ptid);

  if (all || ptid_is_pid (ptid))
    {
      for (tp = thread_list; tp; tp = tp->next)
	{
 	  if (tp->state == THREAD_EXITED)
  	    continue;
	  if (all || ptid_get_pid (ptid) == ptid_get_pid (tp->ptid))
	    {
	      if (tp->executing && tp->state == THREAD_STOPPED)
		any_started = 1;
	      tp->state = tp->executing ? THREAD_RUNNING : THREAD_STOPPED;
	    }
	}
    }
  else
    {
      tp = find_thread_ptid (ptid);
      gdb_assert (tp);
      if (tp->state != THREAD_EXITED)
	{
	  if (tp->executing && tp->state == THREAD_STOPPED)
	    any_started = 1;
	  tp->state = tp->executing ? THREAD_RUNNING : THREAD_STOPPED;
	}
    }

  if (any_started)
    observer_notify_target_resumed (ptid);
}

void
finish_thread_state_cleanup (void *arg)
{
  ptid_t *ptid_p = arg;

  gdb_assert (arg);

  finish_thread_state (*ptid_p);
}

int
pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread)
{
  return (pc >= thread->control.step_range_start
	  && pc < thread->control.step_range_end);
}

/* Prints the list of threads and their details on UIOUT.
   This is a version of 'info_threads_command' suitable for
   use from MI.
   If REQUESTED_THREAD is not -1, it's the GDB id of the thread
   that should be printed.  Otherwise, all threads are
   printed.
   If PID is not -1, only print threads from the process PID.
   Otherwise, threads from all attached PIDs are printed.
   If both REQUESTED_THREAD and PID are not -1, then the thread
   is printed if it belongs to the specified process.  Otherwise,
   an error is raised.  */
void
print_thread_info (struct ui_out *uiout, char *requested_threads, int pid)
{
  struct thread_info *tp;
  ptid_t current_ptid;
  struct cleanup *old_chain;
  char *extra_info, *name, *target_id;
  int current_thread = -1;

  update_thread_list ();
  current_ptid = inferior_ptid;

  /* We'll be switching threads temporarily.  */
  old_chain = make_cleanup_restore_current_thread ();

  /* For backward compatibility, we make a list for MI.  A table is
     preferable for the CLI, though, because it shows table
     headers.  */
  if (ui_out_is_mi_like_p (uiout))
    make_cleanup_ui_out_list_begin_end (uiout, "threads");
  else
    {
      int n_threads = 0;

      for (tp = thread_list; tp; tp = tp->next)
	{
	  if (!number_is_in_list (requested_threads, tp->num))
	    continue;

	  if (pid != -1 && ptid_get_pid (tp->ptid) != pid)
	    continue;

	  if (tp->state == THREAD_EXITED)
	    continue;

	  ++n_threads;
	}

      if (n_threads == 0)
	{
	  if (requested_threads == NULL || *requested_threads == '\0')
	    ui_out_message (uiout, 0, _("No threads.\n"));
	  else
	    ui_out_message (uiout, 0, _("No threads match '%s'.\n"),
			    requested_threads);
	  do_cleanups (old_chain);
	  return;
	}

      make_cleanup_ui_out_table_begin_end (uiout, 4, n_threads, "threads");

      ui_out_table_header (uiout, 1, ui_left, "current", "");
      ui_out_table_header (uiout, 4, ui_left, "id", "Id");
      ui_out_table_header (uiout, 17, ui_left, "target-id", "Target Id");
      ui_out_table_header (uiout, 1, ui_left, "frame", "Frame");
      ui_out_table_body (uiout);
    }

  for (tp = thread_list; tp; tp = tp->next)
    {
      struct cleanup *chain2;
      int core;

      if (!number_is_in_list (requested_threads, tp->num))
	continue;

      if (pid != -1 && ptid_get_pid (tp->ptid) != pid)
	{
	  if (requested_threads != NULL && *requested_threads != '\0')
	    error (_("Requested thread not found in requested process"));
	  continue;
	}

      if (ptid_equal (tp->ptid, current_ptid))
	current_thread = tp->num;

      if (tp->state == THREAD_EXITED)
	continue;

      chain2 = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);

      if (ui_out_is_mi_like_p (uiout))
	{
	  /* Compatibility.  */
	  if (ptid_equal (tp->ptid, current_ptid))
	    ui_out_text (uiout, "* ");
	  else
	    ui_out_text (uiout, "  ");
	}
      else
	{
	  if (ptid_equal (tp->ptid, current_ptid))
	    ui_out_field_string (uiout, "current", "*");
	  else
	    ui_out_field_skip (uiout, "current");
	}

      ui_out_field_int (uiout, "id", tp->num);

      /* For the CLI, we stuff everything into the target-id field.
	 This is a gross hack to make the output come out looking
	 correct.  The underlying problem here is that ui-out has no
	 way to specify that a field's space allocation should be
	 shared by several fields.  For MI, we do the right thing
	 instead.  */

      target_id = target_pid_to_str (tp->ptid);
      extra_info = target_extra_thread_info (tp);
      name = tp->name ? tp->name : target_thread_name (tp);

      if (ui_out_is_mi_like_p (uiout))
	{
	  ui_out_field_string (uiout, "target-id", target_id);
	  if (extra_info)
	    ui_out_field_string (uiout, "details", extra_info);
	  if (name)
	    ui_out_field_string (uiout, "name", name);
	}
      else
	{
	  struct cleanup *str_cleanup;
	  char *contents;

	  if (extra_info && name)
	    contents = xstrprintf ("%s \"%s\" (%s)", target_id,
				   name, extra_info);
	  else if (extra_info)
	    contents = xstrprintf ("%s (%s)", target_id, extra_info);
	  else if (name)
	    contents = xstrprintf ("%s \"%s\"", target_id, name);
	  else
	    contents = xstrdup (target_id);
	  str_cleanup = make_cleanup (xfree, contents);

	  ui_out_field_string (uiout, "target-id", contents);
	  do_cleanups (str_cleanup);
	}

      if (tp->state == THREAD_RUNNING)
	ui_out_text (uiout, "(running)\n");
      else
	{
	  /* The switch below puts us at the top of the stack (leaf
	     frame).  */
	  switch_to_thread (tp->ptid);
	  print_stack_frame (get_selected_frame (NULL),
			     /* For MI output, print frame level.  */
			     ui_out_is_mi_like_p (uiout),
			     LOCATION, 0);
	}

      if (ui_out_is_mi_like_p (uiout))
	{
	  char *state = "stopped";

	  if (tp->state == THREAD_RUNNING)
	    state = "running";
	  ui_out_field_string (uiout, "state", state);
	}

      core = target_core_of_thread (tp->ptid);
      if (ui_out_is_mi_like_p (uiout) && core != -1)
	ui_out_field_int (uiout, "core", core);

      do_cleanups (chain2);
    }

  /* Restores the current thread and the frame selected before
     the "info threads" command.  */
  do_cleanups (old_chain);

  if (pid == -1 && requested_threads == NULL)
    {
      gdb_assert (current_thread != -1
		  || !thread_list
		  || ptid_equal (inferior_ptid, null_ptid));
      if (current_thread != -1 && ui_out_is_mi_like_p (uiout))
	ui_out_field_int (uiout, "current-thread-id", current_thread);

      if (current_thread != -1 && is_exited (current_ptid))
	ui_out_message (uiout, 0, "\n\
The current thread <Thread ID %d> has terminated.  See `help thread'.\n",
			current_thread);
      else if (thread_list
	       && current_thread == -1
	       && ptid_equal (current_ptid, null_ptid))
	ui_out_message (uiout, 0, "\n\
No selected thread.  See `help thread'.\n");
    }
}

/* Print information about currently known threads 

   Optional ARG is a thread id, or list of thread ids.

   Note: this has the drawback that it _really_ switches
         threads, which frees the frame cache.  A no-side
         effects info-threads command would be nicer.  */

static void
info_threads_command (char *arg, int from_tty)
{
  print_thread_info (current_uiout, arg, -1);
}

/* Switch from one thread to another.  */

void
switch_to_thread (ptid_t ptid)
{
  /* Switch the program space as well, if we can infer it from the now
     current thread.  Otherwise, it's up to the caller to select the
     space it wants.  */
  if (!ptid_equal (ptid, null_ptid))
    {
      struct inferior *inf;

      inf = find_inferior_pid (ptid_get_pid (ptid));
      gdb_assert (inf != NULL);
      set_current_program_space (inf->pspace);
      set_current_inferior (inf);
    }

  if (ptid_equal (ptid, inferior_ptid))
    return;

  inferior_ptid = ptid;
  reinit_frame_cache ();

  /* We don't check for is_stopped, because we're called at times
     while in the TARGET_RUNNING state, e.g., while handling an
     internal event.  */
  if (!ptid_equal (inferior_ptid, null_ptid)
      && !is_exited (ptid)
      && !is_executing (ptid))
    stop_pc = regcache_read_pc (get_thread_regcache (ptid));
  else
    stop_pc = ~(CORE_ADDR) 0;
}

static void
restore_current_thread (ptid_t ptid)
{
  switch_to_thread (ptid);
}

static void
restore_selected_frame (struct frame_id a_frame_id, int frame_level)
{
  struct frame_info *frame = NULL;
  int count;

  /* This means there was no selected frame.  */
  if (frame_level == -1)
    {
      select_frame (NULL);
      return;
    }

  gdb_assert (frame_level >= 0);

  /* Restore by level first, check if the frame id is the same as
     expected.  If that fails, try restoring by frame id.  If that
     fails, nothing to do, just warn the user.  */

  count = frame_level;
  frame = find_relative_frame (get_current_frame (), &count);
  if (count == 0
      && frame != NULL
      /* The frame ids must match - either both valid or both outer_frame_id.
	 The latter case is not failsafe, but since it's highly unlikely
	 the search by level finds the wrong frame, it's 99.9(9)% of
	 the time (for all practical purposes) safe.  */
      && frame_id_eq (get_frame_id (frame), a_frame_id))
    {
      /* Cool, all is fine.  */
      select_frame (frame);
      return;
    }

  frame = frame_find_by_id (a_frame_id);
  if (frame != NULL)
    {
      /* Cool, refound it.  */
      select_frame (frame);
      return;
    }

  /* Nothing else to do, the frame layout really changed.  Select the
     innermost stack frame.  */
  select_frame (get_current_frame ());

  /* Warn the user.  */
  if (frame_level > 0 && !ui_out_is_mi_like_p (current_uiout))
    {
      warning (_("Couldn't restore frame #%d in "
		 "current thread.  Bottom (innermost) frame selected:"),
	       frame_level);
      /* For MI, we should probably have a notification about
	 current frame change.  But this error is not very
	 likely, so don't bother for now.  */
      print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
    }
}

struct current_thread_cleanup
{
  ptid_t inferior_ptid;
  struct frame_id selected_frame_id;
  int selected_frame_level;
  int was_stopped;
  int inf_id;
  int was_removable;
};

static void
do_restore_current_thread_cleanup (void *arg)
{
  struct thread_info *tp;
  struct current_thread_cleanup *old = arg;

  tp = find_thread_ptid (old->inferior_ptid);

  /* If the previously selected thread belonged to a process that has
     in the mean time been deleted (due to normal exit, detach, etc.),
     then don't revert back to it, but instead simply drop back to no
     thread selected.  */
  if (tp
      && find_inferior_pid (ptid_get_pid (tp->ptid)) != NULL)
    restore_current_thread (old->inferior_ptid);
  else
    {
      restore_current_thread (null_ptid);
      set_current_inferior (find_inferior_id (old->inf_id));
    }

  /* The running state of the originally selected thread may have
     changed, so we have to recheck it here.  */
  if (!ptid_equal (inferior_ptid, null_ptid)
      && old->was_stopped
      && is_stopped (inferior_ptid)
      && target_has_registers
      && target_has_stack
      && target_has_memory)
    restore_selected_frame (old->selected_frame_id,
			    old->selected_frame_level);
}

static void
restore_current_thread_cleanup_dtor (void *arg)
{
  struct current_thread_cleanup *old = arg;
  struct thread_info *tp;
  struct inferior *inf;

  tp = find_thread_ptid (old->inferior_ptid);
  if (tp)
    tp->refcount--;
  inf = find_inferior_id (old->inf_id);
  if (inf != NULL)
    inf->removable = old->was_removable;
  xfree (old);
}

/* Set the thread reference count.  */

static void
set_thread_refcount (void *data)
{
  int k;
  struct thread_array_cleanup *ta_cleanup = data;

  for (k = 0; k != ta_cleanup->count; k++)
    ta_cleanup->tp_array[k]->refcount--;
}

struct cleanup *
make_cleanup_restore_current_thread (void)
{
  struct thread_info *tp;
  struct frame_info *frame;
  struct current_thread_cleanup *old;

  old = xmalloc (sizeof (struct current_thread_cleanup));
  old->inferior_ptid = inferior_ptid;
  old->inf_id = current_inferior ()->num;
  old->was_removable = current_inferior ()->removable;

  if (!ptid_equal (inferior_ptid, null_ptid))
    {
      old->was_stopped = is_stopped (inferior_ptid);
      if (old->was_stopped
	  && target_has_registers
	  && target_has_stack
	  && target_has_memory)
	{
	  /* When processing internal events, there might not be a
	     selected frame.  If we naively call get_selected_frame
	     here, then we can end up reading debuginfo for the
	     current frame, but we don't generally need the debuginfo
	     at this point.  */
	  frame = get_selected_frame_if_set ();
	}
      else
	frame = NULL;

      old->selected_frame_id = get_frame_id (frame);
      old->selected_frame_level = frame_relative_level (frame);

      tp = find_thread_ptid (inferior_ptid);
      if (tp)
	tp->refcount++;
    }

  current_inferior ()->removable = 0;

  return make_cleanup_dtor (do_restore_current_thread_cleanup, old,
			    restore_current_thread_cleanup_dtor);
}

/* Apply a GDB command to a list of threads.  List syntax is a whitespace
   seperated list of numbers, or ranges, or the keyword `all'.  Ranges consist
   of two numbers seperated by a hyphen.  Examples:

   thread apply 1 2 7 4 backtrace       Apply backtrace cmd to threads 1,2,7,4
   thread apply 2-7 9 p foo(1)  Apply p foo(1) cmd to threads 2->7 & 9
   thread apply all p x/i $pc   Apply x/i $pc cmd to all threads.  */

static void
thread_apply_all_command (char *cmd, int from_tty)
{
  struct cleanup *old_chain;
  char *saved_cmd;
  int tc;
  struct thread_array_cleanup ta_cleanup;

  if (cmd == NULL || *cmd == '\000')
    error (_("Please specify a command following the thread ID list"));

  update_thread_list ();

  old_chain = make_cleanup_restore_current_thread ();

  /* Save a copy of the command in case it is clobbered by
     execute_command.  */
  saved_cmd = xstrdup (cmd);
  make_cleanup (xfree, saved_cmd);
  tc = thread_count ();

  if (tc)
    {
      struct thread_info **tp_array;
      struct thread_info *tp;
      int i = 0, k;

      /* Save a copy of the thread_list in case we execute detach
         command.  */
      tp_array = xmalloc (sizeof (struct thread_info *) * tc);
      make_cleanup (xfree, tp_array);
      ta_cleanup.tp_array = tp_array;
      ta_cleanup.count = tc;

      ALL_NON_EXITED_THREADS (tp)
        {
          tp_array[i] = tp;
          tp->refcount++;
          i++;
        }

      make_cleanup (set_thread_refcount, &ta_cleanup);

      for (k = 0; k != i; k++)
        if (thread_alive (tp_array[k]))
          {
            switch_to_thread (tp_array[k]->ptid);
            printf_filtered (_("\nThread %d (%s):\n"), 
			     tp_array[k]->num,
			     target_pid_to_str (inferior_ptid));
            execute_command (cmd, from_tty);

            /* Restore exact command used previously.  */
            strcpy (cmd, saved_cmd);
	  }
    }

  do_cleanups (old_chain);
}

static void
thread_apply_command (char *tidlist, int from_tty)
{
  char *cmd;
  struct cleanup *old_chain;
  char *saved_cmd;
  struct get_number_or_range_state state;

  if (tidlist == NULL || *tidlist == '\000')
    error (_("Please specify a thread ID list"));

  for (cmd = tidlist; *cmd != '\000' && !isalpha (*cmd); cmd++);

  if (*cmd == '\000')
    error (_("Please specify a command following the thread ID list"));

  /* Save a copy of the command in case it is clobbered by
     execute_command.  */
  saved_cmd = xstrdup (cmd);
  old_chain = make_cleanup (xfree, saved_cmd);

  init_number_or_range (&state, tidlist);
  while (!state.finished && state.string < cmd)
    {
      struct thread_info *tp;
      int start;

      start = get_number_or_range (&state);

      make_cleanup_restore_current_thread ();

      tp = find_thread_id (start);

      if (!tp)
	warning (_("Unknown thread %d."), start);
      else if (!thread_alive (tp))
	warning (_("Thread %d has terminated."), start);
      else
	{
	  switch_to_thread (tp->ptid);

	  printf_filtered (_("\nThread %d (%s):\n"), tp->num,
			   target_pid_to_str (inferior_ptid));
	  execute_command (cmd, from_tty);

	  /* Restore exact command used previously.  */
	  strcpy (cmd, saved_cmd);
	}
    }

  do_cleanups (old_chain);
}

/* Switch to the specified thread.  Will dispatch off to thread_apply_command
   if prefix of arg is `apply'.  */

static void
thread_command (char *tidstr, int from_tty)
{
  if (!tidstr)
    {
      if (ptid_equal (inferior_ptid, null_ptid))
	error (_("No thread selected"));

      if (target_has_stack)
	{
	  if (is_exited (inferior_ptid))
	    printf_filtered (_("[Current thread is %d (%s) (exited)]\n"),
			     pid_to_thread_id (inferior_ptid),
			     target_pid_to_str (inferior_ptid));
	  else
	    printf_filtered (_("[Current thread is %d (%s)]\n"),
			     pid_to_thread_id (inferior_ptid),
			     target_pid_to_str (inferior_ptid));
	}
      else
	error (_("No stack."));
      return;
    }

  gdb_thread_select (current_uiout, tidstr, NULL);
}

/* Implementation of `thread name'.  */

static void
thread_name_command (char *arg, int from_tty)
{
  struct thread_info *info;

  if (ptid_equal (inferior_ptid, null_ptid))
    error (_("No thread selected"));

  arg = skip_spaces (arg);

  info = inferior_thread ();
  xfree (info->name);
  info->name = arg ? xstrdup (arg) : NULL;
}

/* Find thread ids with a name, target pid, or extra info matching ARG.  */

static void
thread_find_command (char *arg, int from_tty)
{
  struct thread_info *tp;
  char *tmp;
  unsigned long match = 0;

  if (arg == NULL || *arg == '\0')
    error (_("Command requires an argument."));

  tmp = re_comp (arg);
  if (tmp != 0)
    error (_("Invalid regexp (%s): %s"), tmp, arg);

  update_thread_list ();
  for (tp = thread_list; tp; tp = tp->next)
    {
      if (tp->name != NULL && re_exec (tp->name))
	{
	  printf_filtered (_("Thread %d has name '%s'\n"),
			   tp->num, tp->name);
	  match++;
	}

      tmp = target_thread_name (tp);
      if (tmp != NULL && re_exec (tmp))
	{
	  printf_filtered (_("Thread %d has target name '%s'\n"),
			   tp->num, tmp);
	  match++;
	}

      tmp = target_pid_to_str (tp->ptid);
      if (tmp != NULL && re_exec (tmp))
	{
	  printf_filtered (_("Thread %d has target id '%s'\n"),
			   tp->num, tmp);
	  match++;
	}

      tmp = target_extra_thread_info (tp);
      if (tmp != NULL && re_exec (tmp))
	{
	  printf_filtered (_("Thread %d has extra info '%s'\n"),
			   tp->num, tmp);
	  match++;
	}
    }
  if (!match)
    printf_filtered (_("No threads match '%s'\n"), arg);
}

/* Print notices when new threads are attached and detached.  */
int print_thread_events = 1;
static void
show_print_thread_events (struct ui_file *file, int from_tty,
                          struct cmd_list_element *c, const char *value)
{
  fprintf_filtered (file,
		    _("Printing of thread events is %s.\n"),
                    value);
}

static int
do_captured_thread_select (struct ui_out *uiout, void *tidstr)
{
  int num;
  struct thread_info *tp;

  num = value_as_long (parse_and_eval (tidstr));

  tp = find_thread_id (num);

  if (!tp)
    error (_("Thread ID %d not known."), num);

  if (!thread_alive (tp))
    error (_("Thread ID %d has terminated."), num);

  switch_to_thread (tp->ptid);

  annotate_thread_changed ();

  ui_out_text (uiout, "[Switching to thread ");
  ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
  ui_out_text (uiout, " (");
  ui_out_text (uiout, target_pid_to_str (inferior_ptid));
  ui_out_text (uiout, ")]");

  /* Note that we can't reach this with an exited thread, due to the
     thread_alive check above.  */
  if (tp->state == THREAD_RUNNING)
    ui_out_text (uiout, "(running)\n");
  else
    {
      ui_out_text (uiout, "\n");
      print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
    }

  /* Since the current thread may have changed, see if there is any
     exited thread we can now delete.  */
  prune_threads ();

  return GDB_RC_OK;
}

enum gdb_rc
gdb_thread_select (struct ui_out *uiout, char *tidstr, char **error_message)
{
  if (catch_exceptions_with_msg (uiout, do_captured_thread_select, tidstr,
				 error_message, RETURN_MASK_ALL) < 0)
    return GDB_RC_FAIL;
  return GDB_RC_OK;
}

void
update_thread_list (void)
{
  prune_threads ();
  target_find_new_threads ();
}

/* Return a new value for the selected thread's id.  Return a value of 0 if
   no thread is selected, or no threads exist.  */

static struct value *
thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var,
		      void *ignore)
{
  struct thread_info *tp = find_thread_ptid (inferior_ptid);

  return value_from_longest (builtin_type (gdbarch)->builtin_int,
			     (tp ? tp->num : 0));
}

/* Commands with a prefix of `thread'.  */
struct cmd_list_element *thread_cmd_list = NULL;

/* Implementation of `thread' variable.  */

static const struct internalvar_funcs thread_funcs =
{
  thread_id_make_value,
  NULL,
  NULL
};

void
_initialize_thread (void)
{
  static struct cmd_list_element *thread_apply_list = NULL;

  add_info ("threads", info_threads_command, 
	    _("Display currently known threads.\n\
Usage: info threads [ID]...\n\
Optional arguments are thread IDs with spaces between.\n\
If no arguments, all threads are displayed."));

  add_prefix_cmd ("thread", class_run, thread_command, _("\
Use this command to switch between threads.\n\
The new thread ID must be currently known."),
		  &thread_cmd_list, "thread ", 1, &cmdlist);

  add_prefix_cmd ("apply", class_run, thread_apply_command,
		  _("Apply a command to a list of threads."),
		  &thread_apply_list, "thread apply ", 1, &thread_cmd_list);

  add_cmd ("all", class_run, thread_apply_all_command,
	   _("Apply a command to all threads."), &thread_apply_list);

  add_cmd ("name", class_run, thread_name_command,
	   _("Set the current thread's name.\n\
Usage: thread name [NAME]\n\
If NAME is not given, then any existing name is removed."), &thread_cmd_list);

  add_cmd ("find", class_run, thread_find_command, _("\
Find threads that match a regular expression.\n\
Usage: thread find REGEXP\n\
Will display thread ids whose name, target ID, or extra info matches REGEXP."),
	   &thread_cmd_list);

  if (!xdb_commands)
    add_com_alias ("t", "thread", class_run, 1);

  add_setshow_boolean_cmd ("thread-events", no_class,
         &print_thread_events, _("\
Set printing of thread events (such as thread start and exit)."), _("\
Show printing of thread events (such as thread start and exit)."), NULL,
         NULL,
         show_print_thread_events,
         &setprintlist, &showprintlist);

  create_internalvar_type_lazy ("_thread", &thread_funcs, NULL);
}
