/* Everything about catch/throw catchpoints, for GDB.

   Copyright (C) 1986-2025 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 "breakpoint.h"
#include "exceptions.h"
#include "inferior.h"
#include "annotate.h"
#include "valprint.h"
#include "cli/cli-utils.h"
#include "mi/mi-common.h"
#include "probe.h"
#include "cp-abi.h"
#include "gdbsupport/gdb_regex.h"
#include "cp-support.h"
#include "location.h"
#include "cli/cli-decode.h"

/* Each spot where we may place an exception-related catchpoint has
   two names: the SDT probe point and the function name.  This
   structure holds both.  */

struct exception_names
{
  /* The name of the probe point to try, in the form accepted by
     'parse_probes'.  */

  const char *probe;

  /* The name of the corresponding function.  */

  const char *function;
};

/* Names of the probe points and functions on which to break.  This is
   indexed by exception_event_kind.  */
static const struct exception_names exception_functions[] =
{
  { "-probe-stap libstdcxx:throw", "__cxa_throw" },
  { "-probe-stap libstdcxx:rethrow", "__cxa_rethrow" },
  { "-probe-stap libstdcxx:catch", "__cxa_begin_catch" }
};

/* The type of an exception catchpoint.  Unlike most catchpoints, this
   one is implemented with code breakpoints, so it inherits struct
   code_breakpoint, not struct catchpoint.  */

struct exception_catchpoint : public code_breakpoint
{
  exception_catchpoint (struct gdbarch *gdbarch,
			bool temp, const char *cond_string_,
			enum exception_event_kind kind_,
			std::string &&except_rx)
    : code_breakpoint (gdbarch, bp_catchpoint, temp, cond_string_),
      kind (kind_),
      exception_rx (std::move (except_rx)),
      pattern (exception_rx.empty ()
	       ? nullptr
	       : new compiled_regex (exception_rx.c_str (), REG_NOSUB,
				     _("invalid type-matching regexp")))
  {
    pspace = current_program_space;
    re_set (pspace);
  }

  void re_set (program_space *pspace) override;
  enum print_stop_action print_it (const bpstat *bs) const override;
  bool print_one (const bp_location **) const override;
  void print_mention () const override;
  void print_recreate (struct ui_file *fp) const override;
  void print_one_detail (struct ui_out *) const override;
  void check_status (struct bpstat *bs) override;
  struct bp_location *allocate_location () override;

  /* The kind of exception catchpoint.  */

  enum exception_event_kind kind;

  /* If not empty, a string holding the source form of the regular
     expression to match against.  */

  std::string exception_rx;

  /* If non-NULL, a compiled regular expression which is used to
     determine which exceptions to stop on.  */

  std::unique_ptr<compiled_regex> pattern;
};

/* See breakpoint.h.  */

bool
is_exception_catchpoint (breakpoint *bp)
{
  return dynamic_cast<exception_catchpoint *> (bp) != nullptr;
}



/* A helper function that fetches exception probe arguments.  This
   fills in *ARG0 (if non-NULL) and *ARG1 (which must be non-NULL).
   It will throw an exception on any kind of failure.  */

static void
fetch_probe_arguments (struct value **arg0, struct value **arg1)
{
  frame_info_ptr frame = get_selected_frame (_("No frame selected"));
  CORE_ADDR pc = get_frame_pc (frame);
  struct bound_probe pc_probe;
  unsigned n_args;

  pc_probe = find_probe_by_pc (pc);
  if (pc_probe.prob == NULL)
    error (_("did not find exception probe (does libstdcxx have SDT probes?)"));

  if (pc_probe.prob->get_provider () != "libstdcxx"
      || (pc_probe.prob->get_name () != "catch"
	  && pc_probe.prob->get_name () != "throw"
	  && pc_probe.prob->get_name () != "rethrow"))
    error (_("not stopped at a C++ exception catchpoint"));

  n_args = pc_probe.prob->get_argument_count (get_frame_arch (frame));
  if (n_args < 2)
    error (_("C++ exception catchpoint has too few arguments"));

  if (arg0 != NULL)
    *arg0 = pc_probe.prob->evaluate_argument (0, frame);
  *arg1 = pc_probe.prob->evaluate_argument (1, frame);

  if ((arg0 != NULL && *arg0 == NULL) || *arg1 == NULL)
    error (_("error computing probe argument at c++ exception catchpoint"));
}



/* Implement the 'check_status' method.  */

