/* Python frame filters
- Copyright (C) 2013-2014 Free Software Foundation, Inc.
+ Copyright (C) 2013-2015 Free Software Foundation, Inc.
This file is part of GDB.
#include "objfiles.h"
#include "symtab.h"
#include "language.h"
-#include "exceptions.h"
#include "arch-utils.h"
#include "python.h"
#include "ui-out.h"
else
val = fv;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
/* If the object did not provide a value, read it. */
if (val == NULL)
{
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
val = read_var_value (sym, frame);
}
if (print_args_field || args_type != NO_VALUES)
make_cleanup_ui_out_tuple_begin_end (out, NULL);
}
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
if (! ui_out_is_mi_like_p (out))
{
do_cleanups (locals_cleanups);
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
ui_out_text (out, "\n");
}
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
- on success. */
+ on success. It can also throw an exception RETURN_QUIT. */
static enum ext_lang_bt_status
py_print_frame (PyObject *filter, int flags,
CORE_ADDR address = 0;
struct gdbarch *gdbarch = NULL;
struct frame_info *frame = NULL;
- struct cleanup *cleanup_stack = make_cleanup (null_cleanup, NULL);
+ struct cleanup *cleanup_stack;
struct value_print_options opts;
- PyObject *py_inf_frame, *elided;
+ PyObject *py_inf_frame;
int print_level, print_frame_info, print_args, print_locals;
volatile struct gdb_exception except;
read them if they returned filter object requires us to do so. */
py_inf_frame = PyObject_CallMethod (filter, "inferior_frame", NULL);
if (py_inf_frame == NULL)
- goto error;
+ return EXT_LANG_BT_ERROR;
frame = frame_object_to_frame_info (py_inf_frame);;
Py_DECREF (py_inf_frame);
if (frame == NULL)
- goto error;
+ return EXT_LANG_BT_ERROR;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
gdbarch = get_frame_arch (frame);
}
if (except.reason < 0)
{
gdbpy_convert_exception (except);
- goto error;
+ return EXT_LANG_BT_ERROR;
}
-
/* stack-list-variables. */
if (print_locals && print_args && ! print_frame_info)
{
if (py_mi_print_variables (filter, out, &opts,
args_type, frame) == EXT_LANG_BT_ERROR)
- goto error;
- else
- {
- do_cleanups (cleanup_stack);
- return EXT_LANG_BT_COMPLETED;
- }
+ return EXT_LANG_BT_ERROR;
+ return EXT_LANG_BT_COMPLETED;
}
+ cleanup_stack = make_cleanup (null_cleanup, NULL);
+
/* -stack-list-locals does not require a
wrapping frame attribute. */
if (print_frame_info || (print_args && ! print_locals))
and are printed with indention. */
if (indent > 0)
{
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- ui_out_spaces (out, indent*4);
- }
- if (except.reason < 0)
- {
- gdbpy_convert_exception (except);
- goto error;
- }
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ ui_out_spaces (out, indent*4);
+ }
+ if (except.reason < 0)
+ {
+ gdbpy_convert_exception (except);
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
}
/* The address is required for frame annotations, and also for
if (PyObject_HasAttrString (filter, "address"))
{
PyObject *paddr = PyObject_CallMethod (filter, "address", NULL);
- if (paddr != NULL)
+
+ if (paddr == NULL)
{
- if (paddr != Py_None)
- {
- address = PyLong_AsLong (paddr);
- has_addr = 1;
- }
- Py_DECREF (paddr);
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
}
- else
- goto error;
+
+ if (paddr != Py_None)
+ {
+ address = PyLong_AsLong (paddr);
+ has_addr = 1;
+ }
+ Py_DECREF (paddr);
}
}
slot = (struct frame_info **) htab_find_slot (levels_printed,
frame, INSERT);
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
level = frame_relative_level (frame);
if (except.reason < 0)
{
gdbpy_convert_exception (except);
- goto error;
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
}
}
print nothing. */
if (opts.addressprint && has_addr)
{
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
annotate_frame_address ();
ui_out_field_core_addr (out, "addr", gdbarch, address);
if (except.reason < 0)
{
gdbpy_convert_exception (except);
- goto error;
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
}
}
if (PyObject_HasAttrString (filter, "function"))
{
PyObject *py_func = PyObject_CallMethod (filter, "function", NULL);
+ struct cleanup *py_func_cleanup;
+ const char *function = NULL;
- if (py_func != NULL)
+ if (py_func == NULL)
{
- const char *function = NULL;
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
+ py_func_cleanup = make_cleanup_py_decref (py_func);
- if (gdbpy_is_string (py_func))
- {
- char *function_to_free = NULL;
+ if (gdbpy_is_string (py_func))
+ {
+ char *function_to_free;
- function = function_to_free =
- python_string_to_host_string (py_func);
+ function = function_to_free =
+ python_string_to_host_string (py_func);
- if (function == NULL)
- {
- Py_DECREF (py_func);
- goto error;
- }
- make_cleanup (xfree, function_to_free);
- }
- else if (PyLong_Check (py_func))
+ if (function == NULL)
{
- CORE_ADDR addr = PyLong_AsUnsignedLongLong (py_func);
- struct bound_minimal_symbol msymbol;
-
- if (PyErr_Occurred ())
- goto error;
-
- msymbol = lookup_minimal_symbol_by_pc (addr);
- if (msymbol.minsym != NULL)
- function = MSYMBOL_PRINT_NAME (msymbol.minsym);
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
}
- else if (py_func != Py_None)
+ make_cleanup (xfree, function_to_free);
+ }
+ else if (PyLong_Check (py_func))
+ {
+ CORE_ADDR addr = PyLong_AsUnsignedLongLong (py_func);
+ struct bound_minimal_symbol msymbol;
+
+ if (PyErr_Occurred ())
{
- PyErr_SetString (PyExc_RuntimeError,
- _("FrameDecorator.function: expecting a " \
- "String, integer or None."));
- Py_DECREF (py_func);
- goto error;
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
}
+ msymbol = lookup_minimal_symbol_by_pc (addr);
+ if (msymbol.minsym != NULL)
+ function = MSYMBOL_PRINT_NAME (msymbol.minsym);
+ }
+ else if (py_func != Py_None)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("FrameDecorator.function: expecting a " \
+ "String, integer or None."));
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- annotate_frame_function_name ();
- if (function == NULL)
- ui_out_field_skip (out, "func");
- else
- ui_out_field_string (out, "func", function);
- }
- if (except.reason < 0)
- {
- Py_DECREF (py_func);
- gdbpy_convert_exception (except);
- goto error;
- }
- Py_DECREF (py_func);
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ annotate_frame_function_name ();
+ if (function == NULL)
+ ui_out_field_skip (out, "func");
+ else
+ ui_out_field_string (out, "func", function);
}
- else
- goto error;
+ if (except.reason < 0)
+ {
+ gdbpy_convert_exception (except);
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
+ do_cleanups (py_func_cleanup);
}
}
if (print_args)
{
if (py_print_args (filter, out, args_type, frame) == EXT_LANG_BT_ERROR)
- goto error;
+ {
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
}
/* File name/source/line number information. */
if (print_frame_info)
{
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
annotate_frame_source_begin ();
}
if (except.reason < 0)
{
gdbpy_convert_exception (except);
- goto error;
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
}
if (PyObject_HasAttrString (filter, "filename"))
{
- PyObject *py_fn = PyObject_CallMethod (filter, "filename",
- NULL);
- if (py_fn != NULL)
+ PyObject *py_fn = PyObject_CallMethod (filter, "filename", NULL);
+ struct cleanup *py_fn_cleanup;
+
+ if (py_fn == NULL)
{
- if (py_fn != Py_None)
- {
- char *filename = python_string_to_host_string (py_fn);
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
+ py_fn_cleanup = make_cleanup_py_decref (py_fn);
- if (filename == NULL)
- {
- Py_DECREF (py_fn);
- goto error;
- }
+ if (py_fn != Py_None)
+ {
+ char *filename = python_string_to_host_string (py_fn);
- make_cleanup (xfree, filename);
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- ui_out_wrap_hint (out, " ");
- ui_out_text (out, " at ");
- annotate_frame_source_file ();
- ui_out_field_string (out, "file", filename);
- annotate_frame_source_file_end ();
- }
- if (except.reason < 0)
- {
- Py_DECREF (py_fn);
- gdbpy_convert_exception (except);
- goto error;
- }
+ if (filename == NULL)
+ {
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
+
+ make_cleanup (xfree, filename);
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ ui_out_wrap_hint (out, " ");
+ ui_out_text (out, " at ");
+ annotate_frame_source_file ();
+ ui_out_field_string (out, "file", filename);
+ annotate_frame_source_file_end ();
+ }
+ if (except.reason < 0)
+ {
+ gdbpy_convert_exception (except);
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
}
- Py_DECREF (py_fn);
}
- else
- goto error;
+ do_cleanups (py_fn_cleanup);
}
if (PyObject_HasAttrString (filter, "line"))
{
PyObject *py_line = PyObject_CallMethod (filter, "line", NULL);
+ struct cleanup *py_line_cleanup;
int line;
- if (py_line != NULL)
+ if (py_line == NULL)
{
- if (py_line != Py_None)
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
+ py_line_cleanup = make_cleanup_py_decref (py_line);
+
+ if (py_line != Py_None)
+ {
+ line = PyLong_AsLong (py_line);
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
- line = PyLong_AsLong (py_line);
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- ui_out_text (out, ":");
- annotate_frame_source_line ();
- ui_out_field_int (out, "line", line);
- }
- if (except.reason < 0)
- {
- Py_DECREF (py_line);
- gdbpy_convert_exception (except);
- goto error;
- }
+ ui_out_text (out, ":");
+ annotate_frame_source_line ();
+ ui_out_field_int (out, "line", line);
+ }
+ if (except.reason < 0)
+ {
+ gdbpy_convert_exception (except);
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
}
- Py_DECREF (py_line);
}
- else
- goto error;
+ do_cleanups (py_line_cleanup);
}
}
elided frames, so if MI output detected do not send newline. */
if (! ui_out_is_mi_like_p (out))
{
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
annotate_frame_end ();
ui_out_text (out, "\n");
if (except.reason < 0)
{
gdbpy_convert_exception (except);
- goto error;
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
}
}
{
if (py_print_locals (filter, out, args_type, indent,
frame) == EXT_LANG_BT_ERROR)
- goto error;
+ {
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
}
- /* Finally recursively print elided frames, if any. */
- elided = get_py_iter_from_func (filter, "elided");
- if (elided == NULL)
- goto error;
+ {
+ PyObject *elided;
+ struct cleanup *elided_cleanup;
- make_cleanup_py_decref (elided);
- if (elided != Py_None)
- {
- PyObject *item;
+ /* Finally recursively print elided frames, if any. */
+ elided = get_py_iter_from_func (filter, "elided");
+ if (elided == NULL)
+ {
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
+ elided_cleanup = make_cleanup_py_decref (elided);
- make_cleanup_ui_out_list_begin_end (out, "children");
+ if (elided != Py_None)
+ {
+ PyObject *item;
- if (! ui_out_is_mi_like_p (out))
- indent++;
+ make_cleanup_ui_out_list_begin_end (out, "children");
- while ((item = PyIter_Next (elided)))
- {
- enum ext_lang_bt_status success = py_print_frame (item, flags,
- args_type, out,
- indent,
- levels_printed);
+ if (! ui_out_is_mi_like_p (out))
+ indent++;
- if (success == EXT_LANG_BT_ERROR)
- {
- Py_DECREF (item);
- goto error;
- }
+ while ((item = PyIter_Next (elided)))
+ {
+ struct cleanup *item_cleanup = make_cleanup_py_decref (item);
- Py_DECREF (item);
- }
- if (item == NULL && PyErr_Occurred ())
- goto error;
- }
+ enum ext_lang_bt_status success = py_print_frame (item, flags,
+ args_type, out,
+ indent,
+ levels_printed);
+ do_cleanups (item_cleanup);
- do_cleanups (cleanup_stack);
- return EXT_LANG_BT_COMPLETED;
+ if (success == EXT_LANG_BT_ERROR)
+ {
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
+ }
+ if (item == NULL && PyErr_Occurred ())
+ {
+ do_cleanups (cleanup_stack);
+ return EXT_LANG_BT_ERROR;
+ }
+ }
+ do_cleanups (elided_cleanup);
+ }
- error:
do_cleanups (cleanup_stack);
- return EXT_LANG_BT_ERROR;
+ return EXT_LANG_BT_COMPLETED;
}
/* Helper function to initiate frame filter invocation at starting
while ((item = PyIter_Next (iterable)))
{
+ struct cleanup *item_cleanup = make_cleanup_py_decref (item);
+
success = py_print_frame (item, flags, args_type, out, 0,
levels_printed);
+ do_cleanups (item_cleanup);
+
/* 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 ();
-
- Py_DECREF (item);
}
if (item == NULL && PyErr_Occurred ())