/* Top level stuff for GDB, the GNU debugger.

   Copyright (C) 1999-2022 Free Software Foundation, Inc.

   Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.

   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 "top.h"
#include "inferior.h"
#include "infrun.h"
#include "target.h"
#include "terminal.h"
#include "gdbsupport/event-loop.h"
#include "event-top.h"
#include "interps.h"
#include <signal.h>
#include "cli/cli-script.h"     /* for reset_command_nest_depth */
#include "main.h"
#include "gdbthread.h"
#include "observable.h"
#include "gdbcmd.h"		/* for dont_repeat() */
#include "annotate.h"
#include "maint.h"
#include "gdbsupport/buffer.h"
#include "ser-event.h"
#include "gdbsupport/gdb_select.h"
#include "gdbsupport/gdb-sigmask.h"
#include "async-event.h"
#include "bt-utils.h"
#include "pager.h"

/* readline include files.  */
#include "readline/readline.h"
#include "readline/history.h"

/* readline defines this.  */
#undef savestring

static std::string top_level_prompt ();

/* Signal handlers.  */
#ifdef SIGQUIT
static void handle_sigquit (int sig);
#endif
#ifdef SIGHUP
static void handle_sighup (int sig);
#endif

/* Functions to be invoked by the event loop in response to
   signals.  */
#if defined (SIGQUIT) || defined (SIGHUP)
static void async_do_nothing (gdb_client_data);
#endif
#ifdef SIGHUP
static void async_disconnect (gdb_client_data);
#endif
#ifdef SIGTSTP
static void async_sigtstp_handler (gdb_client_data);
#endif
static void async_sigterm_handler (gdb_client_data arg);

/* Instead of invoking (and waiting for) readline to read the command
   line and pass it back for processing, we use readline's alternate
   interface, via callback functions, so that the event loop can react
   to other event sources while we wait for input.  */

/* Important variables for the event loop.  */

/* This is used to determine if GDB is using the readline library or
   its own simplified form of readline.  It is used by the asynchronous
   form of the set editing command.
   ezannoni: as of 1999-04-29 I expect that this
   variable will not be used after gdb is changed to use the event
   loop as default engine, and event-top.c is merged into top.c.  */
bool set_editing_cmd_var;

/* This is used to display the notification of the completion of an
   asynchronous execution command.  */
bool exec_done_display_p = false;

/* Used by the stdin event handler to compensate for missed stdin events.
   Setting this to a non-zero value inside an stdin callback makes the callback
   run again.  */
int call_stdin_event_handler_again_p;

/* When true GDB will produce a minimal backtrace when a fatal signal is
   reached (within GDB code).  */
static bool bt_on_fatal_signal = GDB_PRINT_INTERNAL_BACKTRACE_INIT_ON;

/* Implement 'maintenance show backtrace-on-fatal-signal'.  */

static void
show_bt_on_fatal_signal (struct ui_file *file, int from_tty,
			 struct cmd_list_element *cmd, const char *value)
{
  gdb_printf (file, _("Backtrace on a fatal signal is %s.\n"), value);
}

/* Signal handling variables.  */
/* Each of these is a pointer to a function that the event loop will
   invoke if the corresponding signal has received.  The real signal
   handlers mark these functions as ready to be executed and the event
   loop, in a later iteration, calls them.  See the function
   invoke_async_signal_handler.  */
static struct async_signal_handler *sigint_token;
#ifdef SIGHUP
static struct async_signal_handler *sighup_token;
#endif
#ifdef SIGQUIT
static struct async_signal_handler *sigquit_token;
#endif
#ifdef SIGTSTP
static struct async_signal_handler *sigtstp_token;
#endif
static struct async_signal_handler *async_sigterm_token;

/* This hook is called by gdb_rl_callback_read_char_wrapper after each
   character is processed.  */
void (*after_char_processing_hook) (void);


/* Wrapper function for calling into the readline library.  This takes
   care of a couple things:

   - The event loop expects the callback function to have a parameter,
     while readline expects none.

   - Propagation of GDB exceptions/errors thrown from INPUT_HANDLER
     across readline requires special handling.

   On the exceptions issue:

   DWARF-based unwinding cannot cross code built without -fexceptions.
   Any exception that tries to propagate through such code will fail
   and the result is a call to std::terminate.  While some ABIs, such
   as x86-64, require all code to be built with exception tables,
   others don't.

   This is a problem when GDB calls some non-EH-aware C library code,
   that calls into GDB again through a callback, and that GDB callback
   code throws a C++ exception.  Turns out this is exactly what
   happens with GDB's readline callback.

   In such cases, we must catch and save any C++ exception that might
   be thrown from the GDB callback before returning to the
   non-EH-aware code.  When the non-EH-aware function itself returns
   back to GDB, we then rethrow the original C++ exception.

   In the readline case however, the right thing to do is to longjmp
   out of the callback, rather than do a normal return -- there's no
   way for the callback to return to readline an indication that an
   error happened, so a normal return would have rl_callback_read_char
   potentially continue processing further input, redisplay the
   prompt, etc.  Instead of raw setjmp/longjmp however, we use our
   sjlj-based TRY/CATCH mechanism, which knows to handle multiple
   levels of active setjmp/longjmp frames, needed in order to handle
   the readline callback recursing, as happens with e.g., secondary
   prompts / queries, through gdb_readline_wrapper.  This must be
   noexcept in order to avoid problems with mixing sjlj and
   (sjlj-based) C++ exceptions.  */

