Use an accessor function for general_symbol_info::language
[deliverable/binutils-gdb.git] / gdb / python / py-framefilter.c
index 75b055c98c9803eaab26689c9b902812518f87f0..fd03d313e9ea6260e474e1b52f292adee3f0544f 100644 (file)
@@ -1,6 +1,6 @@
 /* Python frame filters
 
-   Copyright (C) 2013-2017 Free Software Foundation, Inc.
+   Copyright (C) 2013-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "python.h"
 #include "ui-out.h"
 #include "valprint.h"
+#include "stack.h"
+#include "source.h"
 #include "annotate.h"
 #include "hashtab.h"
 #include "demangle.h"
 #include "mi/mi-cmds.h"
 #include "python-internal.h"
-#include "py-ref.h"
-#include "common/gdb_optional.h"
+#include "gdbsupport/gdb_optional.h"
+#include "cli/cli-style.h"
 
 enum mi_print_types
 {
@@ -55,7 +57,7 @@ enum mi_print_types
 
 static enum ext_lang_bt_status
 extract_sym (PyObject *obj, gdb::unique_xmalloc_ptr<char> *name,
-            struct symbol **sym, struct block **sym_block,
+            struct symbol **sym, const struct block **sym_block,
             const struct language_defn **language)
 {
   gdbpy_ref<> result (PyObject_CallMethod (obj, "symbol", NULL));
@@ -101,13 +103,13 @@ extract_sym (PyObject *obj, gdb::unique_xmalloc_ptr<char> *name,
 
       /* Duplicate the symbol name, so the caller has consistency
         in garbage collection.  */
-      name->reset (xstrdup (SYMBOL_PRINT_NAME (*sym)));
+      name->reset (xstrdup ((*sym)->print_name ()));
 
       /* If a symbol is specified attempt to determine the language
         from the symbol.  If mode is not "auto", then the language
         has been explicitly set, use that.  */
       if (language_mode == language_mode_auto)
-       *language = language_def (SYMBOL_LANGUAGE (*sym));
+       *language = language_def ((*sym)->language ());
       else
        *language = current_language;
     }
@@ -199,30 +201,16 @@ mi_should_print (struct symbol *sym, enum mi_print_types type)
 /* Helper function which outputs a type name extracted from VAL to a
    "type" field in the output stream OUT.  OUT is the ui-out structure
    the type name will be output too, and VAL is the value that the
-   type will be extracted from.  Returns EXT_LANG_BT_ERROR on error, with
-   any GDB exceptions converted to a Python exception, or EXT_LANG_BT_OK on
-   success.  */
+   type will be extracted from.  */
 
-static enum ext_lang_bt_status
+static void
 py_print_type (struct ui_out *out, struct value *val)
 {
+  check_typedef (value_type (val));
 
-  TRY
-    {
-      check_typedef (value_type (val));
-
-      string_file stb;
-      type_print (value_type (val), "", &stb, -1);
-      out->field_stream ("type", stb);
-    }
-  CATCH (except, RETURN_MASK_ALL)
-    {
-      gdbpy_convert_exception (except);
-      return EXT_LANG_BT_ERROR;
-    }
-  END_CATCH
-
-  return EXT_LANG_BT_OK;
+  string_file stb;
+  type_print (value_type (val), "", &stb, -1);
+  out->field_stream ("type", stb);
 }
 
 /* Helper function which outputs a value to an output field in a
@@ -230,11 +218,9 @@ py_print_type (struct ui_out *out, struct value *val)
    VAL is the value that will be printed, OPTS contains the value
    printing options, ARGS_TYPE is an enumerator describing the
    argument format, and LANGUAGE is the language_defn that the value
-   will be printed with.  Returns EXT_LANG_BT_ERROR on error, with any GDB
-   exceptions converted to a Python exception, or EXT_LANG_BT_OK on
-   success. */
+   will be printed with.  */
 
