/* General python/gdb code

   Copyright (C) 2008-2026 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 "command.h"
#include "ui-out.h"
#include "cli/cli-script.h"
#include "cli/cli-cmds.h"
#include "progspace.h"
#include "objfiles.h"
#include "value.h"
#include "language.h"
#include "gdbsupport/event-loop.h"
#include "python.h"
#include "extension-priv.h"
#include "cli/cli-utils.h"
#include "location.h"
#include "run-on-main-thread.h"
#include "observable.h"
#include "build-id.h"
#include "cli/cli-style.h"

#if GDB_SELF_TEST
#include "gdbsupport/selftest.h"
#endif

/* Declared constants and enum for python stack printing.  */
static const char python_excp_none[] = "none";
static const char python_excp_full[] = "full";
static const char python_excp_message[] = "message";

/* "set python print-stack" choices.  */
static const char *const python_excp_enums[] =
  {
    python_excp_none,
    python_excp_full,
    python_excp_message,
    NULL
  };

/* The exception printing variable.  'full' if we want to print the
   error message and stack, 'none' if we want to print nothing, and
   'message' if we only want to print the error message.  'message' is
   the default.  */
static const char *gdbpy_should_print_stack = python_excp_message;


#ifdef HAVE_PYTHON

#include "cli/cli-decode.h"
#include "charset.h"
#include "top.h"
#include "ui.h"
#include "python-internal.h"
#include "linespec.h"
#include "source.h"
#include "gdbsupport/version.h"
#include "target.h"
#include "gdbthread.h"
#include "interps.h"
#include "event-top.h"
#include "py-event.h"
#include "py-color.h"

/* True if Python has been successfully initialized, false
   otherwise.  */

int gdb_python_initialized;

extern PyMethodDef python_GdbMethods[];

PyObject *gdb_module;
PyObject *gdb_python_module;

/* Some string constants we may wish to use.  */
PyObject *gdbpy_to_string_cst;
PyObject *gdbpy_children_cst;
PyObject *gdbpy_display_hint_cst;
PyObject *gdbpy_doc_cst;
PyObject *gdbpy_enabled_cst;
PyObject *gdbpy_value_cst;

/* The GdbError exception.  */
PyObject *gdbpy_gdberror_exc;

/* The `gdb.error' base class.  */
PyObject *gdbpy_gdb_error;

/* The `gdb.MemoryError' exception.  */
PyObject *gdbpy_gdb_memory_error;

static script_sourcer_func gdbpy_source_script;
static objfile_script_sourcer_func gdbpy_source_objfile_script;
static objfile_script_executor_func gdbpy_execute_objfile_script;
static void gdbpy_initialize (const struct extension_language_defn *);
static int gdbpy_initialized (const struct extension_language_defn *);
static void finalize_python (const struct extension_language_defn *);
static void gdbpy_eval_from_control_command
  (const struct extension_language_defn *, struct command_line *cmd);
static void gdbpy_start_type_printers (const struct extension_language_defn *,
				       struct ext_lang_type_printers *);
static enum ext_lang_rc gdbpy_apply_type_printers
  (const struct extension_language_defn *,
   const struct ext_lang_type_printers *, struct type *,
   gdb::unique_xmalloc_ptr<char> *);
static void gdbpy_free_type_printers (const struct extension_language_defn *,
				      struct ext_lang_type_printers *);
static void gdbpy_set_quit_flag (const struct extension_language_defn *);
static bool gdbpy_check_quit_flag (const struct extension_language_defn *);
static enum ext_lang_rc gdbpy_before_prompt_hook
  (const struct extension_language_defn *, const char *current_gdb_prompt);
static std::optional<std::string> gdbpy_colorize
  (const std::string &filename, const std::string &contents,
   enum language lang);
static std::optional<std::string> gdbpy_colorize_disasm
(const std::string &content, gdbarch *gdbarch);
static ext_lang_missing_file_result gdbpy_handle_missing_debuginfo
  (const struct extension_language_defn *extlang, struct objfile *objfile);
static ext_lang_missing_file_result gdbpy_find_objfile_from_buildid
  (const struct extension_language_defn *extlang, program_space *pspace,
   const struct bfd_build_id *build_id, const char *missing_filename);

/* The interface between gdb proper and loading of python scripts.  */

static const struct extension_language_script_ops python_extension_script_ops =
{
  gdbpy_source_script,
  gdbpy_source_objfile_script,
  gdbpy_execute_objfile_script,
  gdbpy_auto_load_enabled
};

/* The interface between gdb proper and python extensions.  */

static const struct extension_language_ops python_extension_ops =
{
  gdbpy_initialize,
  gdbpy_initialized,
  finalize_python,

  gdbpy_eval_from_control_command,

  gdbpy_start_type_printers,
  gdbpy_apply_type_printers,
  gdbpy_free_type_printers,

  gdbpy_apply_val_pretty_printer,

  gdbpy_apply_frame_filter,

  gdbpy_load_ptwrite_filter,

  gdbpy_preserve_values,

  gdbpy_breakpoint_has_cond,
  gdbpy_breakpoint_cond_says_stop,

  gdbpy_set_quit_flag,
  gdbpy_check_quit_flag,

  gdbpy_before_prompt_hook,

  gdbpy_get_matching_xmethod_workers,

  gdbpy_colorize,

  gdbpy_colorize_disasm,

  gdbpy_print_insn,

  gdbpy_handle_missing_debuginfo,
  gdbpy_find_objfile_from_buildid
};

#endif /* HAVE_PYTHON */

/* The main struct describing GDB's interface to the Python
   extension language.  */
const struct extension_language_defn extension_language_python =
{
  EXT_LANG_PYTHON,
  "python",
  "Python",

  ".py",
  "-gdb.py",

  python_control,

#ifdef HAVE_PYTHON
  &python_extension_script_ops,
  &python_extension_ops
#else
  NULL,
  NULL
#endif
};

#ifdef HAVE_PYTHON

/* Architecture and language to be used in callbacks from
   the Python interpreter.  */
struct gdbarch *gdbpy_enter::python_gdbarch;

gdbpy_enter::gdbpy_enter  (struct gdbarch *gdbarch,
			   const struct language_defn *language)
: m_gdbarch (python_gdbarch),
  m_language (language == nullptr ? nullptr : current_language)
{
  /* We should not ever enter Python unless initialized.  */
  if (!gdb_python_initialized)
    error (_("Python not initialized"));

  m_previous_active = set_active_ext_lang (&extension_language_python);

  m_state = PyGILState_Ensure ();

  python_gdbarch = gdbarch;
  if (language != nullptr)
    set_language (language->la_language);

  /* Save it and ensure ! PyErr_Occurred () afterwards.  */
  m_error.emplace ();
}

gdbpy_enter::~gdbpy_enter ()
{
  /* Leftover Python error is forbidden by Python Exception Handling.  */
  if (PyErr_Occurred ())
    {
      /* This order is similar to the one calling error afterwards. */
      gdbpy_print_stack ();
      warning (_("internal error: Unhandled Python exception"));
    }

  m_error->restore ();

  python_gdbarch = m_gdbarch;
  if (m_language != nullptr)
    set_language (m_language->la_language);

  restore_active_ext_lang (m_previous_active);
  PyGILState_Release (m_state);
}

struct gdbarch *
gdbpy_enter::get_gdbarch ()
{
  if (python_gdbarch != nullptr)
    return python_gdbarch;
  return get_current_arch ();
}

void
gdbpy_enter::finalize ()
{
  python_gdbarch = current_inferior ()->arch ();
}

/* Set the quit flag.  */

static void
gdbpy_set_quit_flag (const struct extension_language_defn *extlang)
{
  PyErr_SetInterrupt ();
}

/* Return true if the quit flag has been set, false otherwise.  */

static bool
gdbpy_check_quit_flag (const struct extension_language_defn *extlang)
{
  if (!gdb_python_initialized)
    return false;

  gdbpy_gil gil;
  return PyOS_InterruptOccurred ();
}

/* Evaluate a Python command like PyRun_SimpleString, but takes a
   Python start symbol, and does not automatically print the stack on
   errors.  FILENAME is used to set the file name in error messages;
   NULL means that this is evaluating a string, not the contents of a
   file.  */

int
eval_python_command (const char *command, int start_symbol,
		     const char *filename)
{
  PyObject *m, *d;

  m = PyImport_AddModule ("__main__");
  if (m == NULL)
    return -1;

  d = PyModule_GetDict (m);
  if (d == NULL)
    return -1;

  bool file_set = false;
  if (filename != nullptr)
    {
      gdbpy_ref<> file = host_string_to_python_string ("__file__");
      if (file == nullptr)
	return -1;

      /* PyDict_GetItemWithError returns a borrowed reference.  */
      PyObject *found = PyDict_GetItemWithError (d, file.get ());
      if (found == nullptr)
	{
	  if (PyErr_Occurred ())
	    return -1;

	  gdbpy_ref<> filename_obj = host_string_to_python_string (filename);
	  if (filename_obj == nullptr)
	    return -1;

	  if (PyDict_SetItem (d, file.get (), filename_obj.get ()) < 0)
	    return -1;
	  if (PyDict_SetItemString (d, "__cached__", Py_None) < 0)
	    return -1;

	  file_set = true;
	}
    }

  /* Use this API because it is available with the Python limited API.  */
  gdbpy_ref<> code (Py_CompileString (command,
				      filename == nullptr
				      ? "<string>"
				      : filename,
				      start_symbol));

  int result = -1;
  if (code != nullptr)
    {
      gdbpy_ref<> eval_result (PyEval_EvalCode (code.get (), d, d));
      if (eval_result != nullptr)
	result = 0;
    }

  if (file_set)
    {
      /* If there's already an exception occurring, preserve it and
	 restore it before returning from this function.  */
      std::optional<gdbpy_err_fetch> save_error;
      if (result < 0)
	save_error.emplace ();

      /* CPython also just ignores errors here.  These should be
	 expected to be exceedingly rare anyway.  */
      if (PyDict_DelItemString (d, "__file__") < 0)
	PyErr_Clear ();
      if (PyDict_DelItemString (d, "__cached__") < 0)
	PyErr_Clear ();

      if (save_error.has_value ())
	save_error->restore ();
    }

  return result;
}

/* Implementation of the gdb "python-interactive" command.  */

static void
python_interactive_command (const char *arg, int from_tty)
{
  struct ui *ui = current_ui;
  int err;

  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);

  arg = skip_spaces (arg);

  gdbpy_enter enter_py;

  if (arg && *arg)
    {
      std::string script = std::string (arg) + "\n";
      /* Py_single_input causes the result to be displayed.  */
      err = eval_python_command (script.c_str (), Py_single_input);
    }
  else
    {
      err = PyRun_InteractiveLoop (ui->instream, "<stdin>");
      dont_repeat ();
    }

  if (err)
    gdbpy_handle_exception ();
}

/* Like PyRun_SimpleFile, but if there is an exception, it is not
   automatically displayed.  FILE is the Python script to run named
   FILENAME.

   On Windows hosts few users would build Python themselves (this is no
   trivial task on this platform), and thus use binaries built by
   someone else instead.  There may happen situation where the Python
   library and GDB are using two different versions of the C runtime
   library.  Python, being built with VC, would use one version of the
   msvcr DLL (Eg. msvcr100.dll), while MinGW uses msvcrt.dll.
   A FILE * from one runtime does not necessarily operate correctly in
   the other runtime.  */

static int
python_run_simple_file (FILE *file, const char *filename)
{
  std::string contents = read_remainder_of_file (file);
  return eval_python_command (contents.c_str (), Py_file_input, filename);
}

/* Given a command_line, return a command string suitable for passing
   to Python.  Lines in the string are separated by newlines.  */

static std::string
compute_python_string (struct command_line *l)
{
  struct command_line *iter;
  std::string script;

  for (iter = l; iter; iter = iter->next)
    {
      script += iter->line;
      script += '\n';
    }
  return script;
}

/* Take a command line structure representing a 'python' command, and
   evaluate its body using the Python interpreter.  */

static void
gdbpy_eval_from_control_command (const struct extension_language_defn *extlang,
				 struct command_line *cmd)
{
  if (cmd->body_list_1 != nullptr)
    error (_("Invalid \"python\" block structure."));

