Introduce htab_up and use gdbpy_enter in py-framefilter.c

This introduces a new "htab_up" typedef, which is a std::unique_ptr
that can call htab_delete.  Then it changes some code in
py-framefilter.c to use both gdbpy_enter and the new htab_up.

2017-01-10  Tom Tromey  <tom@tromey.com>

	* utils.h (htab_deleter): New struct.
	(htab_up): New typedef.
	* python/py-framefilter.c (gdbpy_apply_frame_filter): Use
	gdbpy_enter, gdbpy_ref, htab_up.
This commit is contained in:
Tom Tromey
2016-11-08 11:11:55 -07:00
parent c0171de646
commit 6349f452e0
3 changed files with 42 additions and 36 deletions

View File

@ -1,3 +1,10 @@
2017-01-10 Tom Tromey <tom@tromey.com>
* utils.h (htab_deleter): New struct.
(htab_up): New typedef.
* python/py-framefilter.c (gdbpy_apply_frame_filter): Use
gdbpy_enter, gdbpy_ref, htab_up.
2017-01-10 Tom Tromey <tom@tromey.com> 2017-01-10 Tom Tromey <tom@tromey.com>
* python/py-unwind.c (pending_frame_invalidate): Remove. * python/py-unwind.c (pending_frame_invalidate): Remove.

View File

@ -1491,11 +1491,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
struct ui_out *out, int frame_low, int frame_high) struct ui_out *out, int frame_low, int frame_high)
{ {
struct gdbarch *gdbarch = NULL; struct gdbarch *gdbarch = NULL;
struct cleanup *cleanups;
enum ext_lang_bt_status success = EXT_LANG_BT_ERROR; enum ext_lang_bt_status success = EXT_LANG_BT_ERROR;
PyObject *iterable;
PyObject *item;
htab_t levels_printed;
if (!gdb_python_initialized) if (!gdb_python_initialized)
return EXT_LANG_BT_NO_FILTERS; return EXT_LANG_BT_NO_FILTERS;
@ -1511,9 +1507,10 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
} }
END_CATCH END_CATCH
cleanups = ensure_python_env (gdbarch, current_language); gdbpy_enter enter_py (gdbarch, current_language);
iterable = bootstrap_python_frame_filters (frame, frame_low, frame_high); gdbpy_ref iterable (bootstrap_python_frame_filters (frame, frame_low,
frame_high));
if (iterable == NULL) if (iterable == NULL)
{ {
@ -1531,34 +1528,36 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
default backtrace. */ default backtrace. */
gdbpy_print_stack (); gdbpy_print_stack ();
do_cleanups (cleanups);
return EXT_LANG_BT_NO_FILTERS; return EXT_LANG_BT_NO_FILTERS;
} }
/* If iterable is None, then there are no frame filters registered. /* If iterable is None, then there are no frame filters registered.
If this is the case, defer to default GDB printing routines in MI If this is the case, defer to default GDB printing routines in MI
and CLI. */ and CLI. */
make_cleanup_py_decref (iterable);
if (iterable == Py_None) if (iterable == Py_None)
{ return EXT_LANG_BT_NO_FILTERS;
success = EXT_LANG_BT_NO_FILTERS;
goto done;
}
levels_printed = htab_create (20, htab_up levels_printed (htab_create (20,
htab_hash_pointer, htab_hash_pointer,
htab_eq_pointer, htab_eq_pointer,
NULL); NULL));
make_cleanup_htab_delete (levels_printed);
while ((item = PyIter_Next (iterable))) while (true)
{ {
struct cleanup *item_cleanup = make_cleanup_py_decref (item); gdbpy_ref item (PyIter_Next (iterable.get ()));
success = py_print_frame (item, flags, args_type, out, 0, if (item == NULL)
levels_printed); {
if (PyErr_Occurred ())
{
gdbpy_print_stack ();
return EXT_LANG_BT_ERROR;
}
break;
}
do_cleanups (item_cleanup); success = py_print_frame (item.get (), flags, args_type, out, 0,
levels_printed.get ());
/* 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. */
@ -1566,17 +1565,5 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
gdbpy_print_stack (); gdbpy_print_stack ();
} }
if (item == NULL && PyErr_Occurred ())
goto error;
done:
do_cleanups (cleanups);
return success; return success;
/* Exit and abandon backtrace on error, printing the exception that
is set. */
error:
gdbpy_print_stack ();
do_cleanups (cleanups);
return EXT_LANG_BT_ERROR;
} }

View File

@ -100,6 +100,18 @@ extern struct cleanup *make_cleanup_free_so (struct so_list *so);
extern struct cleanup *make_cleanup_restore_current_language (void); extern struct cleanup *make_cleanup_restore_current_language (void);
/* A deleter for a hash table. */
struct htab_deleter
{
void operator() (htab *ptr) const
{
htab_delete (ptr);
}
};
/* A unique_ptr wrapper for htab_t. */
typedef std::unique_ptr<htab, htab_deleter> htab_up;
extern struct cleanup *make_cleanup_htab_delete (htab_t htab); extern struct cleanup *make_cleanup_htab_delete (htab_t htab);
struct parser_state; struct parser_state;