/* GNU/Linux native-dependent code for debugging multiple forks.

   Copyright (C) 2005-2020 Free Software Foundation, Inc.

   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 "arch-utils.h"
#include "inferior.h"
#include "infrun.h"
#include "regcache.h"
#include "gdbcmd.h"
#include "infcall.h"
#include "objfiles.h"
#include "linux-fork.h"
#include "linux-nat.h"
#include "gdbthread.h"
#include "source.h"

#include "nat/gdb_ptrace.h"
#include "gdbsupport/gdb_wait.h"
#include <dirent.h>
#include <ctype.h>

#include <list>

/* Fork list data structure:  */
struct fork_info
{
  explicit fork_info (pid_t pid)
    : ptid (pid, pid, 0)
  {
  }

  ~fork_info ()
  {
    /* Notes on step-resume breakpoints: since this is a concern for
       threads, let's convince ourselves that it's not a concern for
       forks.  There are two ways for a fork_info to be created.
       First, by the checkpoint command, in which case we're at a gdb
       prompt and there can't be any step-resume breakpoint.  Second,
       by a fork in the user program, in which case we *may* have
       stepped into the fork call, but regardless of whether we follow
       the parent or the child, we will return to the same place and
       the step-resume breakpoint, if any, will take care of itself as
       usual.  And unlike threads, we do not save a private copy of
       the step-resume breakpoint -- so we're OK.  */

    if (savedregs)
      delete savedregs;
    if (filepos)
      xfree (filepos);
  }

  ptid_t ptid = null_ptid;
  ptid_t parent_ptid = null_ptid;

  /* Convenient handle (GDB fork id).  */
  int num = 0;

  /* Convenient for info fork, saves having to actually switch
     contexts.  */
  readonly_detached_regcache *savedregs = nullptr;

  CORE_ADDR pc = 0;

  /* Set of open file descriptors' offsets.  */
  off_t *filepos = nullptr;

  int maxfd = 0;
};

static std::list<fork_info> fork_list;
static int highest_fork_num;

/* Fork list methods:  */

int
forks_exist_p (void)
{
  return !fork_list.empty ();
}

/* Return the last fork in the list.  */

static struct fork_info *
find_last_fork (void)
{
  if (fork_list.empty ())
    return NULL;

  return &fork_list.back ();
}

/* Return true iff there's one fork in the list.  */

static bool
one_fork_p ()
{
  return fork_list.size () == 1;
}

/* Add a new fork to the internal fork list.  */

void
add_fork (pid_t pid)
{
  fork_list.emplace_back (pid);

  if (one_fork_p ())
    highest_fork_num = 0;

  fork_info *fp = &fork_list.back ();
  fp->num = ++highest_fork_num;
}

static void
delete_fork (ptid_t ptid)
{
  linux_target->low_forget_process (ptid.pid ());

  for (auto it = fork_list.begin (); it != fork_list.end (); ++it)
    if (it->ptid == ptid)
      {
	fork_list.erase (it);

	/* Special case: if there is now only one process in the list,
	   and if it is (hopefully!) the current inferior_ptid, then
	   remove it, leaving the list empty -- we're now down to the
	   default case of debugging a single process.  */
	if (one_fork_p () && fork_list.front ().ptid == inferior_ptid)
	  {
	    /* Last fork -- delete from list and handle as solo
	       process (should be a safe recursion).  */
	    delete_fork (inferior_ptid);
	  }
	return;
      }
}

/* Find a fork_info by matching PTID.  */
static struct fork_info *
find_fork_ptid (ptid_t ptid)
{
  for (fork_info &fi : fork_list)
    if (fi.ptid == ptid)
      return &fi;

  return NULL;
}

/* Find a fork_info by matching ID.  */
static struct fork_info *
find_fork_id (int num)
{
  for (fork_info &fi : fork_list)
    if (fi.num == num)
      return &fi;

  return NULL;
}