static struct gdb_exception
gdb_rl_callback_read_char_wrapper_noexcept () noexcept
{
  struct gdb_exception gdb_expt;

  /* C++ exceptions can't normally be thrown across readline (unless
     it is built with -fexceptions, but it won't by default on many
     ABIs).  So we instead wrap the readline call with a sjlj-based
     TRY/CATCH, and rethrow the GDB exception once back in GDB.  */
  TRY_SJLJ
    {
      rl_callback_read_char ();
#if RL_VERSION_MAJOR >= 8
      /* It can happen that readline (while in rl_callback_read_char)
	 received a signal, but didn't handle it yet.  Make sure it's handled
	 now.  If we don't do that we run into two related problems:
	 - we have to wait for another event triggering
	   rl_callback_read_char before the signal is handled
	 - there's no guarantee that the signal will be processed before the
	   event.  */
      while (rl_pending_signal () != 0)
	/* Do this in a while loop, in case rl_check_signals also leaves a
	   pending signal.  I'm not sure if that's possible, but it seems
	   better to handle the scenario than to assert.  */
	rl_check_signals ();
#else
      /* Unfortunately, rl_check_signals is not available.  */
#endif
      if (after_char_processing_hook)
	(*after_char_processing_hook) ();
    }
  CATCH_SJLJ (ex, RETURN_MASK_ALL)
    {
      gdb_expt = std::move (ex);
    }
  END_CATCH_SJLJ

  return gdb_expt;
}

static void
gdb_rl_callback_read_char_wrapper (gdb_client_data client_data)
{
  struct gdb_exception gdb_expt
    = gdb_rl_callback_read_char_wrapper_noexcept ();

  /* Rethrow using the normal EH mechanism.  */
  if (gdb_expt.reason < 0)
    throw_exception (std::move (gdb_expt));
}

/* GDB's readline callback handler.  Calls the current INPUT_HANDLER,
   and propagates GDB exceptions/errors thrown from INPUT_HANDLER back
   across readline.  See gdb_rl_callback_read_char_wrapper.  This must
   be noexcept in order to avoid problems with mixing sjlj and
   (sjlj-based) C++ exceptions.  */

static void
gdb_rl_callback_handler (char *rl) noexcept
{
  /* This is static to avoid undefined behavior when calling longjmp
     -- gdb_exception has a destructor with side effects.  */
  static struct gdb_exception gdb_rl_expt;
  struct ui *ui = current_ui;

  try
    {
      /* Ensure the exception is reset on each call.  */
      gdb_rl_expt = {};
      ui->input_handler (gdb::unique_xmalloc_ptr<char> (rl));
    }
  catch (gdb_exception &ex)
    {
      gdb_rl_expt = std::move (ex);
    }

  /* If we caught a GDB exception, longjmp out of the readline
     callback.  There's no other way for the callback to signal to
     readline that an error happened.  A normal return would have
     readline potentially continue processing further input, redisplay
     the prompt, etc.  (This is what GDB historically did when it was
     a C program.)  Note that since we're long jumping, local variable
     dtors are NOT run automatically.  */
  if (gdb_rl_expt.reason < 0)
    throw_exception_sjlj (gdb_rl_expt);
}

/* Change the function to be invoked every time there is a character
   ready on stdin.  This is used when the user sets the editing off,
   therefore bypassing readline, and letting gdb handle the input
   itself, via gdb_readline_no_editing_callback.  Also it is used in
   the opposite case in which the user sets editing on again, by
   restoring readline handling of the input.

   NOTE: this operates on input_fd, not instream.  If we are reading
   commands from a file, instream will point to the file.  However, we
   always read commands from a file with editing off.  This means that
   the 'set editing on/off' will have effect only on the interactive
   session.  */

void
change_line_handler (int editing)
{
  struct ui *ui = current_ui;

  /* We can only have one instance of readline, so we only allow
     editing on the main UI.  */
  if (ui != main_ui)
    return;

  /* Don't try enabling editing if the interpreter doesn't support it
     (e.g., MI).  */
  if (!interp_supports_command_editing (top_level_interpreter ())
      || !interp_supports_command_editing (command_interp ()))
    return;

  if (editing)
    {
      gdb_assert (ui == main_ui);

      /* Turn on editing by using readline.  */
      ui->call_readline = gdb_rl_callback_read_char_wrapper;
    }
  else
    {
      /* Turn off editing by using gdb_readline_no_editing_callback.  */
      if (ui->command_editing)
	gdb_rl_callback_handler_remove ();
      ui->call_readline = gdb_readline_no_editing_callback;
    }
  ui->command_editing = editing;
}

/* The functions below are wrappers for rl_callback_handler_remove and
   rl_callback_handler_install that keep track of whether the callback
   handler is installed in readline.  This is necessary because after
   handling a target event of a background execution command, we may
   need to reinstall the callback handler if it was removed due to a
   secondary prompt.  See gdb_readline_wrapper_line.  We don't
   unconditionally install the handler for every target event because
   that also clears the line buffer, thus installing it while the user
   is typing would lose input.  */

/* Whether we've registered a callback handler with readline.  */
static bool callback_handler_installed;

/* See event-top.h, and above.  */

void
gdb_rl_callback_handler_remove (void)
{
  gdb_assert (current_ui == main_ui);

  rl_callback_handler_remove ();
  callback_handler_installed = false;
}

/* See event-top.h, and above.  Note this wrapper doesn't have an
   actual callback parameter because we always install
   INPUT_HANDLER.  */

