Simplify exception handling in py-framefilter.c

This patch changes py-framefilter.c as suggested by Pedro in:
https://sourceware.org/ml/gdb-patches/2017-06/msg00748.html

In particular, gdb exceptions are now caught at the outermost layer,
rather than in each particular function.  This simplifies much of the
code.

gdb/ChangeLog
2018-03-26  Tom Tromey  <tom@tromey.com>

	* python/py-framefilter.c (py_print_type): Don't catch
	exceptions.  Return void.
	(py_print_value): Likewise.
	(py_print_single_arg): Likewise.
	(enumerate_args): Don't catch exceptions.
	(py_print_args): Likewise.
	(py_print_frame): Likewise.
	(gdbpy_apply_frame_filter): Catch exceptions here.
This commit is contained in:
Tom Tromey 2018-03-23 10:32:26 -06:00
parent 9507b29c0a
commit 76c939acfd
2 changed files with 174 additions and 401 deletions

View File

@ -1,3 +1,14 @@
2018-03-26 Tom Tromey <tom@tromey.com>
* python/py-framefilter.c (py_print_type): Don't catch
exceptions. Return void.
(py_print_value): Likewise.
(py_print_single_arg): Likewise.
(enumerate_args): Don't catch exceptions.
(py_print_args): Likewise.
(py_print_frame): Likewise.
(gdbpy_apply_frame_filter): Catch exceptions here.
2018-03-26 Tom Tromey <tom@tromey.com> 2018-03-26 Tom Tromey <tom@tromey.com>
* stack.c (_initialize_stack): Remove trailing newlines from help * stack.c (_initialize_stack): Remove trailing newlines from help

View File