void
exception_catchpoint::check_status (struct bpstat *bs)
{
  std::string type_name;

  this->breakpoint::check_status (bs);
  if (!bs->stop)
    return;

  if (this->pattern == NULL)
    return;

  const char *name = nullptr;
  gdb::unique_xmalloc_ptr<char> canon;
  try
    {
      struct value *typeinfo_arg;

      fetch_probe_arguments (NULL, &typeinfo_arg);
      type_name = cplus_typename_from_type_info (typeinfo_arg);

      canon = cp_canonicalize_string (type_name.c_str ());
      name = (canon != nullptr
	      ? canon.get ()
	      : type_name.c_str ());
    }
  catch (const gdb_exception_error &e)
    {
      exception_print (gdb_stderr, e);
    }

  if (name != nullptr)
    {
      if (this->pattern->exec (name, 0, NULL, 0) != 0)
	bs->stop = false;
    }
}

/* Implement the 're_set' method.  */

void
exception_catchpoint::re_set (program_space *pspace)
{
  std::vector<symtab_and_line> sals;
  struct program_space *filter_pspace = current_program_space;

  /* We first try to use the probe interface.  */
  try
    {
      location_spec_up locspec
	= new_probe_location_spec (exception_functions[kind].probe);
      sals = parse_probes (locspec.get (), filter_pspace, NULL);
    }
  catch (const gdb_exception_error &e)
    {
      /* Using the probe interface failed.  Let's fallback to the normal
	 catchpoint mode.  */
      try
	{
	  location_spec_up locspec
	    = (new_explicit_location_spec_function
	       (exception_functions[kind].function));
	  sals = this->decode_location_spec (locspec.get (), filter_pspace);
	}
      catch (const gdb_exception_error &ex)
	{
	  /* NOT_FOUND_ERROR just means the breakpoint will be
	     pending, so let it through.  */
	  if (ex.error != NOT_FOUND_ERROR)
	    throw;
	}
    }

  update_breakpoint_locations (this, filter_pspace, sals, {});
}

enum print_stop_action
exception_catchpoint::print_it (const bpstat *bs) const
{
  struct ui_out *uiout = current_uiout;
  int bp_temp;

  annotate_catchpoint (number);
  maybe_print_thread_hit_breakpoint (uiout);

  bp_temp = disposition == disp_del;
  uiout->text (bp_temp ? "Temporary catchpoint "
		       : "Catchpoint ");
  print_num_locno (bs, uiout);
  uiout->text ((kind == EX_EVENT_THROW ? " (exception thrown), "
		: (kind == EX_EVENT_CATCH ? " (exception caught), "
		   : " (exception rethrown), ")));
  if (uiout->is_mi_like_p ())
    {
      uiout->field_string ("reason",
			   async_reason_lookup (EXEC_ASYNC_BREAKPOINT_HIT));
      uiout->field_string ("disp", bpdisp_text (disposition));
    }
  return PRINT_SRC_AND_LOC;
}

bool
exception_catchpoint::print_one (const bp_location **last_loc) const
{
  struct value_print_options opts;
  struct ui_out *uiout = current_uiout;

  get_user_print_options (&opts);

  if (opts.addressprint)
    uiout->field_skip ("addr");
  annotate_field (5);

  switch (kind)
    {
    case EX_EVENT_THROW:
      uiout->field_string ("what", "exception throw");
      if (uiout->is_mi_like_p ())
	uiout->field_string ("catch-type", "throw");
      break;

    case EX_EVENT_RETHROW:
      uiout->field_string ("what", "exception rethrow");
      if (uiout->is_mi_like_p ())
	uiout->field_string ("catch-type", "rethrow");
      break;

    case EX_EVENT_CATCH:
      uiout->field_string ("what", "exception catch");
      if (uiout->is_mi_like_p ())
	uiout->field_string ("catch-type", "catch");
      break;
    }

  return true;
}

/* Implement the 'print_one_detail' method.  */

void
exception_catchpoint::print_one_detail (struct ui_out *uiout) const
{
  if (!exception_rx.empty ())
    {
      uiout->text (_("\tmatching: "));
      uiout->field_string ("regexp", exception_rx);
      uiout->text ("\n");
    }
}

void
exception_catchpoint::print_mention () const
{
  struct ui_out *uiout = current_uiout;
  int bp_temp;

  bp_temp = disposition == disp_del;
  uiout->message ("%s %d %s",
		  (bp_temp ? _("Temporary catchpoint ") : _("Catchpoint")),
		  number,
		  (kind == EX_EVENT_THROW
		   ? _("(throw)") : (kind == EX_EVENT_CATCH
				     ? _("(catch)") : _("(rethrow)"))));
}

/* Implement the "print_recreate" method for throw and catch
   catchpoints.  */

void
exception_catchpoint::print_recreate (struct ui_file *fp) const
{
  int bp_temp;

  bp_temp = disposition == disp_del;
  gdb_printf (fp, bp_temp ? "tcatch " : "catch ");
  switch (kind)
    {
    case EX_EVENT_THROW:
      gdb_printf (fp, "throw");
      break;
    case EX_EVENT_CATCH:
      gdb_printf (fp, "catch");
      break;
    case EX_EVENT_RETHROW:
      gdb_printf (fp, "rethrow");
      break;
    }
  print_recreate_thread (fp);
}