/* Find a fork_info by matching pid.  */
extern struct fork_info *
find_fork_pid (pid_t pid)
{
  for (fork_info &fi : fork_list)
    if (pid == fi.ptid.pid ())
      return &fi;

  return NULL;
}

static ptid_t
fork_id_to_ptid (int num)
{
  struct fork_info *fork = find_fork_id (num);
  if (fork)
    return fork->ptid;
  else
    return ptid_t (-1);
}

/* Fork list <-> gdb interface.  */

/* Utility function for fork_load/fork_save.
   Calls lseek in the (current) inferior process.  */

static off_t
call_lseek (int fd, off_t offset, int whence)
{
  char exp[80];

  snprintf (&exp[0], sizeof (exp), "(long) lseek (%d, %ld, %d)",
	    fd, (long) offset, whence);
  return (off_t) parse_and_eval_long (&exp[0]);
}

/* Load infrun state for the fork PTID.  */

static void
fork_load_infrun_state (struct fork_info *fp)
{
  int i;

  linux_nat_switch_fork (fp->ptid);

  if (fp->savedregs)
    get_current_regcache ()->restore (fp->savedregs);

  registers_changed ();
  reinit_frame_cache ();

  inferior_thread ()->suspend.stop_pc
    = regcache_read_pc (get_current_regcache ());
  nullify_last_target_wait_ptid ();

  /* Now restore the file positions of open file descriptors.  */
  if (fp->filepos)
    {
      for (i = 0; i <= fp->maxfd; i++)
	if (fp->filepos[i] != (off_t) -1)
	  call_lseek (i, fp->filepos[i], SEEK_SET);
      /* NOTE: I can get away with using SEEK_SET and SEEK_CUR because
	 this is native-only.  If it ever has to be cross, we'll have
	 to rethink this.  */
    }
}

/* Save infrun state for the fork FP.  */

static void
fork_save_infrun_state (struct fork_info *fp)
{
  char path[PATH_MAX];
  struct dirent *de;
  DIR *d;

  if (fp->savedregs)
    delete fp->savedregs;

  fp->savedregs = new readonly_detached_regcache (*get_current_regcache ());
  fp->pc = regcache_read_pc (get_current_regcache ());

  /* Now save the 'state' (file position) of all open file descriptors.
     Unfortunately fork does not take care of that for us...  */
  snprintf (path, PATH_MAX, "/proc/%ld/fd", (long) fp->ptid.pid ());
  if ((d = opendir (path)) != NULL)
    {
      long tmp;

      fp->maxfd = 0;
      while ((de = readdir (d)) != NULL)
	{
	  /* Count open file descriptors (actually find highest
	     numbered).  */
	  tmp = strtol (&de->d_name[0], NULL, 10);
	  if (fp->maxfd < tmp)
	    fp->maxfd = tmp;
	}
      /* Allocate array of file positions.  */
      fp->filepos = XRESIZEVEC (off_t, fp->filepos, fp->maxfd + 1);

      /* Initialize to -1 (invalid).  */
      for (tmp = 0; tmp <= fp->maxfd; tmp++)
	fp->filepos[tmp] = -1;

      /* Now find actual file positions.  */
      rewinddir (d);
      while ((de = readdir (d)) != NULL)
	if (isdigit (de->d_name[0]))
	  {
	    tmp = strtol (&de->d_name[0], NULL, 10);
	    fp->filepos[tmp] = call_lseek (tmp, 0, SEEK_CUR);
	  }
      closedir (d);
    }
}

/* Kill 'em all, let God sort 'em out...  */