@ -199,30 +199,16 @@ mi_should_print (struct symbol *sym, enum mi_print_types type)
/* Helper function which outputs a type name extracted from VAL to a /* 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 "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 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 type will be extracted from. */
any GDB exceptions converted to a Python exception, or EXT_LANG_BT_OK on
success. */
static enum ext_lang_bt_status static void
py_print_type (struct ui_out *out, struct value *val) py_print_type (struct ui_out *out, struct value *val)
{ {
check_typedef (value_type (val));
TRY string_file stb;
{ type_print (value_type (val), "", &stb, -1);
check_typedef (value_type (val)); out->field_stream ("type", stb);
string_file stb;
type_print (value_type (val), "", &stb, -1);
out->field_stream ("type", stb);
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
return EXT_LANG_BT_OK;
} }
/* Helper function which outputs a value to an output field in a /* Helper function which outputs a value to an output field in a
@ -230,11 +216,9 @@ py_print_type (struct ui_out *out, struct value *val)
VAL is the value that will be printed, OPTS contains the value VAL is the value that will be printed, OPTS contains the value
printing options, ARGS_TYPE is an enumerator describing the printing options, ARGS_TYPE is an enumerator describing the
argument format, and LANGUAGE is the language_defn that the value 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 will be printed with. */
exceptions converted to a Python exception, or EXT_LANG_BT_OK on
success. */
static enum ext_lang_bt_status static void
py_print_value (struct ui_out *out, struct value *val, py_print_value (struct ui_out *out, struct value *val,
const struct value_print_options *opts, const struct value_print_options *opts,
int indent, int indent,
@ -249,18 +233,7 @@ py_print_value (struct ui_out *out, struct value *val,
if (args_type == MI_PRINT_SIMPLE_VALUES if (args_type == MI_PRINT_SIMPLE_VALUES
|| args_type == MI_PRINT_ALL_VALUES) || args_type == MI_PRINT_ALL_VALUES)
{ {
struct type *type = NULL; struct type *type = check_typedef (value_type (val));
TRY
{
type = check_typedef (value_type (val));
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
if (args_type == MI_PRINT_ALL_VALUES) if (args_type == MI_PRINT_ALL_VALUES)
should_print = 1; should_print = 1;
@ -275,22 +248,11 @@ py_print_value (struct ui_out *out, struct value *val,
if (should_print) if (should_print)
{ {
TRY string_file stb;
{
string_file stb;
common_val_print (val, &stb, indent, opts, language); common_val_print (val, &stb, indent, opts, language);
out->field_stream ("value", stb); out->field_stream ("value", stb);
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
} }
return EXT_LANG_BT_OK;
} }
/* Helper function to call a Python method and extract an iterator /* Helper function to call a Python method and extract an iterator
@ -338,10 +300,9 @@ get_py_iter_from_func (PyObject *filter, const char *func)
ARGS_TYPE is an enumerator describing the argument format, ARGS_TYPE is an enumerator describing the argument format,
PRINT_ARGS_FIELD is a flag which indicates if we output "ARGS=1" PRINT_ARGS_FIELD is a flag which indicates if we output "ARGS=1"
in MI output in commands where both arguments and locals are in MI output in commands where both arguments and locals are
printed. Returns EXT_LANG_BT_ERROR on error, with any GDB exceptions printed. */
converted to a Python exception, or EXT_LANG_BT_OK on success. */
static enum ext_lang_bt_status static void
py_print_single_arg (struct ui_out *out, py_print_single_arg (struct ui_out *out,
const char *sym_name, const char *sym_name,
struct frame_arg *fa, struct frame_arg *fa,
@ -352,116 +313,97 @@ py_print_single_arg (struct ui_out *out,
const struct language_defn *language) const struct language_defn *language)
{ {
struct value *val; struct value *val;
enum ext_lang_bt_status retval = EXT_LANG_BT_OK;
if (fa != NULL) if (fa != NULL)
{ {
if (fa->val == NULL && fa->error == NULL) if (fa->val == NULL && fa->error == NULL)
return EXT_LANG_BT_OK; return;
language = language_def (SYMBOL_LANGUAGE (fa->sym)); language = language_def (SYMBOL_LANGUAGE (fa->sym));
val = fa->val; val = fa->val;
} }
else else
val = fv; 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 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 exception is -stack-list-variables which emits an ARGS="1" field
if the value is a frame argument. This is denoted in this if the value is a frame argument. This is denoted in this
function with PRINT_ARGS_FIELD which is flag from the caller to function with PRINT_ARGS_FIELD which is flag from the caller to
emit the ARGS field. */ emit the ARGS field. */
if (out->is_mi_like_p ()) if (out->is_mi_like_p ())
{ {
if (print_args_field || args_type != NO_VALUES) if (print_args_field || args_type != NO_VALUES)
maybe_tuple.emplace (out, nullptr); maybe_tuple.emplace (out, nullptr);
} }
annotate_arg_begin (); annotate_arg_begin ();
/* If frame argument is populated, check for entry-values and the /* If frame argument is populated, check for entry-values and the
entry value options. */ entry value options. */
if (fa != NULL) if (fa != NULL)
{
string_file stb;
fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (fa->sym),
SYMBOL_LANGUAGE (fa->sym),
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), fprintf_symbol_filtered (&stb, SYMBOL_PRINT_NAME (fa->sym),
SYMBOL_LANGUAGE (fa->sym), SYMBOL_LANGUAGE (fa->sym),
DMGL_PARAMS | DMGL_ANSI); 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);
annotate_arg_name_end ();
if (! out->is_mi_like_p ())
out->text ("=");
if (print_args_field)
out->field_int ("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;
}
if (retval != EXT_LANG_BT_ERROR)
{
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
{
/* 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;
}
}
} }
if (fa->entry_kind == print_entry_values_only
|| fa->entry_kind == print_entry_values_compact)
stb.puts ("@entry");
out->field_stream ("name", stb);
} }
CATCH (except, RETURN_MASK_ERROR) else
/* Otherwise, just output the name. */
out->field_string ("name", sym_name);
annotate_arg_name_end ();
if (! out->is_mi_like_p ())
out->text ("=");
if (print_args_field)
out->field_int ("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)
py_print_type (out, 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
{ {
gdbpy_convert_exception (except); /* Otherwise, print the value for both MI and the CLI, except
retval = EXT_LANG_BT_ERROR; 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
py_print_value (out, val, opts, 0, args_type, language);
}
} }
END_CATCH
return retval;
} }
/* Helper function to loop over frame arguments provided by the /* Helper function to loop over frame arguments provided by the
@ -494,16 +436,7 @@ enumerate_args (PyObject *iter,
opts.deref_ref = 1; opts.deref_ref = 1;
TRY annotate_frame_args ();
{
annotate_frame_args ();
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
/* Collect the first argument outside of the loop, so output of /* Collect the first argument outside of the loop, so output of
commas in the argument output is correct. At the end of the commas in the argument output is correct. At the end of the
@ -550,16 +483,7 @@ enumerate_args (PyObject *iter,
return EXT_LANG_BT_ERROR; return EXT_LANG_BT_ERROR;
} }
TRY read_frame_arg (sym, frame, &arg, &entryarg);
{
read_frame_arg (sym, frame, &arg, &entryarg);
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
gdb::unique_xmalloc_ptr<char> arg_holder (arg.error); gdb::unique_xmalloc_ptr<char> arg_holder (arg.error);
gdb::unique_xmalloc_ptr<char> entry_holder (entryarg.error); gdb::unique_xmalloc_ptr<char> entry_holder (entryarg.error);
@ -570,47 +494,32 @@ enumerate_args (PyObject *iter,
if (arg.entry_kind != print_entry_values_only) if (arg.entry_kind != print_entry_values_only)
{ {
if (py_print_single_arg (out, NULL, &arg, py_print_single_arg (out, NULL, &arg,
NULL, &opts, NULL, &opts,
args_type, args_type,
print_args_field, print_args_field,
NULL) == EXT_LANG_BT_ERROR) NULL);
return EXT_LANG_BT_ERROR;
} }
if (entryarg.entry_kind != print_entry_values_no) if (entryarg.entry_kind != print_entry_values_no)
{ {
if (arg.entry_kind != print_entry_values_only) if (arg.entry_kind != print_entry_values_only)
{ {
TRY out->text (", ");
{ out->wrap_hint (" ");
out->text (", ");
out->wrap_hint (" ");
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
} }
if (py_print_single_arg (out, NULL, &entryarg, NULL, &opts, py_print_single_arg (out, NULL, &entryarg, NULL, &opts,
args_type, print_args_field, NULL) args_type, print_args_field, NULL);
== EXT_LANG_BT_ERROR)
return EXT_LANG_BT_ERROR;
} }
} }
else else
{ {
/* If the object has provided a value, we just print that. */ /* If the object has provided a value, we just print that. */
if (val != NULL) if (val != NULL)
{ py_print_single_arg (out, sym_name.get (), NULL, val, &opts,
if (py_print_single_arg (out, sym_name.get (), NULL, val, &opts, args_type, print_args_field,
args_type, print_args_field, language);
language) == EXT_LANG_BT_ERROR)
return EXT_LANG_BT_ERROR;
}
} }
/* Collect the next item from the iterator. If /* Collect the next item from the iterator. If
@ -618,31 +527,11 @@ enumerate_args (PyObject *iter,
comma. */ comma. */
item.reset (PyIter_Next (iter)); item.reset (PyIter_Next (iter));
if (item != NULL) if (item != NULL)
{ out->text (", ");
TRY
{
out->text (", ");
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
}
else if (PyErr_Occurred ()) else if (PyErr_Occurred ())
return EXT_LANG_BT_ERROR; return EXT_LANG_BT_ERROR;
TRY annotate_arg_end ();
{
annotate_arg_end ();
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
} }
return EXT_LANG_BT_OK; return EXT_LANG_BT_OK;
@ -703,18 +592,7 @@ enumerate_locals (PyObject *iter,
/* If the object did not provide a value, read it. */ /* If the object did not provide a value, read it. */
if (val == NULL) if (val == NULL)
{ val = read_var_value (sym, sym_block, frame);
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
}
/* With PRINT_NO_VALUES, MI does not emit a tuple normally as /* With PRINT_NO_VALUES, MI does not emit a tuple normally as
each output contains only one field. The exception is each output contains only one field. The exception is
@ -724,31 +602,19 @@ enumerate_locals (PyObject *iter,
if (print_args_field || args_type != NO_VALUES) if (print_args_field || args_type != NO_VALUES)
tuple.emplace (out, nullptr); tuple.emplace (out, nullptr);
} }
TRY if (! out->is_mi_like_p ())
{ {
if (! out->is_mi_like_p ()) /* If the output is not MI we indent locals. */
{ out->spaces (local_indent);
/* 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)
{ out->field_string ("name", sym_name.get ());
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR; if (! out->is_mi_like_p ())
} out->text (" = ");
END_CATCH
if (args_type == MI_PRINT_SIMPLE_VALUES) if (args_type == MI_PRINT_SIMPLE_VALUES)
{ py_print_type (out, val);
if (py_print_type (out, val) == EXT_LANG_BT_ERROR)
return EXT_LANG_BT_ERROR;
}
/* CLI always prints values for locals. MI uses the /* CLI always prints values for locals. MI uses the
simple/no/all system. */ simple/no/all system. */
@ -756,30 +622,17 @@ enumerate_locals (PyObject *iter,
{ {
int val_indent = (indent + 1) * 4; int val_indent = (indent + 1) * 4;
if (py_print_value (out, val, &opts, val_indent, args_type, py_print_value (out, val, &opts, val_indent, args_type,
language) == EXT_LANG_BT_ERROR) language);
return EXT_LANG_BT_ERROR;
} }
else else
{ {
if (args_type != NO_VALUES) if (args_type != NO_VALUES)
{ py_print_value (out, val, &opts, 0, args_type,
if (py_print_value (out, val, &opts, 0, args_type, language);
language) == EXT_LANG_BT_ERROR)
return EXT_LANG_BT_ERROR;
}
} }
TRY out->text ("\n");
{
out->text ("\n");
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
} }
if (!PyErr_Occurred ()) if (!PyErr_Occurred ())
@ -862,36 +715,18 @@ py_print_args (PyObject *filter,
ui_out_emit_list list_emitter (out, "args"); ui_out_emit_list list_emitter (out, "args");
TRY out->wrap_hint (" ");
{ annotate_frame_args ();
out->wrap_hint (" "); if (! out->is_mi_like_p ())
annotate_frame_args (); out->text (" (");
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 (args_iter != Py_None if (args_iter != Py_None
&& (enumerate_args (args_iter.get (), out, args_type, 0, frame) && (enumerate_args (args_iter.get (), out, args_type, 0, frame)
== EXT_LANG_BT_ERROR)) == EXT_LANG_BT_ERROR))
return EXT_LANG_BT_ERROR; return EXT_LANG_BT_ERROR;
TRY if (! out->is_mi_like_p ())
{ out->text (")");
if (! out->is_mi_like_p ())
out->text (")");
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
return EXT_LANG_BT_OK; return EXT_LANG_BT_OK;
} }
@ -944,16 +779,7 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
if (frame == NULL) if (frame == NULL)
return EXT_LANG_BT_ERROR; return EXT_LANG_BT_ERROR;
TRY gdbarch = get_frame_arch (frame);
{
gdbarch = get_frame_arch (frame);
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
/* stack-list-variables. */ /* stack-list-variables. */
if (print_locals && print_args && ! print_frame_info) if (print_locals && print_args && ! print_frame_info)
@ -976,18 +802,7 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
/* Elided frames are also printed with this function (recursively) /* Elided frames are also printed with this function (recursively)
and are printed with indention. */ and are printed with indention. */
if (indent > 0) if (indent > 0)
{ out->spaces (indent * 4);
TRY
{
out->spaces (indent * 4);
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
}
/* The address is required for frame annotations, and also for /* The address is required for frame annotations, and also for
address printing. */ address printing. */
@ -1017,32 +832,24 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
slot = (struct frame_info **) htab_find_slot (levels_printed, slot = (struct frame_info **) htab_find_slot (levels_printed,
frame, INSERT); frame, INSERT);
TRY
{
level = frame_relative_level (frame);
/* Check if this frame has already been printed (there are cases level = frame_relative_level (frame);
where elided synthetic dummy-frames have to 'borrow' the frame
architecture from the eliding frame. If that is the case, do /* Check if this frame has already been printed (there are cases
not print 'level', but print spaces. */ where elided synthetic dummy-frames have to 'borrow' the frame
if (*slot == frame) architecture from the eliding frame. If that is the case, do
out->field_skip ("level"); not print 'level', but print spaces. */
else if (*slot == frame)
{ out->field_skip ("level");
*slot = frame; else
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)
{ {
gdbpy_convert_exception (except); *slot = frame;
return EXT_LANG_BT_ERROR; annotate_frame_begin (print_level ? level : 0,
gdbarch, address);
out->text ("#");
out->field_fmt_int (2, ui_left, "level",
level);
} }
END_CATCH
} }
if (print_frame_info) if (print_frame_info)
@ -1051,19 +858,10 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
print nothing. */ print nothing. */
if (opts.addressprint && has_addr) if (opts.addressprint && has_addr)
{ {
TRY annotate_frame_address ();
{ out->field_core_addr ("addr", gdbarch, address);
annotate_frame_address (); annotate_frame_address_end ();
out->field_core_addr ("addr", gdbarch, address); out->text (" in ");
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. */ /* Print frame function name. */
@ -1104,20 +902,11 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
return EXT_LANG_BT_ERROR; return EXT_LANG_BT_ERROR;
} }
TRY annotate_frame_function_name ();
{ if (function == NULL)
annotate_frame_function_name (); out->field_skip ("func");
if (function == NULL) else
out->field_skip ("func"); out->field_string ("func", function);
else
out->field_string ("func", function);
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
} }
} }
@ -1133,16 +922,7 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
/* File name/source/line number information. */ /* File name/source/line number information. */
if (print_frame_info) if (print_frame_info)
{ {
TRY annotate_frame_source_begin ();
{
annotate_frame_source_begin ();
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
if (PyObject_HasAttrString (filter, "filename")) if (PyObject_HasAttrString (filter, "filename"))
{ {
@ -1159,20 +939,11 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
if (filename == NULL) if (filename == NULL)
return EXT_LANG_BT_ERROR; return EXT_LANG_BT_ERROR;
TRY out->wrap_hint (" ");
{ out->text (" at ");
out->wrap_hint (" "); annotate_frame_source_file ();
out->text (" at "); out->field_string ("file", filename.get ());
annotate_frame_source_file (); annotate_frame_source_file_end ();
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
} }
} }
@ -1190,18 +961,9 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
if (PyErr_Occurred ()) if (PyErr_Occurred ())
return EXT_LANG_BT_ERROR; return EXT_LANG_BT_ERROR;
TRY out->text (":");
{ annotate_frame_source_line ();
out->text (":"); out->field_int ("line", line);
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
} }
} }
} }
@ -1210,17 +972,8 @@ py_print_frame (PyObject *filter, frame_filter_flags flags,
elided frames, so if MI output detected do not send newline. */ elided frames, so if MI output detected do not send newline. */
if (! out->is_mi_like_p ()) if (! out->is_mi_like_p ())
{ {
TRY annotate_frame_end ();
{ out->text ("\n");
annotate_frame_end ();
out->text ("\n");
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
return EXT_LANG_BT_ERROR;
}
END_CATCH
} }
if (print_locals) if (print_locals)
@ -1434,8 +1187,17 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
} }
} }
success = py_print_frame (item.get (), flags, args_type, out, 0, TRY
levels_printed.get ()); {
success = py_print_frame (item.get (), flags, args_type, out, 0,
levels_printed.get ());
}
CATCH (except, RETURN_MASK_ERROR)
{
gdbpy_convert_exception (except);
success = EXT_LANG_BT_ERROR;
}
END_CATCH
/* Do not exit on error printing a single frame. Print the /* Do not exit on error printing a single frame. Print the
error and continue with other frames. */ error and continue with other frames. */