  gdbpy_enter enter_py;

  std::string script = compute_python_string (cmd->body_list_0.get ());
  int ret = eval_python_command (script.c_str (), Py_file_input);
  if (ret != 0)
    gdbpy_handle_exception ();
}

/* Implementation of the gdb "python" command.  */

static void
python_command (const char *arg, int from_tty)
{
  gdbpy_enter enter_py;

  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);

  arg = skip_spaces (arg);
  if (arg && *arg)
    {
      int ret = eval_python_command (arg, Py_file_input);
      if (ret != 0)
	gdbpy_handle_exception ();
    }
  else
    {
      counted_command_line l = get_command_line (python_control, "");

      execute_control_command_untraced (l.get ());
    }
}



/* Transform a gdb parameters's value into a Python value.  May return
   NULL (and set a Python exception) on error.  Helper function for
   get_parameter.  */
PyObject *
gdbpy_parameter_value (const setting &var)
{
  switch (var.type ())
    {
    case var_string:
    case var_string_noescape:
    case var_optional_filename:
    case var_filename:
    case var_enum:
      {
	const char *str;
	if (var.type () == var_enum)
	  str = var.get<const char *> ();
	else
	  str = var.get<std::string> ().c_str ();

	return host_string_to_python_string (str).release ();
      }

    case var_color:
      {
	const ui_file_style::color &color = var.get<ui_file_style::color> ();
	return create_color_object (color).release ();
      }

    case var_boolean:
      {
	if (var.get<bool> ())
	  Py_RETURN_TRUE;
	else
	  Py_RETURN_FALSE;
      }

    case var_auto_boolean:
      {
	enum auto_boolean ab = var.get<enum auto_boolean> ();

	if (ab == AUTO_BOOLEAN_TRUE)
	  Py_RETURN_TRUE;
	else if (ab == AUTO_BOOLEAN_FALSE)
	  Py_RETURN_FALSE;
	else
	  Py_RETURN_NONE;
      }

    case var_uinteger:
    case var_integer:
    case var_pinteger:
      {
	LONGEST value
	  = (var.type () == var_uinteger
	     ? static_cast<LONGEST> (var.get<unsigned int> ())
	     : static_cast<LONGEST> (var.get<int> ()));

	if (var.extra_literals () != nullptr)
	  for (const literal_def *l = var.extra_literals ();
	       l->literal != nullptr;
	       l++)
	    if (value == l->use)
	      {
		if (strcmp (l->literal, "unlimited") == 0)
		  {
		    /* Compatibility hack for API brokenness.  */
		    if (var.type () == var_pinteger
			&& l->val.has_value ()
			&& *l->val == -1)
		      value = -1;
		    else
		      Py_RETURN_NONE;
		  }
		else if (l->val.has_value ())
		  value = *l->val;
		else
		  return host_string_to_python_string (l->literal).release ();
	      }

	if (var.type () == var_uinteger)
	  return
	    gdb_py_object_from_ulongest
	      (static_cast<unsigned int> (value)).release ();
	else
	  return
	    gdb_py_object_from_longest
	      (static_cast<int> (value)).release ();
      }
    }

  return PyErr_Format (PyExc_RuntimeError,
		       _("Programmer error: unhandled type."));
}

/* A Python function which returns a gdb parameter's value as a Python
   value.  */

static PyObject *
gdbpy_parameter (PyObject *self, PyObject *args)
{
  struct cmd_list_element *alias, *prefix, *cmd;
  const char *arg;
  int found = -1;

  if (! PyArg_ParseTuple (args, "s", &arg))
    return NULL;

  std::string newarg = std::string ("show ") + arg;

  try
    {
      found = lookup_cmd_composition (newarg.c_str (), &alias, &prefix, &cmd);
    }
  catch (const gdb_exception &ex)
    {
      return gdbpy_handle_gdb_exception (nullptr, ex);
    }

  if (cmd == CMD_LIST_AMBIGUOUS)
    return PyErr_Format (PyExc_RuntimeError,
			 _("Parameter `%s' is ambiguous."), arg);
  else if (!found)
    return PyErr_Format (PyExc_RuntimeError,
			 _("Could not find parameter `%s'."), arg);

  if (!cmd->var.has_value ())
    return PyErr_Format (PyExc_RuntimeError,
			 _("`%s' is not a parameter."), arg);

  return gdbpy_parameter_value (*cmd->var);
}

/* Wrapper for target_charset.  */

static PyObject *
gdbpy_target_charset (PyObject *self, PyObject *args)
{
  const char *cset = target_charset (gdbpy_enter::get_gdbarch ());

  return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL);
}

/* Wrapper for target_wide_charset.  */

static PyObject *
gdbpy_target_wide_charset (PyObject *self, PyObject *args)
{
  const char *cset = target_wide_charset (gdbpy_enter::get_gdbarch ());

  return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL);
}

/* Implement gdb.host_charset().  */

static PyObject *
gdbpy_host_charset (PyObject *self, PyObject *args)
{
  const char *cset = host_charset ();

  return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL);
}

/* A Python function which evaluates a string using the gdb CLI.  */

static PyObject *
execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
{
  const char *arg;
  PyObject *from_tty_obj = nullptr;
  PyObject *to_string_obj = nullptr;
  PyObject *styling = nullptr;
  static const char *keywords[]
    = { "command", "from_tty", "to_string", "styling", nullptr };

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!O!", keywords, &arg,
					&PyBool_Type, &from_tty_obj,
					&PyBool_Type, &to_string_obj,
					&PyBool_Type, &styling))
    return nullptr;

  bool from_tty = false;
  if (from_tty_obj != nullptr)
    {
      int cmp = PyObject_IsTrue (from_tty_obj);
      if (cmp < 0)
	return nullptr;
      from_tty = (cmp != 0);
    }

  bool to_string = false;
  if (to_string_obj != nullptr)
    {
      int cmp = PyObject_IsTrue (to_string_obj);
      if (cmp < 0)
	return nullptr;
      to_string = (cmp != 0);
    }

  bool styling_p = !to_string;
  if (styling != nullptr)
    {
      int cmp = PyObject_IsTrue (styling);
      if (cmp < 0)
	return nullptr;
      styling_p = (cmp != 0);
    }

  std::string to_string_res;

  scoped_restore preventer = prevent_dont_repeat ();

  /* If the executed command raises an exception, we may have to
     enable stdin and recover the GDB prompt.

     Stdin should not be re-enabled if it is already blocked because,
     for example, we are running a command in the context of a
     synchronous execution command ("run", "continue", etc.).  Like
     this:

     User runs "continue"
     --> command blocks the prompt
     --> Python API is invoked, e.g.  via events
     --> gdb.execute(C) invoked inside Python
     --> command C raises an exception

     In this case case, GDB would go back to the top "continue" command
     and move on with its normal course of execution.  That is, it
     would enable stdin in the way it normally does.

     Similarly, if the command we are about to execute enables the
     stdin while we are still in the context of a synchronous
     execution command, we would be displaying the prompt too early,
     before the surrounding command completes.

     For these reasons, we keep the prompt blocked, if it already is.  */
  bool prompt_was_blocked = (current_ui->prompt_state == PROMPT_BLOCKED);
  scoped_restore save_prompt_state
    = make_scoped_restore (&current_ui->keep_prompt_blocked,
			   prompt_was_blocked);

  try
    {
      gdbpy_allow_threads allow_threads;

      struct interp *interp;

      std::string arg_copy = arg;
      bool first = true;
      char *save_ptr = nullptr;
      auto reader
	= [&] (std::string &buffer)
	  {
	    const char *result = strtok_r (first ? &arg_copy[0] : nullptr,
					   "\n", &save_ptr);
	    first = false;
	    return result;
	  };

      counted_command_line lines = read_command_lines_1 (reader, 1, nullptr);

      {
	scoped_restore save_async = make_scoped_restore (&current_ui->async,
							 0);

	scoped_restore save_uiout = make_scoped_restore (&current_uiout);

	/* If the Python 'styling' argument was False then temporarily
	   disable styling.  Otherwise, don't do anything, styling could
	   already be disabled for some other reason, we shouldn't override
	   that and force styling on.  */
	std::optional<scoped_disable_styling> disable_styling;
	if (!styling_p)
	  disable_styling.emplace ();

	/* Use the console interpreter uiout to have the same print format
	   for console or MI.  */
	interp = interp_lookup (current_ui, "console");
	current_uiout = interp->interp_ui_out ();

	if (to_string)
	  {
	    /* Pass 'true' here to always request styling, however, if
	       the scoped_disable_styling disabled styling, or the user
	       has globally disabled styling, then the output will not be
	       styled.  */
	    to_string_res
	      = execute_control_commands_to_string (lines.get (), from_tty,
						    true);
	  }
	else
	  execute_control_commands (lines.get (), from_tty);
      }

      /* Do any commands attached to breakpoint we stopped at.  */
      bpstat_do_actions ();
    }
  catch (const gdb_exception &except)
    {
      /* If an exception occurred then we won't hit normal_stop (), or have
	 an exception reach the top level of the event loop, which are the
	 two usual places in which stdin would be re-enabled. So, before we
	 convert the exception and continue back in Python, we should
	 re-enable stdin here.  */
      async_enable_stdin ();
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  if (to_string)
    return PyUnicode_Decode (to_string_res.c_str (), to_string_res.size (),
			     host_charset (), nullptr);
  Py_RETURN_NONE;
}

/* Implementation of Python rbreak command.  Take a REGEX and
   optionally a MINSYMS, THROTTLE and SYMTABS keyword and return a
   Python list that contains newly set breakpoints that match that
   criteria.  REGEX refers to a GDB format standard regex pattern of
   symbols names to search; MINSYMS is an optional boolean (default
   False) that indicates if the function should search GDB's minimal
   symbols; THROTTLE is an optional integer (default unlimited) that
   indicates the maximum amount of breakpoints allowable before the
   function exits (note, if the throttle bound is passed, no
   breakpoints will be set and a runtime error returned); SYMTABS is
   an optional Python iterable that contains a set of gdb.Symtabs to
   constrain the search within.  */