void
linux_fork_killall (void)
{
  /* Walk list and kill every pid.  No need to treat the
     current inferior_ptid as special (we do not return a
     status for it) -- however any process may be a child
     or a parent, so may get a SIGCHLD from a previously
     killed child.  Wait them all out.  */

  for (fork_info &fi : fork_list)
    {
      pid_t pid = fi.ptid.pid ();
      int status;
      pid_t ret;
      do {
	/* Use SIGKILL instead of PTRACE_KILL because the former works even
	   if the thread is running, while the later doesn't.  */
	kill (pid, SIGKILL);
	ret = waitpid (pid, &status, 0);
	/* We might get a SIGCHLD instead of an exit status.  This is
	 aggravated by the first kill above - a child has just
	 died.  MVS comment cut-and-pasted from linux-nat.  */
      } while (ret == pid && WIFSTOPPED (status));
    }

  /* Clear list, prepare to start fresh.  */
  fork_list.clear ();
}

/* The current inferior_ptid has exited, but there are other viable
   forks to debug.  Delete the exiting one and context-switch to the
   first available.  */

void
linux_fork_mourn_inferior (void)
{
  struct fork_info *last;
  int status;

  /* Wait just one more time to collect the inferior's exit status.
     Do not check whether this succeeds though, since we may be
     dealing with a process that we attached to.  Such a process will
     only report its exit status to its original parent.  */
  waitpid (inferior_ptid.pid (), &status, 0);

  /* OK, presumably inferior_ptid is the one who has exited.
     We need to delete that one from the fork_list, and switch
     to the next available fork.  */
  delete_fork (inferior_ptid);

  /* There should still be a fork - if there's only one left,
     delete_fork won't remove it, because we haven't updated
     inferior_ptid yet.  */
  gdb_assert (!fork_list.empty ());

  last = find_last_fork ();
  fork_load_infrun_state (last);
  printf_filtered (_("[Switching to %s]\n"),
		   target_pid_to_str (inferior_ptid).c_str ());

  /* If there's only one fork, switch back to non-fork mode.  */
  if (one_fork_p ())
    delete_fork (inferior_ptid);
}

/* The current inferior_ptid is being detached, but there are other
   viable forks to debug.  Detach and delete it and context-switch to
   the first available.  */

void
linux_fork_detach (int from_tty)
{
  /* OK, inferior_ptid is the one we are detaching from.  We need to
     delete it from the fork_list, and switch to the next available
     fork.  */

  if (ptrace (PTRACE_DETACH, inferior_ptid.pid (), 0, 0))
    error (_("Unable to detach %s"),
	   target_pid_to_str (inferior_ptid).c_str ());

  delete_fork (inferior_ptid);

  /* There should still be a fork - if there's only one left,
     delete_fork won't remove it, because we haven't updated
     inferior_ptid yet.  */
  gdb_assert (!fork_list.empty ());

  fork_load_infrun_state (&fork_list.front ());

  if (from_tty)
    printf_filtered (_("[Switching to %s]\n"),
		     target_pid_to_str (inferior_ptid).c_str ());

  /* If there's only one fork, switch back to non-fork mode.  */
  if (one_fork_p ())
    delete_fork (inferior_ptid);
}

/* Temporarily switch to the infrun state stored on the fork_info
   identified by a given ptid_t.  When this object goes out of scope,
   restore the currently selected infrun state.   */

class scoped_switch_fork_info
{
public:
  /* Switch to the infrun state held on the fork_info identified by
     PPTID.  If PPTID is the current inferior then no switch is done.  */
  explicit scoped_switch_fork_info (ptid_t pptid)
    : m_oldfp (nullptr)
  {
    if (pptid != inferior_ptid)
      {
	struct fork_info *newfp = nullptr;

	/* Switch to pptid.  */
	m_oldfp = find_fork_ptid (inferior_ptid);
	gdb_assert (m_oldfp != nullptr);
	newfp = find_fork_ptid (pptid);
	gdb_assert (newfp != nullptr);
	fork_save_infrun_state (m_oldfp);
	remove_breakpoints ();
	fork_load_infrun_state (newfp);
	insert_breakpoints ();
      }
  }

