/* Python interface to finish breakpoints
- Copyright (C) 2011-2015 Free Software Foundation, Inc.
+ Copyright (C) 2011-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdbthread.h"
#include "arch-utils.h"
#include "language.h"
-#include "observer.h"
+#include "observable.h"
#include "inferior.h"
#include "block.h"
#include "location.h"
+#include "py-ref.h"
/* Function that is called when a Python finish bp is found out of scope. */
-static char * const outofscope_func = "out_of_scope";
+static const char outofscope_func[] = "out_of_scope";
/* struct implementing the gdb.FinishBreakpoint object by extending
the gdb.Breakpoint class. */
value_object_to_value (self_finishbp->function_value);
struct type *value_type =
type_object_to_type (self_finishbp->return_type);
-
- /* bpfinishpy_init cannot finish into DUMMY_FRAME (throws an error
- in such case) so it is OK to always pass CTX_SAVER as NULL. */
- struct value *ret = get_return_value (function, value_type, NULL);
+ struct value *ret = get_return_value (function, value_type);
if (ret)
{
static int
bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
- static char *keywords[] = { "frame", "internal", NULL };
+ static const char *keywords[] = { "frame", "internal", NULL };
struct finish_breakpoint_object *self_bpfinish =
(struct finish_breakpoint_object *) self;
- int type = bp_breakpoint;
PyObject *frame_obj = NULL;
int thread;
struct frame_info *frame = NULL; /* init for gcc -Wall */
struct frame_id frame_id;
PyObject *internal = NULL;
int internal_bp = 0;
- CORE_ADDR finish_pc, pc;
- char small_buf[100], *p;
+ CORE_ADDR pc;
struct symbol *function;
- if (!PyArg_ParseTupleAndKeywords (args, kwargs, "|OO", keywords,
- &frame_obj, &internal))
+ if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "|OO", keywords,
+ &frame_obj, &internal))
return -1;
TRY
if (PyErr_Occurred ())
return -1;
- thread = pid_to_thread_id (inferior_ptid);
- if (thread == 0)
+ if (inferior_ptid == null_ptid)
{
PyErr_SetString (PyExc_ValueError,
_("No thread currently selected."));
return -1;
}
+ thread = inferior_thread ()->global_num;
+
if (internal)
{
internal_bp = PyObject_IsTrue (internal);
/* Ignore Python errors at this stage. */
self_bpfinish->return_type = type_to_type_object (ret_type);
PyErr_Clear ();
- func_value = read_var_value (function, frame);
+ func_value = read_var_value (function, NULL, frame);
self_bpfinish->function_value =
value_to_value_object (func_value);
PyErr_Clear ();
TRY
{
- struct event_location *location;
- struct cleanup *back_to;
-
/* Set a breakpoint on the return address. */
- finish_pc = get_frame_pc (prev_frame);
- xsnprintf (small_buf, sizeof (small_buf), "*%s", hex_string (finish_pc));
- p = small_buf;
- location = new_linespec_location (&p);
- back_to = make_cleanup_delete_event_location (location);
+ event_location_up location
+ = new_address_location (get_frame_pc (prev_frame), NULL, 0);
create_breakpoint (python_gdbarch,
- location, NULL, thread, NULL,
+ location.get (), NULL, thread, NULL,
0,
1 /*temp_flag*/,
bp_breakpoint,
AUTO_BOOLEAN_TRUE,
&bkpt_breakpoint_ops,
0, 1, internal_bp, 0);
- do_cleanups (back_to);
}
CATCH (except, RETURN_MASK_ALL)
{
if (bpfinish_obj->py_bp.bp->enable_state == bp_enabled
&& PyObject_HasAttrString (py_obj, outofscope_func))
{
- PyObject *meth_result;
-
- meth_result = PyObject_CallMethod (py_obj, outofscope_func, NULL);
+ gdbpy_ref<> meth_result (PyObject_CallMethod (py_obj, outofscope_func,
+ NULL));
if (meth_result == NULL)
gdbpy_print_stack ();
- Py_XDECREF (meth_result);
}
delete_breakpoint (bpfinish_obj->py_bp.bp);
{
struct breakpoint *bp_stopped = (struct breakpoint *) args;
PyObject *py_bp = (PyObject *) b->py_bp_object;
- struct gdbarch *garch = b->gdbarch ? b->gdbarch : get_current_arch ();
/* Trigger out_of_scope if this is a FinishBreakpoint and its frame is
not anymore in the current callstack. */
static void
bpfinishpy_handle_stop (struct bpstats *bs, int print_frame)
{
- struct cleanup *cleanup = ensure_python_env (get_current_arch (),
- current_language);
+ gdbpy_enter enter_py (get_current_arch (), current_language);
iterate_over_breakpoints (bpfinishpy_detect_out_scope_cb,
bs == NULL ? NULL : bs->breakpoint_at);
-
- do_cleanups (cleanup);
}
/* Attached to `exit' notifications, triggers all the necessary out of
static void
bpfinishpy_handle_exit (struct inferior *inf)
{
- struct cleanup *cleanup = ensure_python_env (target_gdbarch (),
- current_language);
+ gdbpy_enter enter_py (target_gdbarch (), current_language);
iterate_over_breakpoints (bpfinishpy_detect_out_scope_cb, NULL);
-
- do_cleanups (cleanup);
}
/* Initialize the Python finish breakpoint code. */
(PyObject *) &finish_breakpoint_object_type) < 0)
return -1;
- observer_attach_normal_stop (bpfinishpy_handle_stop);
- observer_attach_inferior_exit (bpfinishpy_handle_exit);
+ gdb::observers::normal_stop.attach (bpfinishpy_handle_stop);
+ gdb::observers::inferior_exit.attach (bpfinishpy_handle_exit);
return 0;
}
-static PyGetSetDef finish_breakpoint_object_getset[] = {
+static gdb_PyGetSetDef finish_breakpoint_object_getset[] = {
{ "return_value", bpfinishpy_get_returnvalue, NULL,
"gdb.Value object representing the return value, if any. \
None otherwise.", NULL },