void
gdb_rl_callback_handler_install (const char *prompt)
{
  gdb_assert (current_ui == main_ui);

  /* Calling rl_callback_handler_install resets readline's input
     buffer.  Calling this when we were already processing input
     therefore loses input.  */
  gdb_assert (!callback_handler_installed);

  rl_callback_handler_install (prompt, gdb_rl_callback_handler);
  callback_handler_installed = true;
}

/* See event-top.h, and above.  */

void
gdb_rl_callback_handler_reinstall (void)
{
  gdb_assert (current_ui == main_ui);

  if (!callback_handler_installed)
    {
      /* Passing NULL as prompt argument tells readline to not display
	 a prompt.  */
      gdb_rl_callback_handler_install (NULL);
    }
}

/* Displays the prompt.  If the argument NEW_PROMPT is NULL, the
   prompt that is displayed is the current top level prompt.
   Otherwise, it displays whatever NEW_PROMPT is as a local/secondary
   prompt.

   This is used after each gdb command has completed, and in the
   following cases:

   1. When the user enters a command line which is ended by '\'
   indicating that the command will continue on the next line.  In
   that case the prompt that is displayed is the empty string.

   2. When the user is entering 'commands' for a breakpoint, or
   actions for a tracepoint.  In this case the prompt will be '>'

   3. On prompting for pagination.  */

void
display_gdb_prompt (const char *new_prompt)
{
  std::string actual_gdb_prompt;

  annotate_display_prompt ();

  /* Reset the nesting depth used when trace-commands is set.  */
  reset_command_nest_depth ();

  /* Do not call the python hook on an explicit prompt change as
     passed to this function, as this forms a secondary/local prompt,
     IE, displayed but not set.  */
  if (! new_prompt)
    {
      struct ui *ui = current_ui;

      if (ui->prompt_state == PROMPTED)
	internal_error (__FILE__, __LINE__, _("double prompt"));
      else if (ui->prompt_state == PROMPT_BLOCKED)
	{
	  /* This is to trick readline into not trying to display the
	     prompt.  Even though we display the prompt using this
	     function, readline still tries to do its own display if
	     we don't call rl_callback_handler_install and
	     rl_callback_handler_remove (which readline detects
	     because a global variable is not set).  If readline did
	     that, it could mess up gdb signal handlers for SIGINT.
	     Readline assumes that between calls to rl_set_signals and
	     rl_clear_signals gdb doesn't do anything with the signal
	     handlers.  Well, that's not the case, because when the
	     target executes we change the SIGINT signal handler.  If
	     we allowed readline to display the prompt, the signal
	     handler change would happen exactly between the calls to
	     the above two functions.  Calling
	     rl_callback_handler_remove(), does the job.  */

	  if (current_ui->command_editing)
	    gdb_rl_callback_handler_remove ();
	  return;
	}
      else if (ui->prompt_state == PROMPT_NEEDED)
	{
	  /* Display the top level prompt.  */
	  actual_gdb_prompt = top_level_prompt ();
	  ui->prompt_state = PROMPTED;
	}
    }
  else
    actual_gdb_prompt = new_prompt;

  if (current_ui->command_editing)
    {
      gdb_rl_callback_handler_remove ();
      gdb_rl_callback_handler_install (actual_gdb_prompt.c_str ());
    }
  /* new_prompt at this point can be the top of the stack or the one
     passed in.  It can't be NULL.  */
  else
    {
      /* Don't use a _filtered function here.  It causes the assumed
	 character position to be off, since the newline we read from
	 the user is not accounted for.  */
      printf_unfiltered ("%s", actual_gdb_prompt.c_str ());
      gdb_flush (gdb_stdout);
    }
}

/* Return the top level prompt, as specified by "set prompt", possibly
   overridden by the python gdb.prompt_hook hook, and then composed
   with the prompt prefix and suffix (annotations).  */

static std::string
top_level_prompt (void)
{
  /* Give observers a chance of changing the prompt.  E.g., the python
     `gdb.prompt_hook' is installed as an observer.  */
  gdb::observers::before_prompt.notify (get_prompt ().c_str ());

  const std::string &prompt = get_prompt ();

  if (annotation_level >= 2)
    {
      /* Prefix needs to have new line at end.  */
      const char prefix[] = "\n\032\032pre-prompt\n";

      /* Suffix needs to have a new line at end and \032 \032 at
	 beginning.  */
      const char suffix[] = "\n\032\032prompt\n";

      return std::string (prefix) + prompt.c_str () + suffix;
    }

  return prompt;
}

/* See top.h.  */

struct ui *main_ui;
struct ui *current_ui;
struct ui *ui_list;

/* Get a pointer to the current UI's line buffer.  This is used to
   construct a whole line of input from partial input.  */

static struct buffer *
get_command_line_buffer (void)
{
  return &current_ui->line_buffer;
}

/* When there is an event ready on the stdin file descriptor, instead
   of calling readline directly throught the callback function, or
   instead of calling gdb_readline_no_editing_callback, give gdb a
   chance to detect errors and do something.  */