  /* Restore the previously selected infrun state.  If the constructor
     didn't need to switch states, then nothing is done here either.  */
  ~scoped_switch_fork_info ()
  {
    if (m_oldfp != nullptr)
      {
	/* Switch back to inferior_ptid.  */
	try
	  {
	    remove_breakpoints ();
	    fork_load_infrun_state (m_oldfp);
	    insert_breakpoints ();
	  }
	catch (const gdb_exception &ex)
	  {
	    warning (_("Couldn't restore checkpoint state in %s: %s"),
		     target_pid_to_str (m_oldfp->ptid).c_str (),
		     ex.what ());
	  }
      }
  }

  DISABLE_COPY_AND_ASSIGN (scoped_switch_fork_info);

private:
  /* The fork_info for the previously selected infrun state, or nullptr if
     we were already in the desired state, and nothing needs to be
     restored.  */
  struct fork_info *m_oldfp;
};

static int
inferior_call_waitpid (ptid_t pptid, int pid)
{
  struct objfile *waitpid_objf;
  struct value *waitpid_fn = NULL;
  int ret = -1;

  scoped_switch_fork_info switch_fork_info (pptid);

  /* Get the waitpid_fn.  */
  if (lookup_minimal_symbol ("waitpid", NULL, NULL).minsym != NULL)
    waitpid_fn = find_function_in_inferior ("waitpid", &waitpid_objf);
  if (!waitpid_fn
      && lookup_minimal_symbol ("_waitpid", NULL, NULL).minsym != NULL)
    waitpid_fn = find_function_in_inferior ("_waitpid", &waitpid_objf);
  if (waitpid_fn != nullptr)
    {
      struct gdbarch *gdbarch = get_current_arch ();
      struct value *argv[3], *retv;

      /* Get the argv.  */
      argv[0] = value_from_longest (builtin_type (gdbarch)->builtin_int, pid);
      argv[1] = value_from_pointer (builtin_type (gdbarch)->builtin_data_ptr, 0);
      argv[2] = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);

      retv = call_function_by_hand (waitpid_fn, NULL, argv);

      if (value_as_long (retv) >= 0)
	ret = 0;
    }

  return ret;
}

/* Fork list <-> user interface.  */

static void
delete_checkpoint_command (const char *args, int from_tty)
{
  ptid_t ptid, pptid;
  struct fork_info *fi;

  if (!args || !*args)
    error (_("Requires argument (checkpoint id to delete)"));

  ptid = fork_id_to_ptid (parse_and_eval_long (args));
  if (ptid == minus_one_ptid)
    error (_("No such checkpoint id, %s"), args);

  if (ptid == inferior_ptid)
    error (_("\
Please switch to another checkpoint before deleting the current one"));

  if (ptrace (PTRACE_KILL, ptid.pid (), 0, 0))
    error (_("Unable to kill pid %s"), target_pid_to_str (ptid).c_str ());

  fi = find_fork_ptid (ptid);
  gdb_assert (fi);
  pptid = fi->parent_ptid;

  if (from_tty)
    printf_filtered (_("Killed %s\n"), target_pid_to_str (ptid).c_str ());

  delete_fork (ptid);

  /* If fi->parent_ptid is not a part of lwp but it's a part of checkpoint
     list, waitpid the ptid.
     If fi->parent_ptid is a part of lwp and it is stopped, waitpid the
     ptid.  */
  thread_info *parent = find_thread_ptid (linux_target, pptid);
  if ((parent == NULL && find_fork_ptid (pptid))
      || (parent != NULL && parent->state == THREAD_STOPPED))
    {
      if (inferior_call_waitpid (pptid, ptid.pid ()))
        warning (_("Unable to wait pid %s"),
		 target_pid_to_str (ptid).c_str ());
    }
}