static PyObject *
gdbpy_rbreak (PyObject *self, PyObject *args, PyObject *kw)
{
  char *regex = NULL;
  std::vector<symbol_search> symbols;
  unsigned long count = 0;
  PyObject *symtab_list = NULL;
  PyObject *minsyms_p_obj = NULL;
  int minsyms_p = 0;
  unsigned int throttle = 0;
  static const char *keywords[] = {"regex","minsyms", "throttle",
				   "symtabs", NULL};

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!IO", keywords,
					&regex, &PyBool_Type,
					&minsyms_p_obj, &throttle,
					&symtab_list))
    return NULL;

  /* Parse minsyms keyword.  */
  if (minsyms_p_obj != NULL)
    {
      int cmp = PyObject_IsTrue (minsyms_p_obj);
      if (cmp < 0)
	return NULL;
      minsyms_p = cmp;
    }

  global_symbol_searcher spec (SEARCH_FUNCTION_DOMAIN, regex);

  /* The "symtabs" keyword is any Python iterable object that returns
     a gdb.Symtab on each iteration.  If specified, iterate through
     the provided gdb.Symtabs and extract their full path.  As
     python_string_to_target_string returns a
     gdb::unique_xmalloc_ptr<char> and a vector containing these types
     cannot be coerced to a const char **p[] via the vector.data call,
     release the value from the unique_xmalloc_ptr and place it in a
     simple type symtab_list_type (which holds the vector and a
     destructor that frees the contents of the allocated strings.  */
  if (symtab_list != NULL)
    {
      gdbpy_ref<> iter (PyObject_GetIter (symtab_list));

      if (iter == NULL)
	return NULL;

      while (true)
	{
	  gdbpy_ref<> next (PyIter_Next (iter.get ()));

	  if (next == NULL)
	    {
	      if (PyErr_Occurred ())
		return NULL;
	      break;
	    }

	  gdbpy_ref<> obj_name (PyObject_GetAttrString (next.get (),
							"filename"));

	  if (obj_name == NULL)
	    return NULL;

	  /* Is the object file still valid?  */
	  if (obj_name == Py_None)
	    continue;

	  gdb::unique_xmalloc_ptr<char> filename =
	    python_string_to_target_string (obj_name.get ());

	  if (filename == NULL)
	    return NULL;

	  spec.add_filename (std::move (filename));
	}
    }

  /* The search spec.  */
  symbols = spec.search ();

  /* Count the number of symbols (both symbols and optionally minimal
     symbols) so we can correctly check the throttle limit.  */
  for (const symbol_search &p : symbols)
    {
      /* Minimal symbols included?  */
      if (minsyms_p)
	{
	  if (p.msymbol.minsym != NULL)
	    count++;
	}

      if (p.symbol != NULL)
	count++;
    }

  /* Check throttle bounds and exit if in excess.  */
  if (throttle != 0 && count > throttle)
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Number of breakpoints exceeds throttled maximum."));
      return NULL;
    }

  gdbpy_ref<> return_list (PyList_New (0));

  if (return_list == NULL)
    return NULL;

  /* Construct full path names for symbols and call the Python
     breakpoint constructor on the resulting names.  Be tolerant of
     individual breakpoint failures.  */
  for (const symbol_search &p : symbols)
    {
      std::string symbol_name;

      /* Skipping minimal symbols?  */
      if (minsyms_p == 0)
	if (p.msymbol.minsym != NULL)
	  continue;

      if (p.msymbol.minsym == NULL)
	{
	  struct symtab *symtab = p.symbol->symtab ();
	  const char *fullname = symtab_to_fullname (symtab);

	  symbol_name = fullname;
	  symbol_name  += ":";
	  symbol_name  += p.symbol->linkage_name ();
	}
      else
	symbol_name = p.msymbol.minsym->linkage_name ();

      gdbpy_ref<> argList (Py_BuildValue("(s)", symbol_name.c_str ()));
      gdbpy_ref<> obj (PyObject_CallObject ((PyObject *)
					    &breakpoint_object_type,
					    argList.get ()));

      /* Tolerate individual breakpoint failures.  */
      if (obj == NULL)
	gdbpy_print_stack ();
      else
	{
	  if (PyList_Append (return_list.get (), obj.get ()) == -1)
	    return NULL;
	}
    }
  return return_list.release ();
}

/* A Python function which is a wrapper for decode_line_1.  */

static PyObject *
gdbpy_decode_line (PyObject *self, PyObject *args)
{
  const char *arg = NULL;
  gdbpy_ref<> result;
  gdbpy_ref<> unparsed;
  location_spec_up locspec;

  if (! PyArg_ParseTuple (args, "|s", &arg))
    return NULL;

  /* Treat a string consisting of just whitespace the same as
     NULL.  */
  if (arg != NULL)
    {
      arg = skip_spaces (arg);
      if (*arg == '\0')
	arg = NULL;
    }

  if (arg != NULL)
    locspec = string_to_location_spec_basic (&arg, current_language,
					     symbol_name_match_type::WILD);

  std::vector<symtab_and_line> decoded_sals;
  symtab_and_line def_sal;
  gdb::array_view<symtab_and_line> sals;
  try
    {
      if (locspec != NULL)
	{
	  decoded_sals = decode_line_1 (locspec.get (), 0, NULL, NULL, 0);
	  sals = decoded_sals;
	}
      else
	{
	  set_default_source_symtab_and_line ();
	  def_sal = get_current_source_symtab_and_line (current_program_space);
	  sals = def_sal;
	}
    }
  catch (const gdb_exception &ex)
    {
      /* We know this will always throw.  */
      return gdbpy_handle_gdb_exception (nullptr, ex);
    }

  if (!sals.empty ())
    {
      result.reset (PyTuple_New (sals.size ()));
      if (result == NULL)
	return NULL;
      for (size_t i = 0; i < sals.size (); ++i)
	{
	  gdbpy_ref<> obj = symtab_and_line_to_sal_object (sals[i]);
	  if (obj == nullptr)
	    return nullptr;

	  PyTuple_SetItem (result.get (), i, obj.release ());
	}
    }
  else
    result = gdbpy_ref<>::new_reference (Py_None);

  gdbpy_ref<> return_result (PyTuple_New (2));
  if (return_result == NULL)
    return NULL;

  if (arg != NULL && strlen (arg) > 0)
    {
      unparsed.reset (PyUnicode_FromString (arg));
      if (unparsed == NULL)
	return NULL;
    }
  else
    unparsed = gdbpy_ref<>::new_reference (Py_None);

  if (PyTuple_SetItem (return_result.get (), 0, unparsed.release ()) < 0
      || PyTuple_SetItem (return_result.get (), 1, result.release ()) < 0)
    return nullptr;

  return return_result.release ();
}

/* Parse a string and evaluate it as an expression.  */
static PyObject *
gdbpy_parse_and_eval (PyObject *self, PyObject *args, PyObject *kw)
{
  static const char *keywords[] = { "expression", "global_context", nullptr };

  const char *expr_str;
  PyObject *global_context_obj = nullptr;

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!", keywords,
					&expr_str,
					&PyBool_Type, &global_context_obj))
    return nullptr;

  parser_flags flags = 0;
  if (global_context_obj != NULL)
    {
      int cmp = PyObject_IsTrue (global_context_obj);
      if (cmp < 0)
	return nullptr;
      if (cmp)
	flags |= PARSER_LEAVE_BLOCK_ALONE;
    }

  gdbpy_ref<> result;
  try
    {
      scoped_value_mark free_values;
      struct value *val;
      {
	/* Allow other Python threads to run while we're evaluating
	   the expression.  This is important because the expression
	   could involve inferior calls or otherwise be a lengthy
	   calculation.  We take care here to re-acquire the GIL here
	   before continuing with Python work.  */
	gdbpy_allow_threads allow_threads;
	val = parse_and_eval (expr_str, flags);
      }
      result = value_to_value_object (val);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result.release ();
}

/* Implementation of gdb.invalidate_cached_frames.  */

static PyObject *
gdbpy_invalidate_cached_frames (PyObject *self, PyObject *args)
{
  reinit_frame_cache ();
  Py_RETURN_NONE;
}

/* Read a file as Python code.
   This is the extension_language_script_ops.script_sourcer "method".
   FILE is the file to load.  FILENAME is name of the file FILE.
   This does not throw any errors.  If an exception occurs python will print
   the traceback and clear the error indicator.  */

static void
gdbpy_source_script (const struct extension_language_defn *extlang,
		     FILE *file, const char *filename)
{
  gdbpy_enter enter_py;
  int result = python_run_simple_file (file, filename);
  if (result != 0)
    gdbpy_handle_exception ();
}



/* Posting and handling events.  */

/* A single event.  */
struct gdbpy_event
{
  gdbpy_event (gdbpy_ref<> &&func)
    : m_func (func.release ())
  {
  }

  gdbpy_event (gdbpy_event &&other) noexcept
    : m_func (other.m_func)
  {
    other.m_func = nullptr;
  }

  gdbpy_event (const gdbpy_event &other)
    : m_func (other.m_func)
  {
    gdbpy_gil gil;
    Py_XINCREF (m_func);
  }

  ~gdbpy_event ()
  {
    gdbpy_gil gil;
    Py_XDECREF (m_func);
  }

  gdbpy_event &operator= (const gdbpy_event &other) = delete;

  void operator() ()
  {
    gdbpy_enter enter_py;

    gdbpy_ref<> call_result (PyObject_CallObject (m_func, NULL));
    if (call_result == NULL)
      gdbpy_print_stack ();
  }

private:

  /* The Python event.  This is just a callable object.  Note that
     this is not a gdbpy_ref<>, because we have to take particular
     care to only destroy the reference when holding the GIL. */
  PyObject *m_func;
};

/* Submit an event to the gdb thread.  */
static PyObject *
gdbpy_post_event (PyObject *self, PyObject *args)
{
  PyObject *func;

  if (!PyArg_ParseTuple (args, "O", &func))
    return NULL;

  if (!PyCallable_Check (func))
    {
      PyErr_SetString (PyExc_RuntimeError,
		       _("Posted event is not callable"));
      return NULL;
    }

  gdbpy_ref<> func_ref = gdbpy_ref<>::new_reference (func);
  gdbpy_event event (std::move (func_ref));
  run_on_main_thread (event);

  Py_RETURN_NONE;
}

/* Interrupt the current operation on the main thread.  */
static PyObject *
gdbpy_interrupt (PyObject *self, PyObject *args)
{
#ifdef __MINGW32__
  {
    gdbpy_allow_threads temporarily_exit_python;
    scoped_disable_cooperative_sigint_handling no_python_sigint;

    set_quit_flag ();
  }
#else
  {
    /* For targets with support kill() just send SIGINT.  This will be
       handled as if the user hit Ctrl+C.  This isn't exactly the same as
       the above, which directly sets the quit flag.  Consider, for
       example, every place that install_sigint_handler is called.  */
    kill (getpid (), SIGINT);
  }
#endif

  Py_RETURN_NONE;
}



/* This is the extension_language_ops.before_prompt "method".  */

static enum ext_lang_rc
gdbpy_before_prompt_hook (const struct extension_language_defn *extlang,
			  const char *current_gdb_prompt)
{
  if (!gdb_python_initialized)
    return EXT_LANG_RC_NOP;

  gdbpy_enter enter_py;

  if (!evregpy_no_listeners_p (gdb_py_events.before_prompt)
      && evpy_emit_event (NULL, gdb_py_events.before_prompt) < 0)
    return EXT_LANG_RC_ERROR;

  if (gdb_python_module
      && PyObject_HasAttrString (gdb_python_module, "prompt_hook"))
    {
      gdbpy_ref<> hook (PyObject_GetAttrString (gdb_python_module,
						"prompt_hook"));
      if (hook == NULL)
	{
	  gdbpy_print_stack ();
	  return EXT_LANG_RC_ERROR;
	}

      if (PyCallable_Check (hook.get ()))
	{
	  gdbpy_ref<> current_prompt (PyUnicode_FromString (current_gdb_prompt));
	  if (current_prompt == NULL)
	    {
	      gdbpy_print_stack ();
	      return EXT_LANG_RC_ERROR;
	    }

	  gdbpy_ref<> result
	    (PyObject_CallFunctionObjArgs (hook.get (), current_prompt.get (),
					   NULL));
	  if (result == NULL)
	    {
	      gdbpy_print_stack ();
	      return EXT_LANG_RC_ERROR;
	    }

	  /* Return type should be None, or a String.  If it is None,
	     fall through, we will not set a prompt.  If it is a
	     string, set  PROMPT.  Anything else, set an exception.  */
	  if (result != Py_None && !PyUnicode_Check (result.get ()))
	    {
	      PyErr_Format (PyExc_RuntimeError,
			    _("Return from prompt_hook must " \
			      "be either a Python string, or None"));
	      gdbpy_print_stack ();
	      return EXT_LANG_RC_ERROR;
	    }

	  if (result != Py_None)
	    {
	      gdb::unique_xmalloc_ptr<char>
		prompt (python_string_to_host_string (result.get ()));

	      if (prompt == NULL)
		{
		  gdbpy_print_stack ();
		  return EXT_LANG_RC_ERROR;
		}

	      set_prompt (prompt.get ());
	      return EXT_LANG_RC_OK;
	    }
	}
    }

  return EXT_LANG_RC_NOP;
}

/* This is the extension_language_ops.colorize "method".  */

static std::optional<std::string>
gdbpy_colorize (const std::string &filename, const std::string &contents,
		enum language lang)
{
  if (!gdb_python_initialized)
    return {};

  gdbpy_enter enter_py;