static void
stdin_event_handler (int error, gdb_client_data client_data)
{
  struct ui *ui = (struct ui *) client_data;

  if (error)
    {
      /* Switch to the main UI, so diagnostics always go there.  */
      current_ui = main_ui;

      ui->unregister_file_handler ();
      if (main_ui == ui)
	{
	  /* If stdin died, we may as well kill gdb.  */
	  gdb_printf (gdb_stderr, _("error detected on stdin\n"));
	  quit_command ((char *) 0, 0);
	}
      else
	{
	  /* Simply delete the UI.  */
	  delete ui;
	}
    }
  else
    {
      /* Switch to the UI whose input descriptor woke up the event
	 loop.  */
      current_ui = ui;

      /* This makes sure a ^C immediately followed by further input is
	 always processed in that order.  E.g,. with input like
	 "^Cprint 1\n", the SIGINT handler runs, marks the async
	 signal handler, and then select/poll may return with stdin
	 ready, instead of -1/EINTR.  The
	 gdb.base/double-prompt-target-event-error.exp test exercises
	 this.  */
      QUIT;

      do
	{
	  call_stdin_event_handler_again_p = 0;
	  ui->call_readline (client_data);
	}
      while (call_stdin_event_handler_again_p != 0);
    }
}

/* See top.h.  */

void
ui::register_file_handler ()
{
  if (input_fd != -1)
    add_file_handler (input_fd, stdin_event_handler, this,
		      string_printf ("ui-%d", num), true);
}

/* See top.h.  */

void
ui::unregister_file_handler ()
{
  if (input_fd != -1)
    delete_file_handler (input_fd);
}

/* Re-enable stdin after the end of an execution command in
   synchronous mode, or after an error from the target, and we aborted
   the exec operation.  */

void
async_enable_stdin (void)
{
  struct ui *ui = current_ui;

  if (ui->prompt_state == PROMPT_BLOCKED)
    {
      target_terminal::ours ();
      ui->register_file_handler ();
      ui->prompt_state = PROMPT_NEEDED;
    }
}

/* Disable reads from stdin (the console) marking the command as
   synchronous.  */

void
async_disable_stdin (void)
{
  struct ui *ui = current_ui;

  ui->prompt_state = PROMPT_BLOCKED;
  ui->unregister_file_handler ();
}


/* Handle a gdb command line.  This function is called when
   handle_line_of_input has concatenated one or more input lines into
   a whole command.  */

void
command_handler (const char *command)
{
  struct ui *ui = current_ui;
  const char *c;

  if (ui->instream == ui->stdin_stream)
    reinitialize_more_filter ();

  scoped_command_stats stat_reporter (true);

  /* Do not execute commented lines.  */
  for (c = command; *c == ' ' || *c == '\t'; c++)
    ;
  if (c[0] != '#')
    {
      execute_command (command, ui->instream == ui->stdin_stream);

      /* Do any commands attached to breakpoint we stopped at.  */
      bpstat_do_actions ();
    }
}

/* Append RL, an input line returned by readline or one of its
   emulations, to CMD_LINE_BUFFER.  Returns the command line if we
   have a whole command line ready to be processed by the command
   interpreter or NULL if the command line isn't complete yet (input
   line ends in a backslash).  */

static char *
command_line_append_input_line (struct buffer *cmd_line_buffer, const char *rl)
{
  char *cmd;
  size_t len;

  len = strlen (rl);

  if (len > 0 && rl[len - 1] == '\\')
    {
      /* Don't copy the backslash and wait for more.  */
      buffer_grow (cmd_line_buffer, rl, len - 1);
      cmd = NULL;
    }
  else
    {
      /* Copy whole line including terminating null, and we're
	 done.  */
      buffer_grow (cmd_line_buffer, rl, len + 1);
      cmd = cmd_line_buffer->buffer;
    }

  return cmd;
}

/* Handle a line of input coming from readline.

   If the read line ends with a continuation character (backslash),
   save the partial input in CMD_LINE_BUFFER (except the backslash),
   and return NULL.  Otherwise, save the partial input and return a
   pointer to CMD_LINE_BUFFER's buffer (null terminated), indicating a
   whole command line is ready to be executed.

   Returns EOF on end of file.

   If REPEAT, handle command repetitions:

     - If the input command line is NOT empty, the command returned is
       saved using save_command_line () so that it can be repeated later.

     - OTOH, if the input command line IS empty, return the saved
       command instead of the empty input line.
*/

