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

   Copyright (C) 2005-2022 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)
  {
  }

  ~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;

    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 ()->set_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 "));
      puts_filtered (paddress (gdbarch, pc));

      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 = fork_objf->arch ();
  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."));
}