static void
detach_checkpoint_command (const char *args, int from_tty)
{
  ptid_t ptid;

  if (!args || !*args)
    error (_("Requires argument (checkpoint id to detach)"));

  ptid = fork_id_to_ptid (parse_and_eval_long (args));
  if (ptid == minus_one_ptid)
    error (_("No such checkpoint id, %s"), args);

  if (ptid == inferior_ptid)
    error (_("\
Please switch to another checkpoint before detaching the current one"));

  if (ptrace (PTRACE_DETACH, ptid.pid (), 0, 0))
    error (_("Unable to detach %s"), target_pid_to_str (ptid).c_str ());

  if (from_tty)
    printf_filtered (_("Detached %s\n"), target_pid_to_str (ptid).c_str ());

  delete_fork (ptid);
}

/* Print information about currently known checkpoints.  */

static void
info_checkpoints_command (const char *arg, int from_tty)
{
  struct gdbarch *gdbarch = get_current_arch ();
  int requested = -1;
  const fork_info *printed = NULL;

  if (arg && *arg)
    requested = (int) parse_and_eval_long (arg);

  for (const fork_info &fi : fork_list)
    {
      if (requested > 0 && fi.num != requested)
	continue;

      printed = &fi;
      if (fi.ptid == inferior_ptid)
	printf_filtered ("* ");
      else
	printf_filtered ("  ");

      ULONGEST pc = fi.pc;
      printf_filtered ("%d %s", fi.num, target_pid_to_str (fi.ptid).c_str ());
      if (fi.num == 0)
	printf_filtered (_(" (main process)"));
      printf_filtered (_(" at "));
      fputs_filtered (paddress (gdbarch, pc), gdb_stdout);

      symtab_and_line sal = find_pc_line (pc, 0);
      if (sal.symtab)
	printf_filtered (_(", file %s"),
			 symtab_to_filename_for_display (sal.symtab));
      if (sal.line)
	printf_filtered (_(", line %d"), sal.line);
      if (!sal.symtab && !sal.line)
	{
	  struct bound_minimal_symbol msym;

	  msym = lookup_minimal_symbol_by_pc (pc);
	  if (msym.minsym)
	    printf_filtered (", <%s>", msym.minsym->linkage_name ());
	}

      putchar_filtered ('\n');
    }
  if (printed == NULL)
    {
      if (requested > 0)
	printf_filtered (_("No checkpoint number %d.\n"), requested);
      else
	printf_filtered (_("No checkpoints.\n"));
    }
}

/* The PID of the process we're checkpointing.  */
static int checkpointing_pid = 0;

int
linux_fork_checkpointing_p (int pid)
{
  return (checkpointing_pid == pid);
}

/* Return true if the current inferior is multi-threaded.  */

static bool
inf_has_multiple_threads ()
{
  int count = 0;

  /* Return true as soon as we see the second thread of the current
     inferior.  */
  for (thread_info *tp ATTRIBUTE_UNUSED : current_inferior ()->threads ())
    if (++count > 1)
      return true;

  return false;
}