char *
handle_line_of_input (struct buffer *cmd_line_buffer,
		      const char *rl, int repeat,
		      const char *annotation_suffix)
{
  struct ui *ui = current_ui;
  int from_tty = ui->instream == ui->stdin_stream;
  char *p1;
  char *cmd;

  if (rl == NULL)
    return (char *) EOF;

  cmd = command_line_append_input_line (cmd_line_buffer, rl);
  if (cmd == NULL)
    return NULL;

  /* We have a complete command line now.  Prepare for the next
     command, but leave ownership of memory to the buffer .  */
  cmd_line_buffer->used_size = 0;

  if (from_tty && annotation_level > 1)
    printf_unfiltered (("\n\032\032post-%s\n"), annotation_suffix);

#define SERVER_COMMAND_PREFIX "server "
  server_command = startswith (cmd, SERVER_COMMAND_PREFIX);
  if (server_command)
    {
      /* Note that we don't call `save_command_line'.  Between this
	 and the check in dont_repeat, this insures that repeating
	 will still do the right thing.  */
      return cmd + strlen (SERVER_COMMAND_PREFIX);
    }

  /* Do history expansion if that is wished.  */
  if (history_expansion_p && from_tty && current_ui->input_interactive_p ())
    {
      char *cmd_expansion;
      int expanded;

      expanded = history_expand (cmd, &cmd_expansion);
      gdb::unique_xmalloc_ptr<char> history_value (cmd_expansion);
      if (expanded)
	{
	  size_t len;

	  /* Print the changes.  */
	  printf_unfiltered ("%s\n", history_value.get ());

	  /* If there was an error, call this function again.  */
	  if (expanded < 0)
	    return cmd;

	  /* history_expand returns an allocated string.  Just replace
	     our buffer with it.  */
	  len = strlen (history_value.get ());
	  xfree (buffer_finish (cmd_line_buffer));
	  cmd_line_buffer->buffer = history_value.get ();
	  cmd_line_buffer->buffer_size = len + 1;
	  cmd = history_value.release ();
	}
    }

  /* If we just got an empty line, and that is supposed to repeat the
     previous command, return the previously saved command.  */
  for (p1 = cmd; *p1 == ' ' || *p1 == '\t'; p1++)
    ;
  if (repeat && *p1 == '\0')
    return get_saved_command_line ();

  /* Add command to history if appropriate.  Note: lines consisting
     solely of comments are also added to the command history.  This
     is useful when you type a command, and then realize you don't
     want to execute it quite yet.  You can comment out the command
     and then later fetch it from the value history and remove the
     '#'.  The kill ring is probably better, but some people are in
     the habit of commenting things out.  */
  if (*cmd != '\0' && from_tty && current_ui->input_interactive_p ())
    gdb_add_history (cmd);

  /* Save into global buffer if appropriate.  */
  if (repeat)
    {
      save_command_line (cmd);
      return get_saved_command_line ();
    }
  else
    return cmd;
}

/* See event-top.h.  */

void
gdb_rl_deprep_term_function (void)
{
#ifdef RL_STATE_EOF
  gdb::optional<scoped_restore_tmpl<int>> restore_eof_found;

  if (RL_ISSTATE (RL_STATE_EOF))
    {
      printf_unfiltered ("quit\n");
      restore_eof_found.emplace (&rl_eof_found, 0);
    }

#endif /* RL_STATE_EOF */

  rl_deprep_terminal ();
}

/* Handle a complete line of input.  This is called by the callback
   mechanism within the readline library.  Deal with incomplete
   commands as well, by saving the partial input in a global
   buffer.

   NOTE: This is the asynchronous version of the command_line_input
   function.  */

void
command_line_handler (gdb::unique_xmalloc_ptr<char> &&rl)
{
  struct buffer *line_buffer = get_command_line_buffer ();
  struct ui *ui = current_ui;
  char *cmd;

  cmd = handle_line_of_input (line_buffer, rl.get (), 1, "prompt");
  if (cmd == (char *) EOF)
    {
      /* stdin closed.  The connection with the terminal is gone.
	 This happens at the end of a testsuite run, after Expect has
	 hung up but GDB is still alive.  In such a case, we just quit
	 gdb killing the inferior program too.  This also happens if the
	 user sends EOF, which is usually bound to ctrl+d.  */

#ifndef RL_STATE_EOF
      /* When readline is using bracketed paste mode, then, when eof is
	 received, readline will emit the control sequence to leave
	 bracketed paste mode.

	 This control sequence ends with \r, which means that the "quit" we
	 are about to print will overwrite the prompt on this line.

	 The solution to this problem is to actually print the "quit"
	 message from gdb_rl_deprep_term_function (see above), however, we
	 can only do that if we can know, in that function, when eof was
	 received.

	 Unfortunately, with older versions of readline, it is not possible
	 in the gdb_rl_deprep_term_function to know if eof was received or
	 not, and, as GDB can be built against the system readline, which
	 could be older than the readline in GDB's repository, then we
	 can't be sure that we can work around this prompt corruption in
	 the gdb_rl_deprep_term_function function.

	 If we get here, RL_STATE_EOF is not defined.  This indicates that
	 we are using an older readline, and couldn't print the quit
	 message in gdb_rl_deprep_term_function.  So, what we do here is
	 check to see if bracketed paste mode is on or not.  If it's on
	 then we print a \n and then the quit, this means the user will
	 see:

	 (gdb)
	 quit

	 Rather than the usual:

	 (gdb) quit

	 Which we will get with a newer readline, but this really is the
	 best we can do with older versions of readline.  */
      const char *value = rl_variable_value ("enable-bracketed-paste");
      if (value != nullptr && strcmp (value, "on") == 0
	  && ((rl_readline_version >> 8) & 0xff) > 0x07)
	printf_unfiltered ("\n");
      printf_unfiltered ("quit\n");
#endif

      execute_command ("quit", 1);
    }
  else if (cmd == NULL)
    {
      /* We don't have a full line yet.  Print an empty prompt.  */
      display_gdb_prompt ("");
    }
  else
    {
      ui->prompt_state = PROMPT_NEEDED;

      command_handler (cmd);

      if (ui->prompt_state != PROMPTED)
	display_gdb_prompt (0);
    }
}

/* Does reading of input from terminal w/o the editing features
   provided by the readline library.  Calls the line input handler
   once we have a whole input line.  */