/* Implement the "allocate_location" method for throw and catch
   catchpoints.  */

bp_location *
exception_catchpoint::allocate_location ()
{
  return new bp_location (this, bp_loc_software_breakpoint);
}

static void
handle_gnu_v3_exceptions (int tempflag, std::string &&except_rx,
			  const char *cond_string,
			  enum exception_event_kind ex_event, int from_tty)
{
  struct gdbarch *gdbarch = get_current_arch ();

  std::unique_ptr<exception_catchpoint> cp
    (new exception_catchpoint (gdbarch, tempflag, cond_string,
			       ex_event, std::move (except_rx)));

  install_breakpoint (0, std::move (cp), 1);
}

/* Look for an "if" token in *STRING.  The "if" token must be preceded
   by whitespace.
   
   If there is any non-whitespace text between *STRING and the "if"
   token, then it is returned in a newly-xmalloc'd string.  Otherwise,
   this returns NULL.
   
   STRING is updated to point to the "if" token, if it exists, or to
   the end of the string.  */

static std::string
extract_exception_regexp (const char **string)
{
  const char *start;
  const char *last, *last_space;

  start = skip_spaces (*string);

  last = start;
  last_space = start;
  while (*last != '\0')
    {
      const char *if_token = last;

      /* Check for the "if".  */
      if (check_for_argument (&if_token, "if", 2))
	break;

      /* No "if" token here.  Skip to the next word start.  */
      last_space = skip_to_space (last);
      last = skip_spaces (last_space);
    }

  *string = last;
  if (last_space > start)
    return std::string (start, last_space - start);
  return std::string ();
}

/* See breakpoint.h.  */

void
catch_exception_event (enum exception_event_kind ex_event,
		       const char *arg, bool tempflag, int from_tty)
{
  const char *cond_string = NULL;

  if (!arg)
    arg = "";
  arg = skip_spaces (arg);

  std::string except_rx = extract_exception_regexp (&arg);

  cond_string = ep_parse_optional_if_clause (&arg);

  if ((*arg != '\0') && !c_isspace (*arg))
    error (_("Junk at end of arguments."));

  if (ex_event != EX_EVENT_THROW
      && ex_event != EX_EVENT_CATCH
      && ex_event != EX_EVENT_RETHROW)
    error (_("Unsupported or unknown exception event; cannot catch it"));

  handle_gnu_v3_exceptions (tempflag, std::move (except_rx), cond_string,
			    ex_event, from_tty);
}

/* Implementation of "catch catch" command.  */

static void
catch_catch_command (const char *arg, int from_tty,
		     struct cmd_list_element *command)
{
  bool tempflag = command->context () == CATCH_TEMPORARY;

  catch_exception_event (EX_EVENT_CATCH, arg, tempflag, from_tty);
}

/* Implementation of "catch throw" command.  */

static void
catch_throw_command (const char *arg, int from_tty,
		     struct cmd_list_element *command)
{
  bool tempflag = command->context () == CATCH_TEMPORARY;

  catch_exception_event (EX_EVENT_THROW, arg, tempflag, from_tty);
}

/* Implementation of "catch rethrow" command.  */

static void
catch_rethrow_command (const char *arg, int from_tty,
		       struct cmd_list_element *command)
{
  bool tempflag = command->context () == CATCH_TEMPORARY;

  catch_exception_event (EX_EVENT_RETHROW, arg, tempflag, from_tty);
}



/* Implement the 'make_value' method for the $_exception
   internalvar.  */

static struct value *
compute_exception (struct gdbarch *argc, struct internalvar *var, void *ignore)
{
  struct value *arg0, *arg1;
  struct type *obj_type;

  fetch_probe_arguments (&arg0, &arg1);

  /* ARG0 is a pointer to the exception object.  ARG1 is a pointer to
     the std::type_info for the exception.  Now we find the type from
     the type_info and cast the result.  */
  obj_type = cplus_type_from_type_info (arg1);
  return value_ind (value_cast (make_pointer_type (obj_type, NULL), arg0));
}

/* Implementation of the '$_exception' variable.  */

static const struct internalvar_funcs exception_funcs =
{
  compute_exception,
  NULL,
};



INIT_GDB_FILE (break_catch_throw)
{
  /* Add catch and tcatch sub-commands.  */
  add_catch_command ("catch", _("\
Catch an exception, when caught."),
		     catch_catch_command,
		     NULL,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);
  add_catch_command ("throw", _("\
Catch an exception, when thrown."),
		     catch_throw_command,
		     NULL,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);
  add_catch_command ("rethrow", _("\
Catch an exception, when rethrown."),
		     catch_rethrow_command,
		     NULL,
		     CATCH_PERMANENT,
		     CATCH_TEMPORARY);

  create_internalvar_type_lazy ("_exception", &exception_funcs, NULL);
}