-static enum ext_lang_bt_status
+static void
 py_print_value (struct ui_out *out, struct value *val,
                const struct value_print_options *opts,
                int indent,
@@ -249,18 +235,7 @@ py_print_value (struct ui_out *out, struct value *val,
   if (args_type == MI_PRINT_SIMPLE_VALUES
       || args_type == MI_PRINT_ALL_VALUES)
     {
-      struct type *type = NULL;
-
-      TRY
-       {
-         type = check_typedef (value_type (val));
-       }
-      CATCH (except, RETURN_MASK_ALL)
-       {
-         gdbpy_convert_exception (except);
-         return EXT_LANG_BT_ERROR;
-       }
-      END_CATCH
+      struct type *type = check_typedef (value_type (val));
 
       if (args_type == MI_PRINT_ALL_VALUES)
        should_print = 1;
@@ -275,22 +250,11 @@ py_print_value (struct ui_out *out, struct value *val,
 
   if (should_print)
     {
-      TRY
-       {
-         string_file stb;
+      string_file stb;
 
-         common_val_print (val, &stb, indent, opts, language);
-         out->field_stream ("value", stb);
-       }
-      CATCH (except, RETURN_MASK_ALL)
-       {
-         gdbpy_convert_exception (except);
-         return EXT_LANG_BT_ERROR;
-       }
-      END_CATCH
+      common_val_print (val, &stb, indent, opts, language);
+      out->field_stream ("value", stb);
     }
-
-  return EXT_LANG_BT_OK;
 }
 
 /* Helper function to call a Python method and extract an iterator
@@ -338,10 +302,9 @@ get_py_iter_from_func (PyObject *filter, const char *func)
     ARGS_TYPE is an enumerator describing the argument format,
     PRINT_ARGS_FIELD is a flag which indicates if we output "ARGS=1"
     in MI output in commands where both arguments and locals are
-    printed.  Returns EXT_LANG_BT_ERROR on error, with any GDB exceptions
-    converted to a Python exception, or EXT_LANG_BT_OK on success.  */
+    printed.  */
 
-static enum ext_lang_bt_status
+static void
 py_print_single_arg (struct ui_out *out,
                     const char *sym_name,
                     struct frame_arg *fa,
@@ -352,115 +315,96 @@ py_print_single_arg (struct ui_out *out,
                     const struct language_defn *language)
 {
   struct value *val;
-  enum ext_lang_bt_status retval = EXT_LANG_BT_OK;
 
   if (fa != NULL)
     {
       if (fa->val == NULL && fa->error == NULL)
-       return EXT_LANG_BT_OK;
-      language = language_def (SYMBOL_LANGUAGE (fa->sym));
+       return;
+      language = language_def (fa->sym->language ());
       val = fa->val;
     }
   else
     val = fv;
 
-  TRY
-    {
-      gdb::optional<ui_out_emit_tuple> maybe_tuple;
+  gdb::optional<ui_out_emit_tuple> maybe_tuple;
 
-      /*  MI has varying rules for tuples, but generally if there is only
+  /*  MI has varying rules for tuples, but generally if there is only
       one element in each item in the list, do not start a tuple.  The
       exception is -stack-list-variables which emits an ARGS="1" field
       if the value is a frame argument.  This is denoted in this
       function with PRINT_ARGS_FIELD which is flag from the caller to
       emit the ARGS field.  */
-      if (out->is_mi_like_p ())
-       {
-         if (print_args_field || args_type != NO_VALUES)
-           maybe_tuple.emplace (out, nullptr);
-       }
+  if (out->is_mi_like_p ())
+    {
+      if (print_args_field || args_type != NO_VALUES)
+       maybe_tuple.emplace (out, nullptr);
+    }
 
-      annotate_arg_begin ();
+  annotate_arg_begin ();
 
-      /* If frame argument is populated, check for entry-values and the
-        entry value options.  */
-      if (fa != NULL)
+  /* If frame argument is populated, check for entry-values and the
+     entry value options.  */
+  if (fa != NULL)
+    {
+      string_file stb;
+
+      fprintf_symbol_filtered (&stb, fa->sym->print_name (),
+                              fa->sym->language (),
+                              DMGL_PARAMS | DMGL_ANSI);
+      if (fa->entry_kind == print_entry_values_compact)
        {
-         string_file stb;
+         stb.puts ("=");
 
-         fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (fa->sym),
-                                  SYMBOL_LANGUAGE (fa->sym),
+         fprintf_symbol_filtered (&stb, fa->sym->print_name (),
+                                  fa->sym->language (),
                                   DMGL_PARAMS | DMGL_ANSI);
-         if (fa->entry_kind == print_entry_values_compact)
-           {
-             stb.puts ("=");
-
-             fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (fa->sym),
-                                      SYMBOL_LANGUAGE (fa->sym),
-                                      DMGL_PARAMS | DMGL_ANSI);
-           }
-         if (fa->entry_kind == print_entry_values_only
-             || fa->entry_kind == print_entry_values_compact)
-           stb.puts ("@entry");
-         out->field_stream ("name", stb);
        }
-      else
-       /* Otherwise, just output the name.  */
-       out->field_string ("name", sym_name);
+      if (fa->entry_kind == print_entry_values_only
+         || fa->entry_kind == print_entry_values_compact)
+       stb.puts ("@entry");
+      out->field_stream ("name", stb);
+    }
+  else
+    /* Otherwise, just output the name.  */
+    out->field_string ("name", sym_name);
 
-      annotate_arg_name_end ();
+  annotate_arg_name_end ();
 
-      if (! out->is_mi_like_p ())
-       out->text ("=");
+  out->text ("=");
 
-      if (print_args_field)
-       out->field_int ("arg", 1);
+  if (print_args_field)
+    out->field_signed ("arg", 1);
 
-      /* For MI print the type, but only for simple values.  This seems
-        weird, but this is how MI choose to format the various output
-        types.  */
-      if (args_type == MI_PRINT_SIMPLE_VALUES && val != NULL)
-       {
-         if (py_print_type (out, val) == EXT_LANG_BT_ERROR)
-           retval = EXT_LANG_BT_ERROR;
-       }
+  /* For MI print the type, but only for simple values.  This seems
+     weird, but this is how MI choose to format the various output
+     types.  */
+  if (args_type == MI_PRINT_SIMPLE_VALUES && val != NULL)
+    py_print_type (out, val);
 
-      if (retval != EXT_LANG_BT_ERROR)
-       {
-         if (val != NULL)
-           annotate_arg_value (value_type (val));
+  if (val != NULL)
+    annotate_arg_value (value_type (val));
 
-         /* If the output is to the CLI, and the user option "set print
-            frame-arguments" is set to none, just output "...".  */
-         if (! out->is_mi_like_p () && args_type == NO_VALUES)
-           out->field_string ("value", "...");
-         else
+  /* If the output is to the CLI, and the user option "set print
+     frame-arguments" is set to none, just output "...".  */
+  if (! out->is_mi_like_p () && args_type == NO_VALUES)
+    out->field_string ("value", "...");
+  else
+    {
+      /* Otherwise, print the value for both MI and the CLI, except
+        for the case of MI_PRINT_NO_VALUES.  */
+      if (args_type != NO_VALUES)
+       {
+         if (val == NULL)
            {
-             /* Otherwise, print the value for both MI and the CLI, except
-                for the case of MI_PRINT_NO_VALUES.  */
-             if (args_type != NO_VALUES)
-               {
-                 if (val == NULL)
-                   {
-                     gdb_assert (fa != NULL && fa->error != NULL);
-                     out->field_fmt ("value",
-                                       _("<error reading variable: %s>"),
-                                       fa->error);
-                   }
-                 else if (py_print_value (out, val, opts, 0, args_type, language)
-                          == EXT_LANG_BT_ERROR)
-                   retval = EXT_LANG_BT_ERROR;
-               }
+             gdb_assert (fa != NULL && fa->error != NULL);
+             out->field_fmt ("value", metadata_style.style (),
+                             _("<error reading variable: %s>"),
+                             fa->error.get ());
            }
+         else
+           py_print_value (out, val, opts, 0, args_type, language);
        }
     }
-  CATCH (except, RETURN_MASK_ERROR)
-    {
-      gdbpy_convert_exception (except);
-    }
-  END_CATCH
-
-  return retval;
 }
 
 /* Helper function to loop over frame arguments provided by the
@@ -493,16 +437,7 @@ enumerate_args (PyObject *iter,
 
   opts.deref_ref = 1;
 
-  TRY
-    {
-      annotate_frame_args ();
-    }
-  CATCH (except, RETURN_MASK_ALL)
-    {
-      gdbpy_convert_exception (except);
-      return EXT_LANG_BT_ERROR;
-    }
-  END_CATCH
+  annotate_frame_args ();
 
   /*  Collect the first argument outside of the loop, so output of
       commas in the argument output is correct.  At the end of the
@@ -517,7 +452,7 @@ enumerate_args (PyObject *iter,
       const struct language_defn *language;
       gdb::unique_xmalloc_ptr<char> sym_name;
       struct symbol *sym;
-      struct block *sym_block;
+      const struct block *sym_block;
       struct value *val;
       enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
 
@@ -549,16 +484,8 @@ enumerate_args (PyObject *iter,
              return EXT_LANG_BT_ERROR;
            }
 
-         TRY
-           {
-             read_frame_arg (sym, frame, &arg, &entryarg);
-           }
-         CATCH (except, RETURN_MASK_ALL)
-           {
-             gdbpy_convert_exception (except);
-             return EXT_LANG_BT_ERROR;
-           }
-         END_CATCH
+         read_frame_arg (user_frame_print_options,
+                         sym, frame, &arg, &entryarg);
 
          /* The object has not provided a value, so this is a frame
             argument to be read by GDB.  In this case we have to
@@ -566,60 +493,32 @@ enumerate_args (PyObject *iter,
 
          if (arg.entry_kind != print_entry_values_only)
            {
-             if (py_print_single_arg (out, NULL, &arg,
-                                      NULL, &opts,
-                                      args_type,
-                                      print_args_field,
-                                      NULL) == EXT_LANG_BT_ERROR)
-               {
-                 xfree (arg.error);
-                 xfree (entryarg.error);
-                 return EXT_LANG_BT_ERROR;
-               }
+             py_print_single_arg (out, NULL, &arg,
+                                  NULL, &opts,
+                                  args_type,
+                                  print_args_field,
+                                  NULL);
            }
 
          if (entryarg.entry_kind != print_entry_values_no)
            {
              if (arg.entry_kind != print_entry_values_only)
                {
-                 TRY
-                   {
-                     out->text (", ");
-                     out->wrap_hint ("    ");
-                   }
-                 CATCH (except, RETURN_MASK_ALL)
-                   {
-                     xfree (arg.error);
-                     xfree (entryarg.error);
-                     gdbpy_convert_exception (except);
-                     return EXT_LANG_BT_ERROR;
-                   }
-                 END_CATCH
+                 out->text (", ");
+                 out->wrap_hint ("    ");
                }
 
-             if (py_print_single_arg (out, NULL, &entryarg, NULL, &opts,
-                                      args_type, print_args_field, NULL)
-                 == EXT_LANG_BT_ERROR)
-               {
-                 xfree (arg.error);
-                 xfree (entryarg.error);
-                 return EXT_LANG_BT_ERROR;
-               }
+             py_print_single_arg (out, NULL, &entryarg, NULL, &opts,
+                                  args_type, print_args_field, NULL);
            }
-
-         xfree (arg.error);
-         xfree (entryarg.error);
        }
       else
        {
          /* If the object has provided a value, we just print that.  */
          if (val != NULL)
-           {
-             if (py_print_single_arg (out, sym_name.get (), NULL, val, &opts,
-                                      args_type, print_args_field,
-                                      language) == EXT_LANG_BT_ERROR)
-               return EXT_LANG_BT_ERROR;
-           }
+           py_print_single_arg (out, sym_name.get (), NULL, val, &opts,
+                                args_type, print_args_field,
+                                language);
        }
 
       /* Collect the next item from the iterator.  If
@@ -627,31 +526,11 @@ enumerate_args (PyObject *iter,
         comma.  */
       item.reset (PyIter_Next (iter));
       if (item != NULL)
-       {
-         TRY
-           {
-             out->text (", ");
-           }
-         CATCH (except, RETURN_MASK_ALL)
-           {
-             gdbpy_convert_exception (except);
-             return EXT_LANG_BT_ERROR;
-           }
-         END_CATCH
-       }
+       out->text (", ");
       else if (PyErr_Occurred ())
        return EXT_LANG_BT_ERROR;
 
-      TRY
-       {
-         annotate_arg_end ();
-       }
-      CATCH (except, RETURN_MASK_ALL)
-       {
-         gdbpy_convert_exception (except);
-         return EXT_LANG_BT_ERROR;
-       }
-      END_CATCH
+      annotate_arg_end ();
     }
 
   return EXT_LANG_BT_OK;
@@ -689,7 +568,7 @@ enumerate_locals (PyObject *iter,
       struct value *val;
       enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
       struct symbol *sym;
-      struct block *sym_block;
+      const struct block *sym_block;
       int local_indent = 8 + (8 * indent);
       gdb::optional<ui_out_emit_tuple> tuple;
 
@@ -712,18 +591,7 @@ enumerate_locals (PyObject *iter,
 
       /* If the object did not provide a value, read it.  */
       if (val == NULL)
-       {
-         TRY
-           {
-             val = read_var_value (sym, sym_block, frame);
-           }
-         CATCH (except, RETURN_MASK_ERROR)
-           {
-             gdbpy_convert_exception (except);
-             return EXT_LANG_BT_ERROR;
-           }
-         END_CATCH
-       }
+       val = read_var_value (sym, sym_block, frame);
 
       /* With PRINT_NO_VALUES, MI does not emit a tuple normally as
         each output contains only one field.  The exception is
@@ -733,31 +601,14 @@ enumerate_locals (PyObject *iter,
          if (print_args_field || args_type != NO_VALUES)
            tuple.emplace (out, nullptr);
        }
-      TRY
-       {
-         if (! out->is_mi_like_p ())
-           {
-             /* If the output is not MI we indent locals.  */
-             out->spaces (local_indent);
-           }
 
-         out->field_string ("name", sym_name.get ());
-
-         if (! out->is_mi_like_p ())
-           out->text (" = ");
-       }
-      CATCH (except, RETURN_MASK_ERROR)
-       {
-         gdbpy_convert_exception (except);
-         return EXT_LANG_BT_ERROR;
-       }
-      END_CATCH
+      /* If the output is not MI we indent locals.  */
+      out->spaces (local_indent);
+      out->field_string ("name", sym_name.get ());
+      out->text (" = ");
 
       if (args_type == MI_PRINT_SIMPLE_VALUES)
-       {
-         if (py_print_type (out, val) == EXT_LANG_BT_ERROR)
-           return EXT_LANG_BT_ERROR;
-       }
+       py_print_type (out, val);
 
       /* CLI always prints values for locals.  MI uses the
         simple/no/all system.  */
@@ -765,30 +616,17 @@ enumerate_locals (PyObject *iter,
        {
          int val_indent = (indent + 1) * 4;
 
-         if (py_print_value (out, val, &opts, val_indent, args_type,
-                             language) == EXT_LANG_BT_ERROR)
-           return EXT_LANG_BT_ERROR;
+         py_print_value (out, val, &opts, val_indent, args_type,
+                         language);
        }
       else
        {
          if (args_type != NO_VALUES)
-           {
-             if (py_print_value (out, val, &opts, 0, args_type,
-                                 language) == EXT_LANG_BT_ERROR)
-               return EXT_LANG_BT_ERROR;
-           }
+           py_print_value (out, val, &opts, 0, args_type,
+                           language);
        }
 
-      TRY
-       {
-         out->text ("\n");
-       }
-      CATCH (except, RETURN_MASK_ERROR)
-       {
-         gdbpy_convert_exception (except);
-         return EXT_LANG_BT_ERROR;
-       }
-      END_CATCH
+      out->text ("\n");
     }
 
   if (!PyErr_Occurred ())
@@ -871,35 +709,28 @@ py_print_args (PyObject *filter,
 
   ui_out_emit_list list_emitter (out, "args");
 
-  TRY
-    {
-      annotate_frame_args ();
-      if (! out->is_mi_like_p ())
-       out->text (" (");
-    }
-  CATCH (except, RETURN_MASK_ALL)
+  out->wrap_hint ("   ");
+  annotate_frame_args ();
+  out->text (" (");
+
+  if (args_type == CLI_PRESENCE)
     {
-      gdbpy_convert_exception (except);
-      return EXT_LANG_BT_ERROR;
-    }
-  END_CATCH
+      if (args_iter != Py_None)
+       {
+         gdbpy_ref<> item (PyIter_Next (args_iter.get ()));
 
-  if (args_iter != Py_None
-      && (enumerate_args (args_iter.get (), out, args_type, 0, frame)
-         == EXT_LANG_BT_ERROR))
+         if (item != NULL)
+           out->text ("...");
+         else if (PyErr_Occurred ())
+           return EXT_LANG_BT_ERROR;
+       }
+    }
+  else if (args_iter != Py_None
+          && (enumerate_args (args_iter.get (), out, args_type, 0, frame)
+              == EXT_LANG_BT_ERROR))
     return EXT_LANG_BT_ERROR;
 
-  TRY
-    {
-      if (! out->is_mi_like_p ())
-       out->text (")");
-    }
-  CATCH (except, RETURN_MASK_ALL)
-    {
-      gdbpy_convert_exception (except);
-      return EXT_LANG_BT_ERROR;
-    }
-  END_CATCH
+  out->text (")");
 
   return EXT_LANG_BT_OK;
 }
@@ -916,11 +747,11 @@ py_print_args (PyObject *filter,
     containing all the frames level that have already been printed.
     If a frame level has been printed, do not print it again (in the
     case of elided frames).  Returns EXT_LANG_BT_ERROR on error, with any
-    GDB exceptions converted to a Python exception, or EXT_LANG_BT_COMPLETED
+    GDB exceptions converted to a Python exception, or EXT_LANG_BT_OK
     on success.  It can also throw an exception RETURN_QUIT.  */
 
 static enum ext_lang_bt_status
-py_print_frame (PyObject *filter, int flags,
+py_print_frame (PyObject *filter, frame_filter_flags flags,
                enum ext_lang_frame_args args_type,
                struct ui_out *out, int indent, htab_t levels_printed)
 {
@@ -929,7 +760,16 @@ py_print_frame (PyObject *filter, int flags,
   struct gdbarch *gdbarch = NULL;
   struct frame_info *frame = NULL;
   struct value_print_options opts;
+
   int print_level, print_frame_info, print_args, print_locals;
+  /* Note that the below default in non-mi mode is the same as the
+     default value for the backtrace command (see the call to print_frame_info
+     in backtrace_command_1).
+     Having the same default ensures that 'bt' and 'bt no-filters'
+     have the same behaviour when some filters exist but do not apply
+     to a frame.  */
+  enum print_what print_what
+    = out->is_mi_like_p () ? LOC_AND_ADDRESS : LOCATION;
   gdb::unique_xmalloc_ptr<char> function_to_free;
 
   /* Extract print settings from FLAGS.  */
@@ -939,6 +779,17 @@ py_print_frame (PyObject *filter, int flags,
   print_locals = (flags & PRINT_LOCALS) ? 1 : 0;
 
   get_user_print_options (&opts);
+  if (print_frame_info)
+  {
+    gdb::optional<enum print_what> user_frame_info_print_what;
+
+    get_user_print_what_frame_info (&user_frame_info_print_what);
+    if (!out->is_mi_like_p () && user_frame_info_print_what.has_value ())
+      {
+       /* Use the specific frame information desired by the user.  */
+       print_what = *user_frame_info_print_what;
+      }
+  }
 
   /* Get the underlying frame.  This is needed to determine GDB
   architecture, and also, in the cases of frame variables/arguments to
@@ -952,16 +803,9 @@ py_print_frame (PyObject *filter, int flags,
   if (frame == NULL)
     return EXT_LANG_BT_ERROR;
 
-  TRY
-    {
-      gdbarch = get_frame_arch (frame);
-    }
-  CATCH (except, RETURN_MASK_ERROR)
-    {
-      gdbpy_convert_exception (except);
-      return EXT_LANG_BT_ERROR;
-    }
-  END_CATCH
+  symtab_and_line sal = find_frame_sal (frame);
+
+  gdbarch = get_frame_arch (frame);
 
   /* stack-list-variables.  */
   if (print_locals && print_args && ! print_frame_info)
@@ -969,7 +813,7 @@ py_print_frame (PyObject *filter, int flags,
       if (py_mi_print_variables (filter, out, &opts,
                                 args_type, frame) == EXT_LANG_BT_ERROR)
        return EXT_LANG_BT_ERROR;
-      return EXT_LANG_BT_COMPLETED;
+      return EXT_LANG_BT_OK;
     }
 
   gdb::optional<ui_out_emit_tuple> tuple;
@@ -984,18 +828,7 @@ py_print_frame (PyObject *filter, int flags,
       /* Elided frames are also printed with this function (recursively)
         and are printed with indention.  */
       if (indent > 0)
-       {
-         TRY
-           {
-             out->spaces (indent * 4);
-           }
-         CATCH (except, RETURN_MASK_ERROR)
-           {
-             gdbpy_convert_exception (except);
-             return EXT_LANG_BT_ERROR;
-           }
-         END_CATCH
-       }
+       out->spaces (indent * 4);
 
       /* The address is required for frame annotations, and also for
         address printing.  */
@@ -1016,62 +849,61 @@ py_print_frame (PyObject *filter, int flags,
        }
     }
 
+  /* For MI, each piece is controlled individually.  */
+  bool location_print = (print_frame_info
+                        && !out->is_mi_like_p ()
+                        && (print_what == LOCATION
+                            || print_what == SRC_AND_LOC
+                            || print_what == LOC_AND_ADDRESS
+                            || print_what == SHORT_LOCATION));
+
   /* Print frame level.  MI does not require the level if
      locals/variables only are being printed.  */
-  if ((print_frame_info || print_args) && print_level)
+  if (print_level
+      && (location_print
+         || (out->is_mi_like_p () && (print_frame_info || print_args))))
     {
       struct frame_info **slot;
       int level;
 
       slot = (struct frame_info **) htab_find_slot (levels_printed,
                                                    frame, INSERT);
-      TRY
-       {
-         level = frame_relative_level (frame);
-
-         /* Check if this frame has already been printed (there are cases
-            where elided synthetic dummy-frames have to 'borrow' the frame
-            architecture from the eliding frame.  If that is the case, do
-            not print 'level', but print spaces.  */
-         if (*slot == frame)
-           out->field_skip ("level");
-         else
-           {
-             *slot = frame;
-             annotate_frame_begin (print_level ? level : 0,
-                                   gdbarch, address);
-             out->text ("#");
-             out->field_fmt_int (2, ui_left, "level",
-                                   level);
-           }
-       }
-      CATCH (except, RETURN_MASK_ERROR)
+
+      level = frame_relative_level (frame);
+
+      /* Check if this frame has already been printed (there are cases
+        where elided synthetic dummy-frames have to 'borrow' the frame
+        architecture from the eliding frame.  If that is the case, do
+        not print 'level', but print spaces.  */
+      if (*slot == frame)
+       out->field_skip ("level");
+      else
        {
-         gdbpy_convert_exception (except);
-         return EXT_LANG_BT_ERROR;
+         *slot = frame;
+         annotate_frame_begin (print_level ? level : 0,
+                               gdbarch, address);
+         out->text ("#");
+         out->field_fmt_signed (2, ui_left, "level", level);
        }
-      END_CATCH
     }
 
-  if (print_frame_info)
+  if (location_print || (out->is_mi_like_p () && print_frame_info))
     {
       /* Print address to the address field.  If an address is not provided,
         print nothing.  */
       if (opts.addressprint && has_addr)
        {
-         TRY
+         if (!sal.symtab
+             || frame_show_address (frame, sal)
+             || print_what == LOC_AND_ADDRESS)
            {
              annotate_frame_address ();
              out->field_core_addr ("addr", gdbarch, address);
+             if (get_frame_pc_masked (frame))
+               out->field_string ("pac", " [PAC]");
              annotate_frame_address_end ();
              out->text (" in ");
            }
-         CATCH (except, RETURN_MASK_ERROR)
-           {
-             gdbpy_convert_exception (except);
-             return EXT_LANG_BT_ERROR;
-           }
-         END_CATCH
        }
 
       /* Print frame function name.  */
@@ -1102,7 +934,7 @@ py_print_frame (PyObject *filter, int flags,
 
              msymbol = lookup_minimal_symbol_by_pc (addr);
              if (msymbol.minsym != NULL)
-               function = MSYMBOL_PRINT_NAME (msymbol.minsym);
+               function = msymbol.minsym->print_name ();
            }
          else if (py_func != Py_None)
            {
@@ -1112,45 +944,30 @@ py_print_frame (PyObject *filter, int flags,
              return EXT_LANG_BT_ERROR;
            }
 
-         TRY
-           {
-             annotate_frame_function_name ();
-             if (function == NULL)
-               out->field_skip ("func");
-             else
-               out->field_string ("func", function);
-           }
-         CATCH (except, RETURN_MASK_ERROR)
-           {
-             gdbpy_convert_exception (except);
-             return EXT_LANG_BT_ERROR;
-           }
-         END_CATCH
+         annotate_frame_function_name ();
+         if (function == NULL)
+           out->field_skip ("func");
+         else
+           out->field_string ("func", function, function_name_style.style ());
        }
     }
 
 
   /* Frame arguments.  Check the result, and error if something went
      wrong.  */
-  if (print_args)
+  if (print_args && (location_print || out->is_mi_like_p ()))
     {
       if (py_print_args (filter, out, args_type, frame) == EXT_LANG_BT_ERROR)
        return EXT_LANG_BT_ERROR;
     }
 
   /* File name/source/line number information.  */
-  if (print_frame_info)
+  bool print_location_source
+    = ((location_print && print_what != SHORT_LOCATION)
+       || (out->is_mi_like_p () && print_frame_info));
+  if (print_location_source)
     {
-      TRY
-       {
-         annotate_frame_source_begin ();
-       }
-      CATCH (except, RETURN_MASK_ERROR)
-       {
-         gdbpy_convert_exception (except);
-         return EXT_LANG_BT_ERROR;
-       }
-      END_CATCH
+      annotate_frame_source_begin ();
 
       if (PyObject_HasAttrString (filter, "filename"))
        {
@@ -1167,20 +984,12 @@ py_print_frame (PyObject *filter, int flags,
              if (filename == NULL)
                return EXT_LANG_BT_ERROR;
 
-             TRY
-               {
-                 out->wrap_hint ("   ");
-                 out->text (" at ");
-                 annotate_frame_source_file ();
-                 out->field_string ("file", filename.get ());
-                 annotate_frame_source_file_end ();
-               }
-             CATCH (except, RETURN_MASK_ERROR)
-               {
-                 gdbpy_convert_exception (except);
-                 return EXT_LANG_BT_ERROR;
-               }
-             END_CATCH
+             out->wrap_hint ("   ");
+             out->text (" at ");
+             annotate_frame_source_file ();
+             out->field_string ("file", filename.get (),
+                                file_name_style.style ());
+             annotate_frame_source_file_end ();
            }
        }
 
@@ -1198,37 +1007,34 @@ py_print_frame (PyObject *filter, int flags,
              if (PyErr_Occurred ())
                return EXT_LANG_BT_ERROR;
 
-             TRY
-               {
-                 out->text (":");
-                 annotate_frame_source_line ();
-                 out->field_int ("line", line);
-               }
-             CATCH (except, RETURN_MASK_ERROR)
-               {
-                 gdbpy_convert_exception (except);
-                 return EXT_LANG_BT_ERROR;
-               }
-             END_CATCH
+             out->text (":");
+             annotate_frame_source_line ();
+             out->field_signed ("line", line);
            }
        }
+      if (out->is_mi_like_p ())
+        out->field_string ("arch",
+                           (gdbarch_bfd_arch_info (gdbarch))->printable_name);
+    }
+
+  bool source_print
+    = (! out->is_mi_like_p ()
+       && (print_what == SRC_LINE || print_what == SRC_AND_LOC));
+  if (source_print)
+    {
+      if (print_location_source)
+       out->text ("\n"); /* Newline after the location source.  */
+      print_source_lines (sal.symtab, sal.line, sal.line + 1, 0);
     }
 
   /* For MI we need to deal with the "children" list population of
      elided frames, so if MI output detected do not send newline.  */
   if (! out->is_mi_like_p ())
     {
-      TRY
-       {
-         annotate_frame_end ();
-         out->text ("\n");
-       }
-      CATCH (except, RETURN_MASK_ERROR)
-       {
-         gdbpy_convert_exception (except);
-         return EXT_LANG_BT_ERROR;
-       }
-      END_CATCH
+      annotate_frame_end ();
+      /* print_source_lines has already printed a newline.  */
+      if (!source_print)
+       out->text ("\n");
     }
 
   if (print_locals)
@@ -1238,39 +1044,38 @@ py_print_frame (PyObject *filter, int flags,
        return EXT_LANG_BT_ERROR;
     }
 
-  {
-    /* Finally recursively print elided frames, if any.  */
-    gdbpy_ref<> elided (get_py_iter_from_func (filter, "elided"));
-    if (elided == NULL)
-      return EXT_LANG_BT_ERROR;
+  if ((flags & PRINT_HIDE) == 0)
+    {
+      /* Finally recursively print elided frames, if any.  */
+      gdbpy_ref<> elided (get_py_iter_from_func (filter, "elided"));
+      if (elided == NULL)
+       return EXT_LANG_BT_ERROR;
 
-    if (elided != Py_None)
-      {
-       PyObject *item;
+      if (elided != Py_None)
+       {
+         PyObject *item;
 
-       ui_out_emit_list inner_list_emiter (out, "children");
+         ui_out_emit_list inner_list_emiter (out, "children");
 
-       if (! out->is_mi_like_p ())
          indent++;
 
-       while ((item = PyIter_Next (elided.get ())))
-         {
-           gdbpy_ref<> item_ref (item);
+         while ((item = PyIter_Next (elided.get ())))
+           {
+             gdbpy_ref<> item_ref (item);
 
-           enum ext_lang_bt_status success = py_print_frame (item, flags,
-                                                             args_type, out,
-                                                             indent,
-                                                             levels_printed);
+             enum ext_lang_bt_status success
+               = py_print_frame (item, flags, args_type, out, indent,
+                                 levels_printed);
 
-           if (success == EXT_LANG_BT_ERROR)
-             return EXT_LANG_BT_ERROR;
-         }
-       if (item == NULL && PyErr_Occurred ())
-         return EXT_LANG_BT_ERROR;
-      }
-  }
+             if (success == EXT_LANG_BT_ERROR)
+               return EXT_LANG_BT_ERROR;
+           }
+         if (item == NULL && PyErr_Occurred ())
+           return EXT_LANG_BT_ERROR;
+       }
+    }
 
-  return EXT_LANG_BT_COMPLETED;
+  return EXT_LANG_BT_OK;
 }
 
 /* Helper function to initiate frame filter invocation at starting
@@ -1328,11 +1133,11 @@ bootstrap_python_frame_filters (struct frame_info *frame,
     format, OUT is the output stream to print.  FRAME_LOW is the
     beginning of the slice of frames to print, and FRAME_HIGH is the
     upper limit of the frames to count.  Returns EXT_LANG_BT_ERROR on error,
-    or EXT_LANG_BT_COMPLETED on success.  */
+    or EXT_LANG_BT_OK on success.  */
 
 enum ext_lang_bt_status
 gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
-                         struct frame_info *frame, int flags,
+                         struct frame_info *frame, frame_filter_flags flags,
                          enum ext_lang_frame_args args_type,
                          struct ui_out *out, int frame_low, int frame_high)
 {
@@ -1342,19 +1147,30 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
   if (!gdb_python_initialized)
     return EXT_LANG_BT_NO_FILTERS;
 
-  TRY
+  try
     {
       gdbarch = get_frame_arch (frame);
     }
-  CATCH (except, RETURN_MASK_ALL)
+  catch (const gdb_exception_error &except)
     {
       /* Let gdb try to print the stack trace.  */
       return EXT_LANG_BT_NO_FILTERS;
     }
-  END_CATCH
 
   gdbpy_enter enter_py (gdbarch, current_language);
 
+  /* When we're limiting the number of frames, be careful to request
+     one extra frame, so that we can print a message if there are more
+     frames.  */
+  int frame_countdown = -1;
+  if ((flags & PRINT_MORE_FRAMES) != 0 && frame_low >= 0 && frame_high >= 0)
+    {
+      ++frame_high;
+      /* This has an extra +1 because it is checked before a frame is
+        printed.  */
+      frame_countdown = frame_high - frame_low + 1;
+    }
+
   gdbpy_ref<> iterable (bootstrap_python_frame_filters (frame, frame_low,
                                                        frame_high));
 
@@ -1373,7 +1189,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
         initialization error.  This return code will trigger a
         default backtrace.  */
 
-      gdbpy_print_stack ();
+      gdbpy_print_stack_or_quit ();
       return EXT_LANG_BT_NO_FILTERS;
     }
 
@@ -1396,19 +1212,40 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
        {
          if (PyErr_Occurred ())
            {
-             gdbpy_print_stack ();
+             gdbpy_print_stack_or_quit ();
              return EXT_LANG_BT_ERROR;
            }
          break;
        }
 
-      success = py_print_frame (item.get (), flags, args_type, out, 0,
-                               levels_printed.get ());
+      if (frame_countdown != -1)
+       {
+         gdb_assert ((flags & PRINT_MORE_FRAMES) != 0);
+         --frame_countdown;
+         if (frame_countdown == 0)
+           {
+             /* We've printed all the frames we were asked to
+                print, but more frames existed.  */
+             printf_filtered (_("(More stack frames follow...)\n"));
+             break;
+           }
+       }
+
+      try
+       {
+         success = py_print_frame (item.get (), flags, args_type, out, 0,
+                                   levels_printed.get ());
+       }
+      catch (const gdb_exception_error &except)
+       {
+         gdbpy_convert_exception (except);
+         success = EXT_LANG_BT_ERROR;
+       }
 
       /* Do not exit on error printing a single frame.  Print the
         error and continue with other frames.  */
       if (success == EXT_LANG_BT_ERROR)
-       gdbpy_print_stack ();
+       gdbpy_print_stack_or_quit ();
     }
 
   return success;
This page took 0.05656 seconds and 4 git commands to generate.