void
gdb_readline_no_editing_callback (gdb_client_data client_data)
{
  int c;
  char *result;
  struct buffer line_buffer;
  struct ui *ui = current_ui;

  buffer_init (&line_buffer);

  FILE *stream = ui->instream != nullptr ? ui->instream : ui->stdin_stream;
  gdb_assert (stream != nullptr);

  /* We still need the while loop here, even though it would seem
     obvious to invoke gdb_readline_no_editing_callback at every
     character entered.  If not using the readline library, the
     terminal is in cooked mode, which sends the characters all at
     once.  Poll will notice that the input fd has changed state only
     after enter is pressed.  At this point we still need to fetch all
     the chars entered.  */

  while (1)
    {
      /* Read from stdin if we are executing a user defined command.
	 This is the right thing for prompt_for_continue, at least.  */
      c = fgetc (stream);

      if (c == EOF)
	{
	  if (line_buffer.used_size > 0)
	    {
	      /* The last line does not end with a newline.  Return it, and
		 if we are called again fgetc will still return EOF and
		 we'll return NULL then.  */
	      break;
	    }
	  xfree (buffer_finish (&line_buffer));
	  ui->input_handler (NULL);
	  return;
	}

      if (c == '\n')
	{
	  if (line_buffer.used_size > 0
	      && line_buffer.buffer[line_buffer.used_size - 1] == '\r')
	    line_buffer.used_size--;
	  break;
	}

      buffer_grow_char (&line_buffer, c);
    }

  buffer_grow_char (&line_buffer, '\0');
  result = buffer_finish (&line_buffer);
  ui->input_handler (gdb::unique_xmalloc_ptr<char> (result));
}


/* Attempt to unblock signal SIG, return true if the signal was unblocked,
   otherwise, return false.  */

static bool
unblock_signal (int sig)
{
#if HAVE_SIGPROCMASK
  sigset_t sigset;
  sigemptyset (&sigset);
  sigaddset (&sigset, sig);
  gdb_sigmask (SIG_UNBLOCK, &sigset, 0);
  return true;
#endif

  return false;
}

/* Called to handle fatal signals.  SIG is the signal number.  */

static void ATTRIBUTE_NORETURN
handle_fatal_signal (int sig)
{
#ifdef GDB_PRINT_INTERNAL_BACKTRACE
  const auto sig_write = [] (const char *msg) -> void
  {
    gdb_stderr->write_async_safe (msg, strlen (msg));
  };

  if (bt_on_fatal_signal)
    {
      sig_write ("\n\n");
      sig_write (_("Fatal signal: "));
      sig_write (strsignal (sig));
      sig_write ("\n");

      gdb_internal_backtrace ();

      sig_write (_("A fatal error internal to GDB has been detected, "
		   "further\ndebugging is not possible.  GDB will now "
		   "terminate.\n\n"));
      sig_write (_("This is a bug, please report it."));
      if (REPORT_BUGS_TO[0] != '\0')
	{
	  sig_write (_("  For instructions, see:\n"));
	  sig_write (REPORT_BUGS_TO);
	  sig_write (".");
	}
      sig_write ("\n\n");

      gdb_stderr->flush ();
    }
#endif

  /* If possible arrange for SIG to have its default behaviour (which
     should be to terminate the current process), unblock SIG, and reraise
     the signal.  This ensures GDB terminates with the expected signal.  */
  if (signal (sig, SIG_DFL) != SIG_ERR
      && unblock_signal (sig))
    raise (sig);

  /* The above failed, so try to use SIGABRT to terminate GDB.  */
#ifdef SIGABRT
  signal (SIGABRT, SIG_DFL);
#endif
  abort ();		/* ARI: abort */
}

/* The SIGSEGV handler for this thread, or NULL if there is none.  GDB
   always installs a global SIGSEGV handler, and then lets threads
   indicate their interest in handling the signal by setting this
   thread-local variable.

   This is a static variable instead of extern because on various platforms
   (notably Cygwin) extern thread_local variables cause link errors.  So
   instead, we have scoped_segv_handler_restore, which also makes it impossible
   to accidentally forget to restore it to the original value.  */

static thread_local void (*thread_local_segv_handler) (int);

static void handle_sigsegv (int sig);

/* Install the SIGSEGV handler.  */
static void
install_handle_sigsegv ()
{
#if defined (HAVE_SIGACTION)
  struct sigaction sa;
  sa.sa_handler = handle_sigsegv;
  sigemptyset (&sa.sa_mask);
#ifdef HAVE_SIGALTSTACK
  sa.sa_flags = SA_ONSTACK;
#else
  sa.sa_flags = 0;
#endif
  sigaction (SIGSEGV, &sa, nullptr);
#else
  signal (SIGSEGV, handle_sigsegv);
#endif
}

/* Handler for SIGSEGV.  */

static void
handle_sigsegv (int sig)
{
  install_handle_sigsegv ();

  if (thread_local_segv_handler == nullptr)
    handle_fatal_signal (sig);
  thread_local_segv_handler (sig);
}



/* The serial event associated with the QUIT flag.  set_quit_flag sets
   this, and check_quit_flag clears it.  Used by interruptible_select
   to be able to do interruptible I/O with no race with the SIGINT
   handler.  */
static struct serial_event *quit_serial_event;

/* Initialization of signal handlers and tokens.  There are a number of
   different strategies for handling different signals here.

   For SIGINT, SIGTERM, SIGQUIT, SIGHUP, SIGTSTP, there is a function
   handle_sig* for each of these signals.  These functions are the actual
   signal handlers associated to the signals via calls to signal().  The
   only job for these functions is to enqueue the appropriate
   event/procedure with the event loop.  The event loop will take care of
   invoking the queued procedures to perform the usual tasks associated
   with the reception of the signal.

   For SIGSEGV the handle_sig* function does all the work for handling this
   signal.

   For SIGFPE, SIGBUS, and SIGABRT, these signals will all cause GDB to
   terminate immediately.  */