static void
checkpoint_command (const char *args, int from_tty)
{
  struct objfile *fork_objf;
  struct gdbarch *gdbarch;
  struct target_waitstatus last_target_waitstatus;
  ptid_t last_target_ptid;
  struct value *fork_fn = NULL, *ret;
  struct fork_info *fp;
  pid_t retpid;

  if (!target_has_execution) 
    error (_("The program is not being run."));

  /* Ensure that the inferior is not multithreaded.  */
  update_thread_list ();
  if (inf_has_multiple_threads ())
    error (_("checkpoint: can't checkpoint multiple threads."));
  
  /* Make the inferior fork, record its (and gdb's) state.  */

  if (lookup_minimal_symbol ("fork", NULL, NULL).minsym != NULL)
    fork_fn = find_function_in_inferior ("fork", &fork_objf);
  if (!fork_fn)
    if (lookup_minimal_symbol ("_fork", NULL, NULL).minsym != NULL)
      fork_fn = find_function_in_inferior ("fork", &fork_objf);
  if (!fork_fn)
    error (_("checkpoint: can't find fork function in inferior."));

  gdbarch = get_objfile_arch (fork_objf);
  ret = value_from_longest (builtin_type (gdbarch)->builtin_int, 0);

  /* Tell linux-nat.c that we're checkpointing this inferior.  */
  {
    scoped_restore save_pid
      = make_scoped_restore (&checkpointing_pid, inferior_ptid.pid ());

    ret = call_function_by_hand (fork_fn, NULL, {});
  }

  if (!ret)	/* Probably can't happen.  */
    error (_("checkpoint: call_function_by_hand returned null."));

  retpid = value_as_long (ret);
  get_last_target_status (nullptr, &last_target_ptid, &last_target_waitstatus);

  fp = find_fork_pid (retpid);

  if (from_tty)
    {
      int parent_pid;

      printf_filtered (_("checkpoint %d: fork returned pid %ld.\n"),
		       fp != NULL ? fp->num : -1, (long) retpid);
      if (info_verbose)
	{
	  parent_pid = last_target_ptid.lwp ();
	  if (parent_pid == 0)
	    parent_pid = last_target_ptid.pid ();
	  printf_filtered (_("   gdb says parent = %ld.\n"),
			   (long) parent_pid);
	}
    }

  if (!fp)
    error (_("Failed to find new fork"));

  if (one_fork_p ())
    {
      /* Special case -- if this is the first fork in the list (the
	 list was hitherto empty), then add inferior_ptid first, as a
	 special zeroeth fork id.  */
      fork_list.emplace_front (inferior_ptid.pid ());
    }

  fork_save_infrun_state (fp);
  fp->parent_ptid = last_target_ptid;
}

static void
linux_fork_context (struct fork_info *newfp, int from_tty)
{
  /* Now we attempt to switch processes.  */
  struct fork_info *oldfp;

  gdb_assert (newfp != NULL);

  oldfp = find_fork_ptid (inferior_ptid);
  gdb_assert (oldfp != NULL);

  fork_save_infrun_state (oldfp);
  remove_breakpoints ();
  fork_load_infrun_state (newfp);
  insert_breakpoints ();

  printf_filtered (_("Switching to %s\n"),
		   target_pid_to_str (inferior_ptid).c_str ());

  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
}

/* Switch inferior process (checkpoint) context, by checkpoint id.  */
static void
restart_command (const char *args, int from_tty)
{
  struct fork_info *fp;

  if (!args || !*args)
    error (_("Requires argument (checkpoint id to restart)"));

  if ((fp = find_fork_id (parse_and_eval_long (args))) == NULL)
    error (_("Not found: checkpoint id %s"), args);

  linux_fork_context (fp, from_tty);
}

void _initialize_linux_fork ();
void
_initialize_linux_fork ()
{
  /* Checkpoint command: create a fork of the inferior process
     and set it aside for later debugging.  */

  add_com ("checkpoint", class_obscure, checkpoint_command, _("\
Fork a duplicate process (experimental)."));

  /* Restart command: restore the context of a specified checkpoint
     process.  */

  add_com ("restart", class_obscure, restart_command, _("\
Restore program context from a checkpoint.\n\
Usage: restart N\n\
Argument N is checkpoint ID, as displayed by 'info checkpoints'."));

  /* Delete checkpoint command: kill the process and remove it from
     the fork list.  */

  add_cmd ("checkpoint", class_obscure, delete_checkpoint_command, _("\
Delete a checkpoint (experimental)."),
	   &deletelist);

  /* Detach checkpoint command: release the process to run independently,
     and remove it from the fork list.  */

  add_cmd ("checkpoint", class_obscure, detach_checkpoint_command, _("\
Detach from a checkpoint (experimental)."),
	   &detachlist);

  /* Info checkpoints command: list all forks/checkpoints
     currently under gdb's control.  */

  add_info ("checkpoints", info_checkpoints_command,
	    _("IDs of currently known checkpoints."));
}
