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

   Copyright (C) 2005-2023 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_thread_regcache (inferior_thread ())->restore (fp->savedregs);

  registers_changed ();
  reinit_frame_cache ();

  inferior_thread ()->set_stop_pc
    (regcache_read_pc (get_thread_regcache (inferior_thread ())));
  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_thread_regcache (inferior_thread ()));
  fp->pc = regcache_read_pc (get_thread_regcache (inferior_thread ()));

  /* 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);
  gdb_printf (_("[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)
    gdb_printf (_("[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_quit &ex)
	  {
	    /* We can't throw from a destructor, so re-set the quit flag
	      for later QUIT checking.  */
	    set_quit_flag ();
	  }
	catch (const gdb_exception_forced_quit &ex)
	  {
	    /* Like above, but (eventually) cause GDB to terminate by
	       setting sync_quit_force_run.  */
	    set_force_quit_flag ();
	  }
	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)
    gdb_printf (_("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 = linux_target->find_thread (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)
    gdb_printf (_("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)
	gdb_printf ("* ");
      else
	gdb_printf ("  ");

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

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

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

      gdb_putc ('\n');
    }
  if (printed == NULL)
    {
      if (requested > 0)
	gdb_printf (_("No checkpoint number %d.\n"), requested);
      else
	gdb_printf (_("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;

      gdb_printf (_("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 ();
	  gdb_printf (_("   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 ();

  gdb_printf (_("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."));
}