void
gdb_init_signals (void)
{
  initialize_async_signal_handlers ();

  quit_serial_event = make_serial_event ();

  sigint_token =
    create_async_signal_handler (async_request_quit, NULL, "sigint");
  signal (SIGINT, handle_sigint);

  async_sigterm_token
    = create_async_signal_handler (async_sigterm_handler, NULL, "sigterm");
  signal (SIGTERM, handle_sigterm);

#ifdef SIGQUIT
  sigquit_token =
    create_async_signal_handler (async_do_nothing, NULL, "sigquit");
  signal (SIGQUIT, handle_sigquit);
#endif

#ifdef SIGHUP
  if (signal (SIGHUP, handle_sighup) != SIG_IGN)
    sighup_token =
      create_async_signal_handler (async_disconnect, NULL, "sighup");
  else
    sighup_token =
      create_async_signal_handler (async_do_nothing, NULL, "sighup");
#endif

#ifdef SIGTSTP
  sigtstp_token =
    create_async_signal_handler (async_sigtstp_handler, NULL, "sigtstp");
#endif

#ifdef SIGFPE
  signal (SIGFPE, handle_fatal_signal);
#endif

#ifdef SIGBUS
  signal (SIGBUS, handle_fatal_signal);
#endif

#ifdef SIGABRT
  signal (SIGABRT, handle_fatal_signal);
#endif

  install_handle_sigsegv ();
}

/* See defs.h.  */

void
quit_serial_event_set (void)
{
  serial_event_set (quit_serial_event);
}

/* See defs.h.  */

void
quit_serial_event_clear (void)
{
  serial_event_clear (quit_serial_event);
}

/* Return the selectable file descriptor of the serial event
   associated with the quit flag.  */

static int
quit_serial_event_fd (void)
{
  return serial_event_fd (quit_serial_event);
}

/* See defs.h.  */

void
default_quit_handler (void)
{
  if (check_quit_flag ())
    {
      if (target_terminal::is_ours ())
	quit ();
      else
	target_pass_ctrlc ();
    }
}

/* See defs.h.  */
quit_handler_ftype *quit_handler = default_quit_handler;

/* Handle a SIGINT.  */

void
handle_sigint (int sig)
{
  signal (sig, handle_sigint);

  /* We could be running in a loop reading in symfiles or something so
     it may be quite a while before we get back to the event loop.  So
     set quit_flag to 1 here.  Then if QUIT is called before we get to
     the event loop, we will unwind as expected.  */
  set_quit_flag ();

  /* In case nothing calls QUIT before the event loop is reached, the
     event loop handles it.  */
  mark_async_signal_handler (sigint_token);
}

/* See gdb_select.h.  */

int
interruptible_select (int n,
		      fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
		      struct timeval *timeout)
{
  fd_set my_readfds;
  int fd;
  int res;

  if (readfds == NULL)
    {
      readfds = &my_readfds;
      FD_ZERO (&my_readfds);
    }

  fd = quit_serial_event_fd ();
  FD_SET (fd, readfds);
  if (n <= fd)
    n = fd + 1;

  do
    {
      res = gdb_select (n, readfds, writefds, exceptfds, timeout);
    }
  while (res == -1 && errno == EINTR);

  if (res == 1 && FD_ISSET (fd, readfds))
    {
      errno = EINTR;
      return -1;
    }
  return res;
}

/* Handle GDB exit upon receiving SIGTERM if target_can_async_p ().  */

static void
async_sigterm_handler (gdb_client_data arg)
{
  quit_force (NULL, 0);
}

/* See defs.h.  */
volatile int sync_quit_force_run;

/* Quit GDB if SIGTERM is received.
   GDB would quit anyway, but this way it will clean up properly.  */
void
handle_sigterm (int sig)
{
  signal (sig, handle_sigterm);

  sync_quit_force_run = 1;
  set_quit_flag ();

  mark_async_signal_handler (async_sigterm_token);
}

/* Do the quit.  All the checks have been done by the caller.  */
void
async_request_quit (gdb_client_data arg)
{
  /* If the quit_flag has gotten reset back to 0 by the time we get
     back here, that means that an exception was thrown to unwind the
     current command before we got back to the event loop.  So there
     is no reason to call quit again here.  */
  QUIT;
}

#ifdef SIGQUIT
/* Tell the event loop what to do if SIGQUIT is received.
   See event-signal.c.  */
static void
handle_sigquit (int sig)
{
  mark_async_signal_handler (sigquit_token);
  signal (sig, handle_sigquit);
}
#endif

#if defined (SIGQUIT) || defined (SIGHUP)
/* Called by the event loop in response to a SIGQUIT or an
   ignored SIGHUP.  */
static void
async_do_nothing (gdb_client_data arg)
{
  /* Empty function body.  */
}
#endif

#ifdef SIGHUP
/* Tell the event loop what to do if SIGHUP is received.
   See event-signal.c.  */
static void
handle_sighup (int sig)
{
  mark_async_signal_handler (sighup_token);
  signal (sig, handle_sighup);
}

/* Called by the event loop to process a SIGHUP.  */
static void
async_disconnect (gdb_client_data arg)
{

  try
    {
      quit_cover ();
    }

  catch (const gdb_exception &exception)
    {
      gdb_puts ("Could not kill the program being debugged",
		gdb_stderr);
      exception_print (gdb_stderr, exception);
    }

  for (inferior *inf : all_inferiors ())
    {
      switch_to_inferior_no_thread (inf);
      try
	{
	  pop_all_targets ();
	}
      catch (const gdb_exception &exception)
	{
	}
    }

  signal (SIGHUP, SIG_DFL);	/*FIXME: ???????????  */
  raise (SIGHUP);
}
#endif

