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

   Copyright (C) 2005-2024 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 "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 "target/waitstatus.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 ())));
  inferior_thread ()->set_executing (false);
  inferior_thread ()->set_resumed (false);
  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, lwp_info *lp)
{
  gdb_assert (lp != nullptr);
  gdb_assert (lp->ptid == inferior_ptid);

  /* 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.  But before doing the detach, do make sure that the lwp
     hasn't exited or been terminated first.  */

  if (lp->waitstatus.kind () != TARGET_WAITKIND_EXITED
      && lp->waitstatus.kind () != TARGET_WAITKIND_THREAD_EXITED
      && lp->waitstatus.kind () != TARGET_WAITKIND_SIGNALLED)
    {
      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 (pptid == null_ptid)
    {
      int status;
      /* Wait 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 (ptid.pid (), &status, 0);
      return;
    }

  /* 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;
  bool printed = false;

  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 = true;

      bool is_current = fi.ptid == inferior_ptid;
      if (is_current)
	gdb_printf ("* ");
      else
	gdb_printf ("  ");

      gdb_printf ("%d %s", fi.num, target_pid_to_str (fi.ptid).c_str ());
      if (fi.num == 0)
	gdb_printf (_(" (main process)"));

      if (is_current && inferior_thread ()->state == THREAD_RUNNING)
	{
	  gdb_printf (_(" <running>\n"));
	  continue;
	}

      gdb_printf (_(" at "));
      ULONGEST pc
	= (is_current
	   ? regcache_read_pc (get_thread_regcache (inferior_thread ()))
	   : fi.pc);
      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)
    {
      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."));
}