  gdbpy_ref<> mod (PyImport_ImportModule ("gdb.styling"));
  if (mod == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  if (!PyObject_HasAttrString (mod.get (), "colorize"))
    return {};

  gdbpy_ref<> hook (PyObject_GetAttrString (mod.get (), "colorize"));
  if (hook == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  if (!PyCallable_Check (hook.get ()))
    return {};

  gdbpy_ref<> fname_arg (PyUnicode_FromString (filename.c_str ()));
  if (fname_arg == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  gdbpy_ref<> lang_arg (PyUnicode_FromString (language_str (lang)));
  if (lang_arg == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* The pygments library, which is what we currently use for applying
     styling, is happy to take input as a bytes object, and to figure out
     the encoding for itself.  This removes the need for us to figure out
     (guess?) at how the content is encoded, which is probably a good
     thing.  */
  gdbpy_ref<> contents_arg (PyBytes_FromStringAndSize (contents.c_str (),
						       contents.size ()));
  if (contents_arg == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Calling gdb.colorize passing in the filename (a string), and the file
     contents (a bytes object).  This function should return either a bytes
     object, the same contents with styling applied, or None to indicate
     that no styling should be performed.  */
  gdbpy_ref<> result (PyObject_CallFunctionObjArgs (hook.get (),
						    fname_arg.get (),
						    contents_arg.get (),
						    lang_arg.get (),
						    nullptr));
  if (result == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  if (result == Py_None)
    return {};
  else if (!PyBytes_Check (result.get ()))
    {
      PyErr_SetString (PyExc_TypeError,
		       _("Return value from gdb.colorize should be a bytes object or None."));
      gdbpy_print_stack ();
      return {};
    }

  return std::string (PyBytes_AsString (result.get ()));
}

/* This is the extension_language_ops.colorize_disasm "method".  */

static std::optional<std::string>
gdbpy_colorize_disasm (const std::string &content, gdbarch *gdbarch)
{
  if (!gdb_python_initialized)
    return {};

  gdbpy_enter enter_py;

  gdbpy_ref<> mod (PyImport_ImportModule ("gdb.styling"));
  if (mod == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  if (!PyObject_HasAttrString (mod.get (), "colorize_disasm"))
    return {};

  gdbpy_ref<> hook (PyObject_GetAttrString (mod.get (),
					    "colorize_disasm"));
  if (hook == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  if (!PyCallable_Check (hook.get ()))
    return {};

  gdbpy_ref<> content_arg (PyBytes_FromString (content.c_str ()));
  if (content_arg == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  gdbpy_ref<> gdbarch_arg = gdbarch_to_arch_object (gdbarch);
  if (gdbarch_arg == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  gdbpy_ref<> result (PyObject_CallFunctionObjArgs (hook.get (),
						    content_arg.get (),
						    gdbarch_arg.get (),
						    nullptr));
  if (result == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  if (result == Py_None)
    return {};

  if (!PyBytes_Check (result.get ()))
    {
      PyErr_SetString (PyExc_TypeError,
		       _("Return value from gdb.colorize_disasm should be a bytes object or None."));
      gdbpy_print_stack ();
      return {};
    }

  return std::string (PyBytes_AsString (result.get ()));
}



/* Implement gdb.format_address(ADDR,P_SPACE,ARCH).  Provide access to
   GDB's print_address function from Python.  The returned address will
   have the format '0x..... <symbol+offset>'.  */

static PyObject *
gdbpy_format_address (PyObject *self, PyObject *args, PyObject *kw)
{
  static const char *keywords[] =
    {
      "address", "progspace", "architecture", nullptr
    };
  PyObject *addr_obj = nullptr, *pspace_obj = nullptr, *arch_obj = nullptr;
  CORE_ADDR addr;
  struct gdbarch *gdbarch = nullptr;
  struct program_space *pspace = nullptr;

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O|OO", keywords,
					&addr_obj, &pspace_obj, &arch_obj))
    return nullptr;

  if (get_addr_from_python (addr_obj, &addr) < 0)
    return nullptr;

  /* If the user passed None for progspace or architecture, then we
     consider this to mean "the default".  Here we replace references to
     None with nullptr, this means that in the following code we only have
     to handle the nullptr case.  These are only borrowed references, so
     no decref is required here.  */
  if (pspace_obj == Py_None)
    pspace_obj = nullptr;
  if (arch_obj == Py_None)
    arch_obj = nullptr;

  if (pspace_obj == nullptr && arch_obj == nullptr)
    {
      /* Grab both of these from the current inferior, and its associated
	 default architecture.  */
      pspace = current_inferior ()->pspace;
      gdbarch = current_inferior ()->arch ();
    }
  else if (arch_obj == nullptr || pspace_obj == nullptr)
    {
      /* If the user has only given one of program space or architecture,
	 then don't use the default for the other.  Sure we could use the
	 default, but it feels like there's too much scope of mistakes in
	 this case, so better to require the user to provide both
	 arguments.  */
      PyErr_SetString (PyExc_ValueError,
		       _("The architecture and progspace arguments must both be supplied"));
      return nullptr;
    }
  else
    {
      /* The user provided an address, program space, and architecture.
	 Just check that these objects are valid.  */
      if (!gdbpy_is_progspace (pspace_obj))
	{
	  PyErr_SetString (PyExc_TypeError,
			   _("The progspace argument is not a gdb.Progspace object"));
	  return nullptr;
	}

      pspace = progspace_object_to_program_space (pspace_obj);
      if (pspace == nullptr)
	{
	  PyErr_SetString (PyExc_ValueError,
			   _("The progspace argument is not valid"));
	  return nullptr;
	}

      if (!gdbpy_is_architecture (arch_obj))
	{
	  PyErr_SetString (PyExc_TypeError,
			   _("The architecture argument is not a gdb.Architecture object"));
	  return nullptr;
	}

      /* Architectures are never deleted once created, so gdbarch should
	 never come back as nullptr.  */
      gdbarch = arch_object_to_gdbarch (arch_obj);
      gdb_assert (gdbarch != nullptr);
    }

  /* By this point we should know the program space and architecture we are
     going to use.  */
  gdb_assert (pspace != nullptr);
  gdb_assert (gdbarch != nullptr);

  /* Unfortunately print_address relies on the current program space for
     its symbol lookup.  Temporarily switch now.  */
  scoped_restore_current_program_space restore_progspace;
  set_current_program_space (pspace);

  /* Format the address, and return it as a string.  */
  string_file buf;
  print_address (gdbarch, addr, &buf);
  return PyUnicode_FromString (buf.c_str ());
}



/* Printing.  */

/* A python function to write a single string using gdb's filtered
   output stream .  The optional keyword STREAM can be used to write
   to a particular stream.  The default stream is to gdb_stdout.  */

static PyObject *
gdbpy_write (PyObject *self, PyObject *args, PyObject *kw)
{
  const char *arg;
  static const char *keywords[] = { "text", "stream", "style", nullptr };
  int stream_type = 0;
  PyObject *style_obj = Py_None;

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|iO", keywords, &arg,
					&stream_type, &style_obj))
    return nullptr;

  if (style_obj != Py_None && !gdbpy_is_style (style_obj))
    {
      PyErr_Format
	(PyExc_TypeError,
	 _("'style' argument must be gdb.Style or None, not %s."),
	 Py_TYPE (style_obj)->tp_name);
      return nullptr;
    }

  try
    {
      ui_file *stream;
      switch (stream_type)
	{
	case 1:
	  stream = gdb_stderr;
	  break;
	case 2:
	  stream = gdb_stdlog;
	  break;
	default:
	  stream = gdb_stdout;
	  break;
	}

      if (style_obj == Py_None)
	gdb_puts (arg, stream);
      else
	{
	  std::optional<ui_file_style> style
	    = gdbpy_style_object_to_ui_file_style (style_obj);
	  if (!style.has_value ())
	    return nullptr;

	  fputs_styled (arg, style.value (), stream);
	}
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  Py_RETURN_NONE;
}

/* A python function to flush a gdb stream.  The optional keyword
   STREAM can be used to flush a particular stream.  The default stream
   is gdb_stdout.  */

static PyObject *
gdbpy_flush (PyObject *self, PyObject *args, PyObject *kw)
{
  static const char *keywords[] = { "stream", NULL };
  int stream_type = 0;

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "|i", keywords,
					&stream_type))
    return NULL;

  switch (stream_type)
    {
    case 1:
      {
	if (gdb_stderr != nullptr)
	  gdb_flush (gdb_stderr);
	break;
      }
    case 2:
      {
	if (gdb_stdlog != nullptr)
	  gdb_flush (gdb_stdlog);
	break;
      }
    default:
      if (gdb_stdout != nullptr)
	gdb_flush (gdb_stdout);
    }

  Py_RETURN_NONE;
}

/* Implement gdb.warning().  Takes a single text string argument and emit a
   warning using GDB's 'warning' function.  The input text string must not
   be empty.  */

static PyObject *
gdbpy_warning (PyObject *self, PyObject *args, PyObject *kw)
{
  const char *text;
  static const char *keywords[] = { "text", nullptr };

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &text))
    return nullptr;

  if (strlen (text) == 0)
    {
      PyErr_SetString (PyExc_ValueError,
		       _("Empty text string passed to gdb.warning"));
      return nullptr;
    }

  try
    {
      warning ("%s", text);
    }
  catch (const gdb_exception &ex)
    {
      /* The warning() call probably cannot throw an exception.  But just
	 in case it ever does.  */
      return gdbpy_handle_gdb_exception (nullptr, ex);
    }

  Py_RETURN_NONE;
}

/* Return non-zero if print-stack is not "none".  */

int
gdbpy_print_python_errors_p (void)
{
  return gdbpy_should_print_stack != python_excp_none;
}

/* Print a python exception trace, print just a message, or print
   nothing and clear the python exception, depending on
   gdbpy_should_print_stack.  Only call this if a python exception is
   set.  */
void
gdbpy_print_stack (void)
{

  /* Print "none", just clear exception.  */
  if (gdbpy_should_print_stack == python_excp_none)
    {
      PyErr_Clear ();
    }
  /* Print "full" message and backtrace.  */
  else if (gdbpy_should_print_stack == python_excp_full)
    {
      PyErr_Print ();
      /* PyErr_Print doesn't necessarily end output with a newline.
	 This works because Python's stdout/stderr is fed through
	 gdb_printf.  */
      try
	{
	  begin_line ();
	}
      catch (const gdb_exception &except)
	{
	}
    }
  /* Print "message", just error print message.  */
  else
    {
      gdbpy_err_fetch fetched_error;

      gdb::unique_xmalloc_ptr<char> msg = fetched_error.to_string ();
      gdb::unique_xmalloc_ptr<char> type;
      /* Don't compute TYPE if MSG already indicates that there is an
	 error.  */
      if (msg != NULL)
	type = fetched_error.type_to_string ();

      try
	{
	  if (msg == NULL || type == NULL)
	    {
	      /* An error occurred computing the string representation of the
		 error message.  */
	      gdb_printf (gdb_stderr,
			  _("Error occurred computing Python error "
			    "message.\n"));
	      PyErr_Clear ();
	    }
	  else
	    gdb_printf (gdb_stderr, "Python Exception %s: %s\n",
			type.get (), msg.get ());
	}
      catch (const gdb_exception &except)
	{
	}
    }
}

/* Like gdbpy_print_stack, but if the exception is a
   KeyboardException, throw a gdb "quit" instead.  */

void
gdbpy_print_stack_or_quit ()
{
  if (PyErr_ExceptionMatches (PyExc_KeyboardInterrupt))
    {
      PyErr_Clear ();
      throw_quit ("Quit");
    }
  gdbpy_print_stack ();
}



/* Return a sequence holding all the Progspaces.  */

static PyObject *
gdbpy_progspaces (PyObject *unused1, PyObject *unused2)
{
  gdbpy_ref<> list (PyList_New (0));
  if (list == NULL)
    return NULL;

  for (struct program_space *ps : program_spaces)
    {
      gdbpy_ref<> item = pspace_to_pspace_object (ps);

      if (item == NULL || PyList_Append (list.get (), item.get ()) == -1)
	return NULL;
    }

  return list.release ();
}

/* Return the name of the current language.  */

static PyObject *
gdbpy_current_language (PyObject *unused1, PyObject *unused2)
{
  return host_string_to_python_string (current_language->name ()).release ();
}



/* See python.h.  */
struct objfile *gdbpy_current_objfile;

/* Set the current objfile to OBJFILE and then read FILE named FILENAME
   as Python code.  This does not throw any errors.  If an exception
   occurs python will print the traceback and clear the error indicator.
   This is the extension_language_script_ops.objfile_script_sourcer
   "method".  */

static void
gdbpy_source_objfile_script (const struct extension_language_defn *extlang,
			     struct objfile *objfile, FILE *file,
			     const char *filename)
{
  if (!gdb_python_initialized)
    return;

  gdbpy_enter enter_py (objfile->arch ());
  scoped_restore restire_current_objfile
    = make_scoped_restore (&gdbpy_current_objfile, objfile);

  int result = python_run_simple_file (file, filename);
  if (result != 0)
    gdbpy_print_stack ();
}

/* Set the current objfile to OBJFILE and then execute SCRIPT
   as Python code.  This does not throw any errors.  If an exception
   occurs python will print the traceback and clear the error indicator.
   This is the extension_language_script_ops.objfile_script_executor
   "method".  */

static void
gdbpy_execute_objfile_script (const struct extension_language_defn *extlang,
			      struct objfile *objfile, const char *name,
			      const char *script)
{
  if (!gdb_python_initialized)
    return;

  gdbpy_enter enter_py (objfile->arch ());
  scoped_restore restire_current_objfile
    = make_scoped_restore (&gdbpy_current_objfile, objfile);

  int ret = eval_python_command (script, Py_file_input);
  if (ret != 0)
    gdbpy_print_stack ();
}

/* Return the current Objfile, or None if there isn't one.  */

static PyObject *
gdbpy_get_current_objfile (PyObject *unused1, PyObject *unused2)
{
  if (! gdbpy_current_objfile)
    Py_RETURN_NONE;

  return objfile_to_objfile_object (gdbpy_current_objfile).release ();
}

/* Implement the 'handle_missing_debuginfo' hook for Python.  GDB has
   failed to find any debug information for OBJFILE.  The extension has a
   chance to record this, or even install the required debug information.
   See the description of ext_lang_missing_file_result in extension-priv.h
   for details of the return value.  */

static ext_lang_missing_file_result
gdbpy_handle_missing_debuginfo (const struct extension_language_defn *extlang,
				struct objfile *objfile)
{
  /* Early exit if Python is not initialised.  */
  if (!gdb_python_initialized || gdb_python_module == nullptr)
    return {};

  struct gdbarch *gdbarch = objfile->arch ();

  gdbpy_enter enter_py (gdbarch);

  /* Convert OBJFILE into the corresponding Python object.  */
  gdbpy_ref<> pyo_objfile = objfile_to_objfile_object (objfile);
  if (pyo_objfile == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Lookup the helper function within the GDB module.  */
  gdbpy_ref<> pyo_handler
    (PyObject_GetAttrString (gdb_python_module, "_handle_missing_debuginfo"));
  if (pyo_handler == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Call the function, passing in the Python objfile object.  */
  gdbpy_ref<> pyo_execute_ret
    (PyObject_CallFunctionObjArgs (pyo_handler.get (), pyo_objfile.get (),
				   nullptr));
  if (pyo_execute_ret == nullptr)
    {
      /* If the handler is cancelled due to a Ctrl-C, then propagate
	 the Ctrl-C as a GDB exception instead of swallowing it.  */
      gdbpy_print_stack_or_quit ();
      return {};
    }

  /* Parse the result, and convert it back to the C++ object.  */
  if (pyo_execute_ret == Py_None)
    return {};

  if (PyBool_Check (pyo_execute_ret.get ()))
    {
      /* We know the value is a bool, so it must be either Py_True or
	 Py_False.  Anything else would not get past the above check.  */
      bool try_again = pyo_execute_ret.get () == Py_True;
      return ext_lang_missing_file_result (try_again);
    }

  if (!gdbpy_is_string (pyo_execute_ret.get ()))
    {
      PyErr_SetString (PyExc_ValueError,
		       "return value from _handle_missing_debuginfo should "
		       "be None, a Bool, or a String");
      gdbpy_print_stack ();
      return {};
    }

  gdb::unique_xmalloc_ptr<char> filename
    = python_string_to_host_string (pyo_execute_ret.get ());
  if (filename == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  return ext_lang_missing_file_result (std::string (filename.get ()));
}

/* Implement the find_objfile_from_buildid hook for Python.  PSPACE is the
   program space in which GDB is trying to find an objfile, BUILD_ID is the
   build-id for the missing objfile, and EXPECTED_FILENAME is a non-NULL
   string which can be used (if needed) in messages to the user, and
   represents the file GDB is looking for.  */

static ext_lang_missing_file_result
gdbpy_find_objfile_from_buildid (const struct extension_language_defn *extlang,
				 program_space *pspace,
				 const struct bfd_build_id *build_id,
				 const char *missing_filename)
{
  gdb_assert (pspace != nullptr);
  gdb_assert (build_id != nullptr);
  gdb_assert (missing_filename != nullptr);

  /* Early exit if Python is not initialised.  */
  if (!gdb_python_initialized || gdb_python_module == nullptr)
    return {};

  gdbpy_enter enter_py;

  /* Convert BUILD_ID into a Python object.  */
  std::string hex_form = bin2hex (build_id->data, build_id->size);
  gdbpy_ref<> pyo_buildid = host_string_to_python_string (hex_form.c_str ());
  if (pyo_buildid == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Convert MISSING_FILENAME to a Python object.  */
  gdbpy_ref<> pyo_filename = host_string_to_python_string (missing_filename);
  if (pyo_filename == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Convert PSPACE to a Python object.  */
  gdbpy_ref<> pyo_pspace = pspace_to_pspace_object (pspace);
  if (pyo_pspace == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Lookup the helper function within the GDB module.  */
  gdbpy_ref<> pyo_handler
    (PyObject_GetAttrString (gdb_python_module, "_handle_missing_objfile"));
  if (pyo_handler == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Call the function, passing in the Python objfile object.  */
  gdbpy_ref<> pyo_execute_ret
    (PyObject_CallFunctionObjArgs (pyo_handler.get (), pyo_pspace.get (),
				   pyo_buildid.get (), pyo_filename.get (),
				   nullptr));
  if (pyo_execute_ret == nullptr)
    {
      /* If the handler is cancelled due to a Ctrl-C, then propagate
	 the Ctrl-C as a GDB exception instead of swallowing it.  */
      gdbpy_print_stack_or_quit ();
      return {};
    }

  /* Parse the result, and convert it back to the C++ object.  */
  if (pyo_execute_ret == Py_None)
    return {};

  if (PyBool_Check (pyo_execute_ret.get ()))
    {
      /* We know the value is a bool, so it must be either Py_True or
	 Py_False.  Anything else would not get past the above check.  */
      bool try_again = pyo_execute_ret.get () == Py_True;
      return ext_lang_missing_file_result (try_again);
    }

  if (!gdbpy_is_string (pyo_execute_ret.get ()))
    {
      PyErr_SetString (PyExc_ValueError,
		       "return value from _find_objfile_by_buildid should "
		       "be None, a bool, or a str");
      gdbpy_print_stack ();
      return {};
    }

  gdb::unique_xmalloc_ptr<char> filename
    = python_string_to_host_string (pyo_execute_ret.get ());
  if (filename == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  return ext_lang_missing_file_result (std::string (filename.get ()));
}

/* Compute the list of active python type printers and store them in
   EXT_PRINTERS->py_type_printers.  The product of this function is used by
   gdbpy_apply_type_printers, and freed by gdbpy_free_type_printers.
   This is the extension_language_ops.start_type_printers "method".  */

static void
gdbpy_start_type_printers (const struct extension_language_defn *extlang,
			   struct ext_lang_type_printers *ext_printers)
{
  PyObject *printers_obj = NULL;

  if (!gdb_python_initialized)
    return;

  gdbpy_enter enter_py;

  gdbpy_ref<> type_module (PyImport_ImportModule ("gdb.types"));
  if (type_module == NULL)
    {
      gdbpy_print_stack ();
      return;
    }

  gdbpy_ref<> func (PyObject_GetAttrString (type_module.get (),
					    "get_type_recognizers"));
  if (func == NULL)
    {
      gdbpy_print_stack ();
      return;
    }

  printers_obj = PyObject_CallFunctionObjArgs (func.get (), (char *) NULL);
  if (printers_obj == NULL)
    gdbpy_print_stack ();
  else
    ext_printers->py_type_printers = printers_obj;
}

/* If TYPE is recognized by some type printer, store in *PRETTIED_TYPE
   a newly allocated string holding the type's replacement name, and return
   EXT_LANG_RC_OK.
   If there's a Python error return EXT_LANG_RC_ERROR.
   Otherwise, return EXT_LANG_RC_NOP.
   This is the extension_language_ops.apply_type_printers "method".  */

static enum ext_lang_rc
gdbpy_apply_type_printers (const struct extension_language_defn *extlang,
			   const struct ext_lang_type_printers *ext_printers,
			   struct type *type,
			   gdb::unique_xmalloc_ptr<char> *prettied_type)
{
  PyObject *printers_obj = (PyObject *) ext_printers->py_type_printers;
  gdb::unique_xmalloc_ptr<char> result;

  if (printers_obj == NULL)
    return EXT_LANG_RC_NOP;

  if (!gdb_python_initialized)
    return EXT_LANG_RC_NOP;

  gdbpy_enter enter_py;

  gdbpy_ref<> type_obj = type_to_type_object (type);
  if (type_obj == NULL)
    {
      gdbpy_print_stack ();
      return EXT_LANG_RC_ERROR;
    }

  gdbpy_ref<> type_module (PyImport_ImportModule ("gdb.types"));
  if (type_module == NULL)
    {
      gdbpy_print_stack ();
      return EXT_LANG_RC_ERROR;
    }

  gdbpy_ref<> func (PyObject_GetAttrString (type_module.get (),
					    "apply_type_recognizers"));
  if (func == NULL)
    {
      gdbpy_print_stack ();
      return EXT_LANG_RC_ERROR;
    }

  gdbpy_ref<> result_obj (PyObject_CallFunctionObjArgs (func.get (),
							printers_obj,
							type_obj.get (),
							(char *) NULL));
  if (result_obj == NULL)
    {
      gdbpy_print_stack ();
      return EXT_LANG_RC_ERROR;
    }

  if (result_obj == Py_None)
    return EXT_LANG_RC_NOP;

  result = python_string_to_host_string (result_obj.get ());
  if (result == NULL)
    {
      gdbpy_print_stack ();
      return EXT_LANG_RC_ERROR;
    }

  *prettied_type = std::move (result);
  return EXT_LANG_RC_OK;
}

/* Free the result of start_type_printers.
   This is the extension_language_ops.free_type_printers "method".  */

static void
gdbpy_free_type_printers (const struct extension_language_defn *extlang,
			  struct ext_lang_type_printers *ext_printers)
{
  PyObject *printers = (PyObject *) ext_printers->py_type_printers;

  if (printers == NULL)
    return;

  if (!gdb_python_initialized)
    return;

  gdbpy_enter enter_py;
  Py_DECREF (printers);
}

#else /* HAVE_PYTHON */

/* Dummy implementation of the gdb "python-interactive" and "python"
   command. */

static void
python_interactive_command (const char *arg, int from_tty)
{
  arg = skip_spaces (arg);
  if (arg && *arg)
    error (_("Python scripting is not supported in this copy of GDB."));
  else
    {
      counted_command_line l = get_command_line (python_control, "");

      execute_control_command_untraced (l.get ());
    }
}

static void
python_command (const char *arg, int from_tty)
{
  python_interactive_command (arg, from_tty);
}

#endif /* HAVE_PYTHON */

/* Stand-in for Py_IsInitialized ().  To be used because after a python fatal
   error, no calls into Python are allowed.  */

static bool py_isinitialized = false;

/* Variables to hold the effective values of "python ignore-environment" and
   "python dont-write-bytecode" at Python initialization.  */

static bool python_ignore_environment_at_python_initialization;
static bool python_dont_write_bytecode_at_python_initialization;

/* When this is turned on before Python is initialised then Python will
   ignore any environment variables related to Python.  This is equivalent
   to passing `-E' to the python program.  */
static bool python_ignore_environment = false;

/* Implement 'show python ignore-environment'.  */

static void
show_python_ignore_environment (struct ui_file *file, int from_tty,
				struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Python's ignore-environment setting is %s.\n"),
	      value);
}

/* Implement 'set python ignore-environment'.  This sets Python's internal
   flag no matter when the command is issued, however, if this is used
   after Py_Initialize has been called then most of the environment will
   already have been read.  */

static void
set_python_ignore_environment (const char *args, int from_tty,
			       struct cmd_list_element *c)
{
  if (py_isinitialized)
    {
      python_ignore_environment
	= python_ignore_environment_at_python_initialization;

      warning (_("Setting python ignore-environment after Python"
		 " initialization has no effect, try setting this during"
		 " early initialization"));
    }
}

/* When this is turned on before Python is initialised then Python will
   not write `.pyc' files on import of a module.  */
static enum auto_boolean python_dont_write_bytecode = AUTO_BOOLEAN_AUTO;


/* Return true if environment variable PYTHONDONTWRITEBYTECODE is set to a
   non-empty string.  */

static bool
env_python_dont_write_bytecode ()
{
  const char *envvar = getenv ("PYTHONDONTWRITEBYTECODE");
  return envvar != nullptr && envvar[0] != '\0';
}

/* Implement 'show python dont-write-bytecode'.  */

static void
show_python_dont_write_bytecode (struct ui_file *file, int from_tty,
				 struct cmd_list_element *c, const char *value)
{
  if (python_dont_write_bytecode == AUTO_BOOLEAN_AUTO)
    {
      const char *auto_string
	= ((python_ignore_environment
	    || !env_python_dont_write_bytecode ())
	   ? "off"
	   : "on");

      gdb_printf (file,
		  _("Python's dont-write-bytecode setting is %s (currently %s).\n"),
		  value, auto_string);
    }
  else
    gdb_printf (file, _("Python's dont-write-bytecode setting is %s.\n"),
		value);
}

#ifdef HAVE_PYTHON
/* Return value to assign to PyConfig.write_bytecode or, when
   negated (via !), Py_DontWriteBytecodeFlag.  Py_DontWriteBytecodeFlag
   is deprecated in Python 3.12.  */

static int
python_write_bytecode ()
{
  int wbc = 0;

  if (python_dont_write_bytecode == AUTO_BOOLEAN_AUTO)
    {
      if (python_ignore_environment)
	wbc = 1;
      else
	wbc = env_python_dont_write_bytecode () ? 0 : 1;
    }
  else
    wbc = python_dont_write_bytecode == AUTO_BOOLEAN_TRUE ? 0 : 1;

  return wbc;
}
#endif /* HAVE_PYTHON */

/* Implement 'set python dont-write-bytecode'.  This sets Python's internal
   flag no matter when the command is issued, however, if this is used
   after Py_Initialize has been called then many modules could already
   have been imported and their byte code written out.  */

static void
set_python_dont_write_bytecode (const char *args, int from_tty,
				struct cmd_list_element *c)
{
  if (py_isinitialized)
    {
      python_dont_write_bytecode
	= (python_dont_write_bytecode_at_python_initialization
	   ? AUTO_BOOLEAN_TRUE
	   : AUTO_BOOLEAN_FALSE);

      warning (_("Setting python dont-write-bytecode after Python"
		 " initialization has no effect, try setting this during"
		 " early initialization, or try setting"
		 " sys.dont_write_bytecode"));
    }
}



/* Lists for 'set python' commands.  */

static struct cmd_list_element *user_set_python_list;
static struct cmd_list_element *user_show_python_list;

/* Initialize the Python code.  */

#ifdef HAVE_PYTHON

/* This is installed as a final cleanup and cleans up the
   interpreter.  This lets Python's 'atexit' work.  */

static void
finalize_python (const struct extension_language_defn *ignore)
{
  if (!gdb_python_initialized)
    return;

  struct active_ext_lang_state *previous_active;

  /* We don't use ensure_python_env here because if we ever ran the
     cleanup, gdb would crash -- because the cleanup calls into the
     Python interpreter, which we are about to destroy.  It seems
     clearer to make the needed calls explicitly here than to create a
     cleanup and then mysteriously discard it.  */

  /* This is only called as a final cleanup so we can assume the active
     SIGINT handler is gdb's.  We still need to tell it to notify Python.  */
  previous_active = set_active_ext_lang (&extension_language_python);

  (void) PyGILState_Ensure ();
  gdbpy_enter::finalize ();

  /* Call the gdbpy_finalize_* functions from every *.c file.  */
  gdbpy_initialize_file::finalize_all ();

  Py_Finalize ();

  gdb_python_initialized = false;
  restore_active_ext_lang (previous_active);
}

static struct PyModuleDef python_GdbModuleDef =
{
  PyModuleDef_HEAD_INIT,
  "_gdb",
  NULL,
  -1,
  python_GdbMethods,
  NULL,
  NULL,
  NULL,
  NULL
};

/* This is called via the PyImport_AppendInittab mechanism called
   during initialization, to make the built-in _gdb module known to
   Python.  */
PyMODINIT_FUNC init__gdb_module (void);
PyMODINIT_FUNC
init__gdb_module (void)
{
  return PyModule_Create (&python_GdbModuleDef);
}

/* Emit a gdb.GdbExitingEvent, return a negative value if there are any
   errors, otherwise, return 0.  */

static int
emit_exiting_event (int exit_code)
{
  if (evregpy_no_listeners_p (gdb_py_events.gdb_exiting))
    return 0;

  gdbpy_ref<> event_obj = create_event_object (&gdb_exiting_event_object_type);
  if (event_obj == nullptr)
    return -1;

  gdbpy_ref<> code = gdb_py_object_from_longest (exit_code);
  if (evpy_add_attribute (event_obj.get (), "exit_code", code.get ()) < 0)
    return -1;

  return evpy_emit_event (event_obj.get (), gdb_py_events.gdb_exiting);
}

/* Callback for the gdb_exiting observable.  EXIT_CODE is the value GDB
   will exit with.  */

static void
gdbpy_gdb_exiting (int exit_code)
{
  if (!gdb_python_initialized)
    return;

  gdbpy_enter enter_py;

  if (emit_exiting_event (exit_code) < 0)
    gdbpy_print_stack ();
}

/* Use PyConfig mechanisms for Python 3.9 and newer.

   We used to do this for 3.10 and newer to avoid Py_SetProgramName
   deprecation in 3.11.

   With 3.9 and the py_initialize_catch_abort approach, we run into a problem
   where exit is called instead of abort, making gdb exit (possibly
   https://github.com/python/cpython/issues/107827).  Using the PyConfig
   mechanism (available starting 3.8) fixes that.  Todo: see if we have the
   same problem for 3.8, and if we can apply the same fix.  */
#if PY_VERSION_HEX < 0x03090000
/* Signal handler to convert a SIGABRT into an exception.  */

static void
catch_python_fatal (int signum)
{
  signal (SIGABRT, catch_python_fatal);

  throw_exception_sjlj (gdb_exception {RETURN_ERROR, GENERIC_ERROR});
}

/* Call Py_Initialize (), and return true if successful.   */

static bool
py_initialize_catch_abort ()
{
  auto prev_handler = signal (SIGABRT, catch_python_fatal);
  SCOPE_EXIT { signal (SIGABRT, prev_handler); };

  TRY_SJLJ
    {
      Py_Initialize ();
      py_isinitialized = true;
    }
  CATCH_SJLJ (e, RETURN_MASK_ERROR)
    {
    }
  END_CATCH_SJLJ;

  return py_isinitialized;
}
#endif

/* Initialize python, either by calling Py_Initialize or
   Py_InitializeFromConfig, and return true if successful.  */

static bool
py_initialize ()
{
  /* Sample values at Python initialization.  */
  python_dont_write_bytecode_at_python_initialization
    = !python_write_bytecode ();
  python_ignore_environment_at_python_initialization
    =  python_ignore_environment;

  /* Don't show "python dont-write-bytecode auto" after Python
     initialization.  */
  python_dont_write_bytecode
    = (python_dont_write_bytecode_at_python_initialization
       ? AUTO_BOOLEAN_TRUE
       : AUTO_BOOLEAN_FALSE);

/* Use PyConfig mechanisms for Python 3.9 and newer.  */
#if PY_VERSION_HEX < 0x03090000
  /* Python documentation indicates that the memory given
     to Py_SetProgramName cannot be freed.  However, it seems that
     at least Python 3.7.4 Py_SetProgramName takes a copy of the
     given program_name.  Making progname_copy static and not release
     the memory avoids a leak report for Python versions that duplicate
     program_name, and respect the requirement of Py_SetProgramName
     for Python versions that do not duplicate program_name.  */
  static wchar_t *progname_copy = nullptr;
#else
  wchar_t *progname_copy = nullptr;
  SCOPE_EXIT { XDELETEVEC (progname_copy); };
#endif

#ifdef WITH_PYTHON_PATH
  /* Work around problem where python gets confused about where it is,
     and then can't find its libraries, etc.
     NOTE: Python assumes the following layout:
     /foo/bin/python
     /foo/lib/pythonX.Y/...
     This must be done before calling Py_Initialize.  */
  gdb::unique_xmalloc_ptr<char> progname
    (concat (gdb_ldirname (python_libdir.c_str ()).c_str (), SLASH_STRING, "bin",
	      SLASH_STRING, "python", (char *) NULL));

  {
    std::string oldloc = setlocale (LC_ALL, NULL);
    SCOPE_EXIT { setlocale (LC_ALL, oldloc.c_str ()); };

    setlocale (LC_ALL, "");
    size_t progsize = strlen (progname.get ());
    progname_copy = XNEWVEC (wchar_t, progsize + 1);
    size_t count = mbstowcs (progname_copy, progname.get (), progsize + 1);
    if (count == (size_t) -1)
      {
	fprintf (stderr, "Could not convert python path to string\n");
	return false;
      }
  }
#endif

/* Use PyConfig mechanisms for Python 3.9 and newer.  */
#if PY_VERSION_HEX < 0x03090000
  /* Note that Py_SetProgramName expects the string it is passed to
     remain alive for the duration of the program's execution, so
     it is not freed after this call.  */
  if (progname_copy != nullptr)
    Py_SetProgramName (progname_copy);
  Py_DontWriteBytecodeFlag
    = python_dont_write_bytecode_at_python_initialization;
  Py_IgnoreEnvironmentFlag
    = python_ignore_environment_at_python_initialization ? 1 : 0;
  return py_initialize_catch_abort ();
#else
  PyConfig config;

  PyConfig_InitPythonConfig (&config);
  PyStatus status;
  if (progname_copy != nullptr)
    {
      status = PyConfig_SetString (&config, &config.program_name,
				   progname_copy);
      if (PyStatus_Exception (status))
	goto init_done;
    }

  config.write_bytecode = !python_dont_write_bytecode_at_python_initialization;
  config.use_environment = !python_ignore_environment_at_python_initialization;

  status = PyConfig_Read (&config);
  if (PyStatus_Exception (status))
    goto init_done;

  status = Py_InitializeFromConfig (&config);

init_done:
  PyConfig_Clear (&config);
  if (PyStatus_Exception (status))
    {
      if (PyStatus_IsError (status))
	gdb_printf (_("Python initialization failed: %s\n"), status.err_msg);
      else
	gdb_printf (_("Python initialization failed with exit status: %d\n"),
		    status.exitcode);
      return false;
    }

  py_isinitialized = true;
  return true;
#endif
}

static bool
do_start_initialization ()
{
  /* Define all internal modules.  These are all imported (and thus
     created) during initialization.  */
  if (PyImport_AppendInittab ("_gdb", init__gdb_module) < 0
      || PyImport_AppendInittab ("_gdbevents", gdbpy_events_mod_func) < 0)
    return false;

  if (!py_initialize ())
    return false;

#if PY_VERSION_HEX < 0x03090000
  /* PyEval_InitThreads became deprecated in Python 3.9 and will
     be removed in Python 3.11.  Prior to Python 3.7, this call was
     required to initialize the GIL.  */
  PyEval_InitThreads ();
#endif

  gdb_module = PyImport_ImportModule ("_gdb");
  if (gdb_module == NULL)
    return false;

  if (PyModule_AddStringConstant (gdb_module, "VERSION", version) < 0
      || PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", host_name) < 0
      || PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG",
				     target_name) < 0)
    return false;

  /* Add stream constants.  */
  if (PyModule_AddIntConstant (gdb_module, "STDOUT", 0) < 0
      || PyModule_AddIntConstant (gdb_module, "STDERR", 1) < 0
      || PyModule_AddIntConstant (gdb_module, "STDLOG", 2) < 0)
    return false;

  gdbpy_gdb_error = PyErr_NewException ("gdb.error", PyExc_RuntimeError, NULL);
  if (gdbpy_gdb_error == NULL
      || gdb_pymodule_addobject (gdb_module, "error", gdbpy_gdb_error) < 0)
    return false;

  gdbpy_gdb_memory_error = PyErr_NewException ("gdb.MemoryError",
					       gdbpy_gdb_error, NULL);
  if (gdbpy_gdb_memory_error == NULL
      || gdb_pymodule_addobject (gdb_module, "MemoryError",
				 gdbpy_gdb_memory_error) < 0)
    return false;

  gdbpy_gdberror_exc = PyErr_NewException ("gdb.GdbError", NULL, NULL);
  if (gdbpy_gdberror_exc == NULL
      || gdb_pymodule_addobject (gdb_module, "GdbError",
				 gdbpy_gdberror_exc) < 0)
    return false;

  /* Call the gdbpy_initialize_* functions from every *.c file.  */
  if (!gdbpy_initialize_file::initialize_all ())
    return false;

#define GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base)	\
  if (gdbpy_type_ready (&name##_event_object_type) < 0) \
    return false;
#include "py-event-types.def"
#undef GDB_PY_DEFINE_EVENT_TYPE

  gdbpy_to_string_cst = PyUnicode_FromString ("to_string");
  if (gdbpy_to_string_cst == NULL)
    return false;
  gdbpy_children_cst = PyUnicode_FromString ("children");
  if (gdbpy_children_cst == NULL)
    return false;
  gdbpy_display_hint_cst = PyUnicode_FromString ("display_hint");
  if (gdbpy_display_hint_cst == NULL)
    return false;
  gdbpy_doc_cst = PyUnicode_FromString ("__doc__");
  if (gdbpy_doc_cst == NULL)
    return false;
  gdbpy_enabled_cst = PyUnicode_FromString ("enabled");
  if (gdbpy_enabled_cst == NULL)
    return false;
  gdbpy_value_cst = PyUnicode_FromString ("value");
  if (gdbpy_value_cst == NULL)
    return false;

  gdb::observers::gdb_exiting.attach (gdbpy_gdb_exiting, "python");

  /* Release the GIL while gdb runs.  */
  PyEval_SaveThread ();

  /* Only set this when initialization has succeeded.  */
  gdb_python_initialized = 1;
  return true;
}

#if GDB_SELF_TEST
namespace selftests {

/* Entry point for python unit tests.  */

static void
test_python ()
{
#define CMD(S) execute_command_to_string (S, "python print(5)", 0, true)

  std::string output;

  CMD (output);
  SELF_CHECK (output == "5\n");
  output.clear ();

  bool saw_exception = false;
  {
    scoped_restore reset_gdb_python_initialized
      = make_scoped_restore (&gdb_python_initialized, 0);
    try
      {
	CMD (output);
      }
    catch (const gdb_exception &e)
      {
	saw_exception = true;
	SELF_CHECK (e.reason == RETURN_ERROR);
	SELF_CHECK (e.error == GENERIC_ERROR);
	SELF_CHECK (*e.message == "Python not initialized");
      }
    SELF_CHECK (saw_exception);
    SELF_CHECK (output.empty ());
  }

  saw_exception = false;
  {
    scoped_restore save_hook
      = make_scoped_restore (&hook_set_active_ext_lang,
			     []() { raise (SIGINT); });
    try
      {
	CMD (output);
      }
    catch (const gdb_exception_quit &e)
      {
	saw_exception = true;
	SELF_CHECK (e.reason == RETURN_QUIT);
	SELF_CHECK (e.error == GDB_NO_ERROR);
	SELF_CHECK (*e.message == "Quit");
      }
    SELF_CHECK (saw_exception);
    SELF_CHECK (output.empty ());
  }

#undef CMD
}

#undef CHECK_OUTPUT

} /* namespace selftests */
#endif /* GDB_SELF_TEST */

#endif /* HAVE_PYTHON */

/* See python.h.  */
cmd_list_element *python_cmd_element = nullptr;

INIT_GDB_FILE (python)
{
  cmd_list_element *python_interactive_cmd
    =	add_com ("python-interactive", class_obscure,
		 python_interactive_command,
#ifdef HAVE_PYTHON
	   _("\
Start an interactive Python prompt.\n\
\n\
To return to GDB, type the EOF character (e.g., Ctrl-D on an empty\n\
prompt).\n\
\n\
Alternatively, a single-line Python command can be given as an\n\
argument, and if the command is an expression, the result will be\n\
printed.  For example:\n\
\n\
    (gdb) python-interactive 2 + 3\n\
    5")
#else /* HAVE_PYTHON */
	   _("\
Start a Python interactive prompt.\n\
\n\
Python scripting is not supported in this copy of GDB.\n\
This command is only a placeholder.")
#endif /* HAVE_PYTHON */
	   );
  add_com_alias ("pi", python_interactive_cmd, class_obscure, 1);

  python_cmd_element = add_com ("python", class_obscure, python_command,
#ifdef HAVE_PYTHON
	   _("\
Evaluate a Python command.\n\
\n\
The command can be given as an argument, for instance:\n\
\n\
    python print (23)\n\
\n\
If no argument is given, the following lines are read and used\n\
as the Python commands.  Type a line containing \"end\" to indicate\n\
the end of the command.")
#else /* HAVE_PYTHON */
	   _("\
Evaluate a Python command.\n\
\n\
Python scripting is not supported in this copy of GDB.\n\
This command is only a placeholder.")
#endif /* HAVE_PYTHON */
	   );
  add_com_alias ("py", python_cmd_element, class_obscure, 1);

  /* Add set/show python print-stack.  */
  add_setshow_prefix_cmd ("python", no_class,
			  _("Prefix command for python preference settings."),
			  _("Prefix command for python preference settings."),
			  &user_set_python_list, &user_show_python_list,
			  &setlist, &showlist);

  add_setshow_enum_cmd ("print-stack", no_class, python_excp_enums,
			&gdbpy_should_print_stack, _("\
Set mode for Python stack dump on error."), _("\
Show the mode of Python stack printing on error."), _("\
none  == no stack or message will be printed.\n\
full == a message and a stack will be printed.\n\
message == an error message without a stack will be printed."),
			NULL, NULL,
			&user_set_python_list,
			&user_show_python_list);

  add_setshow_boolean_cmd ("ignore-environment", no_class,
			   &python_ignore_environment, _("\
Set whether the Python interpreter should ignore environment variables."), _("\
Show whether the Python interpreter showlist ignore environment variables."), _("\
When enabled GDB's Python interpreter will ignore any Python related\n\
flags in the environment.  This is equivalent to passing `-E' to a\n\
python executable."),
			   set_python_ignore_environment,
			   show_python_ignore_environment,
			   &user_set_python_list,
			   &user_show_python_list);

  add_setshow_auto_boolean_cmd ("dont-write-bytecode", no_class,
				&python_dont_write_bytecode, _("\
Set whether the Python interpreter should avoid byte-compiling python modules."), _("\
Show whether the Python interpreter should avoid byte-compiling python modules."), _("\
When enabled, GDB's embedded Python interpreter won't byte-compile python\n\
modules.  In order to take effect, this setting must be enabled in an early\n\
initialization file, i.e. those run via the --early-init-eval-command or\n\
-eix command line options.  A 'set python dont-write-bytecode on' command\n\
can also be issued directly from the GDB command line via the\n\
--early-init-eval-command or -eiex command line options.\n\
\n\
This setting defaults to 'auto'.  In this mode, provided the 'python\n\
ignore-environment' setting is 'off', the environment variable\n\
PYTHONDONTWRITEBYTECODE is examined to determine whether or not to\n\
byte-compile python modules.  PYTHONDONTWRITEBYTECODE is considered to be\n\
off/disabled either when set to the empty string or when the\n\
environment variable doesn't exist.  All other settings, including those\n\
which don't seem to make sense, indicate that it's on/enabled."),
				set_python_dont_write_bytecode,
				show_python_dont_write_bytecode,
				&user_set_python_list,
				&user_show_python_list);

#ifdef HAVE_PYTHON
#if GDB_SELF_TEST
  selftests::register_test ("python", selftests::test_python);
#endif /* GDB_SELF_TEST */
#endif /* HAVE_PYTHON */
}

#ifdef HAVE_PYTHON

/* Helper function for gdbpy_initialize.  This does the work and then
   returns false if an error has occurred and must be displayed, or true on
   success.  */

static bool
do_initialize (const struct extension_language_defn *extlang)
{
  PyObject *m;
  PyObject *sys_path;

  /* Add the initial data-directory to sys.path.  */

  std::string gdb_pythondir = (std::string (gdb_datadir) + SLASH_STRING
			       + "python");

  sys_path = PySys_GetObject ("path");

  /* PySys_SetPath was deprecated in Python 3.11.  Disable this
     deprecated code for Python 3.10 and newer.  Also note that this
     ifdef eliminates potential initialization of sys.path via
     PySys_SetPath.  My (kevinb's) understanding of PEP 587 suggests
     that it's not necessary due to module_search_paths being
     initialized to an empty list following any of the PyConfig
     initialization functions.  If it does turn out that some kind of
     initialization is still needed, it should be added to the
     PyConfig-based initialization in do_start_initialize().  */
#if PY_VERSION_HEX < 0x030a0000
  /* If sys.path is not defined yet, define it first.  */
  if (!(sys_path && PyList_Check (sys_path)))
    {
      PySys_SetPath (L"");
      sys_path = PySys_GetObject ("path");
    }
#endif
  if (sys_path && PyList_Check (sys_path))
    {
      gdbpy_ref<> pythondir (PyUnicode_FromString (gdb_pythondir.c_str ()));
      if (pythondir == NULL || PyList_Insert (sys_path, 0, pythondir.get ()))
	return false;
    }
  else
    return false;

  /* Import the gdb module to finish the initialization, and
     add it to __main__ for convenience.  */
  m = PyImport_AddModule ("__main__");
  if (m == NULL)
    return false;

  /* Keep the reference to gdb_python_module since it is in a global
     variable.  */
  gdb_python_module = PyImport_ImportModule ("gdb");
  if (gdb_python_module == NULL)
    {
      gdbpy_print_stack ();
      /* This is passed in one call to warning so that blank lines aren't
	 inserted between each line of text.  */
      warning (_("\n"
		 "Could not load the Python gdb module from `%s'.\n"
		 "Limited Python support is available from the _gdb module.\n"
		 "Suggest passing --data-directory=/path/to/gdb/data-directory."),
	       gdb_pythondir.c_str ());
      /* We return "success" here as we've already emitted the
	 warning.  */
      return true;
    }

  return gdb_pymodule_addobject (m, "gdb", gdb_python_module) >= 0;
}

/* Emit warnings in case python initialization has failed.  */

static void
python_initialization_failed_warnings ()
{
  const char *pythonhome = nullptr;
  const char *pythonpath = nullptr;

  if (!python_ignore_environment)
    {
      pythonhome = getenv ("PYTHONHOME");
      pythonpath = getenv ("PYTHONPATH");
    }

  bool have_pythonhome
    = pythonhome != nullptr && pythonhome[0] != '\0';
  bool have_pythonpath
    = pythonpath != nullptr && pythonpath[0] != '\0';

  if (have_pythonhome)
    warning (_("Python failed to initialize with PYTHONHOME set.  Maybe"
	       " because it is set incorrectly? Maybe because it points to"
	       " incompatible standard libraries? Consider changing or"
	       " unsetting it, or ignoring it using \"set python"
	       " ignore-environment on\" at early initialization."));

  if (have_pythonpath)
    warning (_("Python failed to initialize with PYTHONPATH set.  Maybe because"
	       " it points to incompatible modules? Consider changing or"
	       " unsetting it, or ignoring it using \"set python"
	       " ignore-environment on\" at early initialization."));
}

/* Perform Python initialization.  This will be called after GDB has
   performed all of its own initialization.  This is the
   extension_language_ops.initialize "method".  */

static void
gdbpy_initialize (const struct extension_language_defn *extlang)
{
  if (!do_start_initialization ())
    {
      if (py_isinitialized)
	{
	  if (PyErr_Occurred ())
	    gdbpy_print_stack ();

	  /* We got no use for the Python interpreter anymore.  Finalize it
	     ASAP.  */
	  Py_Finalize ();
	}
      else
	python_initialization_failed_warnings ();

      /* Continue with python disabled.  */
      return;
    }

  gdbpy_enter enter_py;

  if (!do_initialize (extlang))
    {
      gdbpy_print_stack ();
      warning (_("internal error: Unhandled Python exception"));
    }
}

/* Return non-zero if Python has successfully initialized.
   This is the extension_languages_ops.initialized "method".  */

static int
gdbpy_initialized (const struct extension_language_defn *extlang)
{
  return gdb_python_initialized;
}

PyMethodDef python_GdbMethods[] =
{
  { "history", gdbpy_history, METH_VARARGS,
    "Get a value from history" },
  { "add_history", gdbpy_add_history, METH_VARARGS,
    "Add a value to the value history list" },
  { "history_count", gdbpy_history_count, METH_NOARGS,
    "Return an integer, the number of values in GDB's value history" },
  { "execute", (PyCFunction) execute_gdb_command, METH_VARARGS | METH_KEYWORDS,
    "execute (command [, from_tty] [, to_string]) -> [String]\n\
Evaluate command, a string, as a gdb CLI command.  Optionally returns\n\
a Python String containing the output of the command if to_string is\n\
set to True." },
  { "execute_mi", (PyCFunction) gdbpy_execute_mi_command,
    METH_VARARGS | METH_KEYWORDS,
    "execute_mi (command, arg...) -> dictionary\n\
Evaluate command, a string, as a gdb MI command.\n\
Arguments (also strings) are passed to the command." },
  { "parameter", gdbpy_parameter, METH_VARARGS,
    "Return a gdb parameter's value" },

  { "breakpoints", gdbpy_breakpoints, METH_NOARGS,
    "Return a tuple of all breakpoint objects" },

  { "default_visualizer", gdbpy_default_visualizer, METH_VARARGS,
    "Find the default visualizer for a Value." },

  { "progspaces", gdbpy_progspaces, METH_NOARGS,
    "Return a sequence of all progspaces." },

  { "current_objfile", gdbpy_get_current_objfile, METH_NOARGS,
    "Return the current Objfile being loaded, or None." },

  { "newest_frame", gdbpy_newest_frame, METH_NOARGS,
    "newest_frame () -> gdb.Frame.\n\
Return the newest frame object." },
  { "selected_frame", gdbpy_selected_frame, METH_NOARGS,
    "selected_frame () -> gdb.Frame.\n\
Return the selected frame object." },
  { "frame_stop_reason_string", gdbpy_frame_stop_reason_string, METH_VARARGS,
    "stop_reason_string (Integer) -> String.\n\
Return a string explaining unwind stop reason." },

  { "start_recording", gdbpy_start_recording, METH_VARARGS,
    "start_recording ([method] [, format]) -> gdb.Record.\n\
Start recording with the given method.  If no method is given, will fall back\n\
to the system default method.  If no format is given, will fall back to the\n\
default format for the given method."},
  { "current_recording", gdbpy_current_recording, METH_NOARGS,
    "current_recording () -> gdb.Record.\n\
Return current recording object." },
  { "stop_recording", gdbpy_stop_recording, METH_NOARGS,
    "stop_recording () -> None.\n\
Stop current recording." },

  { "lookup_type", (PyCFunction) gdbpy_lookup_type,
    METH_VARARGS | METH_KEYWORDS,
    "lookup_type (name [, block]) -> type\n\
Return a Type corresponding to the given name." },
  { "lookup_symbol", (PyCFunction) gdbpy_lookup_symbol,
    METH_VARARGS | METH_KEYWORDS,
    "lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)\n\
Return a tuple with the symbol corresponding to the given name (or None) and\n\
a boolean indicating if name is a field of the current implied argument\n\
`this' (when the current language is object-oriented)." },
  { "lookup_global_symbol", (PyCFunction) gdbpy_lookup_global_symbol,
    METH_VARARGS | METH_KEYWORDS,
    "lookup_global_symbol (name [, domain]) -> symbol\n\
Return the symbol corresponding to the given name (or None)." },
  { "lookup_static_symbol", (PyCFunction) gdbpy_lookup_static_symbol,
    METH_VARARGS | METH_KEYWORDS,
    "lookup_static_symbol (name [, domain]) -> symbol\n\
Return the static-linkage symbol corresponding to the given name (or None)." },
  { "lookup_static_symbols", (PyCFunction) gdbpy_lookup_static_symbols,
    METH_VARARGS | METH_KEYWORDS,
    "lookup_static_symbols (name [, domain]) -> symbol\n\
Return a list of all static-linkage symbols corresponding to the given name." },

  { "lookup_objfile", (PyCFunction) gdbpy_lookup_objfile,
    METH_VARARGS | METH_KEYWORDS,
    "lookup_objfile (name, [by_build_id]) -> objfile\n\
Look up the specified objfile.\n\
If by_build_id is True, the objfile is looked up by using name\n\
as its build id." },

  { "decode_line", gdbpy_decode_line, METH_VARARGS,
    "decode_line (String) -> Tuple.  Decode a string argument the way\n\
that 'break' or 'edit' does.  Return a tuple containing two elements.\n\
The first element contains any unparsed portion of the String parameter\n\
(or None if the string was fully parsed).  The second element contains\n\
a tuple that contains all the locations that match, represented as\n\
gdb.Symtab_and_line objects (or None)."},
  { "parse_and_eval", (PyCFunction) gdbpy_parse_and_eval,
    METH_VARARGS | METH_KEYWORDS,
    "parse_and_eval (String, [Boolean]) -> Value.\n\
Parse String as an expression, evaluate it, and return the result as a Value."
  },

  { "post_event", gdbpy_post_event, METH_VARARGS,
    "Post an event into gdb's event loop." },
  { "interrupt", gdbpy_interrupt, METH_NOARGS,
    "Interrupt gdb's current operation." },

  { "target_charset", gdbpy_target_charset, METH_NOARGS,
    "target_charset () -> string.\n\
Return the name of the current target charset." },
  { "target_wide_charset", gdbpy_target_wide_charset, METH_NOARGS,
    "target_wide_charset () -> string.\n\
Return the name of the current target wide charset." },
  { "host_charset", gdbpy_host_charset, METH_NOARGS,
    "host_charset () -> string.\n\
Return the name of the current host charset." },
  { "rbreak", (PyCFunction) gdbpy_rbreak, METH_VARARGS | METH_KEYWORDS,
    "rbreak (Regex) -> List.\n\
Return a Tuple containing gdb.Breakpoint objects that match the given Regex." },
  { "string_to_argv", gdbpy_string_to_argv, METH_VARARGS,
    "string_to_argv (String) -> Array.\n\
Parse String and return an argv-like array.\n\
Arguments are separate by spaces and may be quoted."
  },
  { "write", (PyCFunction)gdbpy_write, METH_VARARGS | METH_KEYWORDS,
    "Write a string using gdb's filtered stream." },
  { "flush", (PyCFunction)gdbpy_flush, METH_VARARGS | METH_KEYWORDS,
    "Flush gdb's filtered stdout stream." },
  { "selected_thread", gdbpy_selected_thread, METH_NOARGS,
    "selected_thread () -> gdb.InferiorThread.\n\
Return the selected thread object." },
  { "selected_inferior", gdbpy_selected_inferior, METH_NOARGS,
    "selected_inferior () -> gdb.Inferior.\n\
Return the selected inferior object." },
  { "inferiors", gdbpy_inferiors, METH_NOARGS,
    "inferiors () -> (gdb.Inferior, ...).\n\
Return a tuple containing all inferiors." },

  { "invalidate_cached_frames", gdbpy_invalidate_cached_frames, METH_NOARGS,
    "invalidate_cached_frames () -> None.\n\
Invalidate any cached frame objects in gdb.\n\
Intended for internal use only." },

  { "convenience_variable", gdbpy_convenience_variable, METH_VARARGS,
    "convenience_variable (NAME) -> value.\n\
Return the value of the convenience variable $NAME,\n\
or None if not set." },
  { "set_convenience_variable", gdbpy_set_convenience_variable, METH_VARARGS,
    "convenience_variable (NAME, VALUE) -> None.\n\
Set the value of the convenience variable $NAME." },

#ifdef TUI
  { "register_window_type", (PyCFunction) gdbpy_register_tui_window,
    METH_VARARGS | METH_KEYWORDS,
    "register_window_type (NAME, CONSTRUCTOR) -> None\n\
Register a TUI window constructor." },
#endif	/* TUI */

  { "architecture_names", gdbpy_all_architecture_names, METH_NOARGS,
    "architecture_names () -> List.\n\
Return a list of all the architecture names GDB understands." },

  { "connections", gdbpy_connections, METH_NOARGS,
    "connections () -> List.\n\
Return a list of gdb.TargetConnection objects." },

  { "format_address", (PyCFunction) gdbpy_format_address,
    METH_VARARGS | METH_KEYWORDS,
    "format_address (ADDRESS, PROG_SPACE, ARCH) -> String.\n\
Format ADDRESS, an address within PROG_SPACE, a gdb.Progspace, using\n\
ARCH, a gdb.Architecture to determine the address size.  The format of\n\
the returned string is 'ADDRESS <SYMBOL+OFFSET>' without the quotes." },

  { "current_language", gdbpy_current_language, METH_NOARGS,
    "current_language () -> string\n\
Return the name of the currently selected language." },

  { "print_options", gdbpy_print_options, METH_NOARGS,
    "print_options () -> dict\n\
Return the current print options." },

  { "notify_mi", (PyCFunction) gdbpy_notify_mi,
    METH_VARARGS | METH_KEYWORDS,
    "notify_mi (name, data) -> None\n\
Output async record to MI channels if any." },

  { "warning", (PyCFunction) gdbpy_warning,
    METH_VARARGS | METH_KEYWORDS,
    "warning (text) -> None\n\
Print a warning." },

  {NULL, NULL, 0, NULL}
};

/* Define all the event objects.  */
#define GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base) \
  PyTypeObject name##_event_object_type \
    = { \
      PyVarObject_HEAD_INIT (NULL, 0)				\
      "gdb." py_name,                             /* tp_name */ \
      sizeof (event_object),                      /* tp_basicsize */ \
      0,                                          /* tp_itemsize */ \
      evpy_dealloc,                               /* tp_dealloc */ \
      0,                                          /* tp_print */ \
      0,                                          /* tp_getattr */ \
      0,                                          /* tp_setattr */ \
      0,                                          /* tp_compare */ \
      0,                                          /* tp_repr */ \
      0,                                          /* tp_as_number */ \
      0,                                          /* tp_as_sequence */ \
      0,                                          /* tp_as_mapping */ \
      0,                                          /* tp_hash  */ \
      0,                                          /* tp_call */ \
      0,                                          /* tp_str */ \
      0,                                          /* tp_getattro */ \
      0,                                          /* tp_setattro */ \
      0,                                          /* tp_as_buffer */ \
      Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /* tp_flags */ \
      doc,                                        /* tp_doc */ \
      0,                                          /* tp_traverse */ \
      0,                                          /* tp_clear */ \
      0,                                          /* tp_richcompare */ \
      0,                                          /* tp_weaklistoffset */ \
      0,                                          /* tp_iter */ \
      0,                                          /* tp_iternext */ \
      0,                                          /* tp_methods */ \
      0,                                          /* tp_members */ \
      0,                                          /* tp_getset */ \
      &base,                                      /* tp_base */ \
      0,                                          /* tp_dict */ \
      0,                                          /* tp_descr_get */ \
      0,                                          /* tp_descr_set */ \
      0,                                          /* tp_dictoffset */ \
      0,                                          /* tp_init */ \
      0                                           /* tp_alloc */ \
    };
#include "py-event-types.def"
#undef GDB_PY_DEFINE_EVENT_TYPE

#endif /* HAVE_PYTHON */