#ifdef SIGTSTP
void
handle_sigtstp (int sig)
{
  mark_async_signal_handler (sigtstp_token);
  signal (sig, handle_sigtstp);
}

static void
async_sigtstp_handler (gdb_client_data arg)
{
  const std::string &prompt = get_prompt ();

  signal (SIGTSTP, SIG_DFL);
  unblock_signal (SIGTSTP);
  raise (SIGTSTP);
  signal (SIGTSTP, handle_sigtstp);
  printf_unfiltered ("%s", prompt.c_str ());
  gdb_flush (gdb_stdout);

  /* Forget about any previous command -- null line now will do
     nothing.  */
  dont_repeat ();
}
#endif /* SIGTSTP */



/* Set things up for readline to be invoked via the alternate
   interface, i.e. via a callback function
   (gdb_rl_callback_read_char), and hook up instream to the event
   loop.  */

void
gdb_setup_readline (int editing)
{
  struct ui *ui = current_ui;

  /* If the input stream is connected to a terminal, turn on editing.
     However, that is only allowed on the main UI, as we can only have
     one instance of readline.  Also, INSTREAM might be nullptr when
     executing a user-defined command.  */
  if (ui->instream != nullptr && ISATTY (ui->instream)
      && editing && ui == main_ui)
    {
      /* Tell gdb that we will be using the readline library.  This
	 could be overwritten by a command in .gdbinit like 'set
	 editing on' or 'off'.  */
      ui->command_editing = 1;

      /* When a character is detected on instream by select or poll,
	 readline will be invoked via this callback function.  */
      ui->call_readline = gdb_rl_callback_read_char_wrapper;

      /* Tell readline to use the same input stream that gdb uses.  */
      rl_instream = ui->instream;
    }
  else
    {
      ui->command_editing = 0;
      ui->call_readline = gdb_readline_no_editing_callback;
    }

  /* Now create the event source for this UI's input file descriptor.
     Another source is going to be the target program (inferior), but
     that must be registered only when it actually exists (I.e. after
     we say 'run' or after we connect to a remote target.  */
  ui->register_file_handler ();
}

/* Disable command input through the standard CLI channels.  Used in
   the suspend proc for interpreters that use the standard gdb readline
   interface, like the cli & the mi.  */

void
gdb_disable_readline (void)
{
  struct ui *ui = current_ui;

  if (ui->command_editing)
    gdb_rl_callback_handler_remove ();
  ui->unregister_file_handler ();
}

scoped_segv_handler_restore::scoped_segv_handler_restore (segv_handler_t new_handler)
{
  m_old_handler = thread_local_segv_handler;
  thread_local_segv_handler = new_handler;
}

scoped_segv_handler_restore::~scoped_segv_handler_restore()
{
  thread_local_segv_handler = m_old_handler;
}

static const char debug_event_loop_off[] = "off";
static const char debug_event_loop_all_except_ui[] = "all-except-ui";
static const char debug_event_loop_all[] = "all";

static const char *debug_event_loop_enum[] = {
  debug_event_loop_off,
  debug_event_loop_all_except_ui,
  debug_event_loop_all,
  nullptr
};

static const char *debug_event_loop_value = debug_event_loop_off;

static void
set_debug_event_loop_command (const char *args, int from_tty,
			      cmd_list_element *c)
{
  if (debug_event_loop_value == debug_event_loop_off)
    debug_event_loop = debug_event_loop_kind::OFF;
  else if (debug_event_loop_value == debug_event_loop_all_except_ui)
    debug_event_loop = debug_event_loop_kind::ALL_EXCEPT_UI;
  else if (debug_event_loop_value == debug_event_loop_all)
    debug_event_loop = debug_event_loop_kind::ALL;
  else
    gdb_assert_not_reached ("Invalid debug event look kind value.");
}

static void
show_debug_event_loop_command (struct ui_file *file, int from_tty,
			       struct cmd_list_element *cmd, const char *value)
{
  gdb_printf (file, _("Event loop debugging is %s.\n"), value);
}

void _initialize_event_top ();
void
_initialize_event_top ()
{
  add_setshow_enum_cmd ("event-loop", class_maintenance,
			debug_event_loop_enum,
			&debug_event_loop_value,
			_("Set event-loop debugging."),
			_("Show event-loop debugging."),
			_("\
Control whether to show event loop-related debug messages."),
			set_debug_event_loop_command,
			show_debug_event_loop_command,
			&setdebuglist, &showdebuglist);

  add_setshow_boolean_cmd ("backtrace-on-fatal-signal", class_maintenance,
			   &bt_on_fatal_signal, _("\
Set whether to produce a backtrace if GDB receives a fatal signal."), _("\
Show whether GDB will produce a backtrace if it receives a fatal signal."), _("\
Use \"on\" to enable, \"off\" to disable.\n\
If enabled, GDB will produce a minimal backtrace if it encounters a fatal\n\
signal from within GDB itself.  This is a mechanism to help diagnose\n\
crashes within GDB, not a mechanism for debugging inferiors."),
			   gdb_internal_backtrace_set_cmd,
			   show_bt_on_fatal_signal,
			   &maintenance_set_cmdlist,
			   &maintenance_show_cmdlist);
}
