/* Python interface to finish breakpoints
- Copyright (C) 2011-2013 Free Software Foundation, Inc.
+ Copyright (C) 2011-2014 Free Software Foundation, Inc.
This file is part of GDB.
#include "defs.h"
-#include "exceptions.h"
#include "python-internal.h"
#include "breakpoint.h"
#include "frame.h"
#include "inferior.h"
#include "block.h"
-static PyTypeObject finish_breakpoint_object_type;
-
/* Function that is called when a Python finish bp is found out of scope. */
static char * const outofscope_func = "out_of_scope";
struct finish_breakpoint_object
{
/* gdb.Breakpoint base class. */
- breakpoint_object py_bp;
+ gdbpy_breakpoint_object py_bp;
/* gdb.Type object of the value return by the breakpointed function.
May be NULL if no debug information was available or return type
was VOID. */
PyObject *return_value;
};
+static PyTypeObject finish_breakpoint_object_type
+ CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("finish_breakpoint_object");
+
/* Python function to get the 'return_value' attribute of
FinishBreakpoint. */
`return_value', if possible. */
void
-bpfinishpy_pre_stop_hook (struct breakpoint_object *bp_obj)
+bpfinishpy_pre_stop_hook (struct gdbpy_breakpoint_object *bp_obj)
{
struct finish_breakpoint_object *self_finishbp =
(struct finish_breakpoint_object *) bp_obj;
of the gdb.FinishBreakpoint object BP_OBJ. */
void
-bpfinishpy_post_stop_hook (struct breakpoint_object *bp_obj)
+bpfinishpy_post_stop_hook (struct gdbpy_breakpoint_object *bp_obj)
{
volatile struct gdb_exception except;
int type = bp_breakpoint;
PyObject *frame_obj = NULL;
int thread;
- struct frame_info *frame, *prev_frame = NULL;
+ struct frame_info *frame = NULL; /* init for gcc -Wall */
+ struct frame_info *prev_frame = NULL;
struct frame_id frame_id;
PyObject *internal = NULL;
int internal_bp = 0;
&frame_obj, &internal))
return -1;
- /* Default frame to gdb.newest_frame if necessary. */
- if (!frame_obj)
- frame_obj = gdbpy_newest_frame (NULL, NULL);
- else
- Py_INCREF (frame_obj);
-
- frame = frame_object_to_frame_info (frame_obj);
- Py_DECREF (frame_obj);
-
- if (frame == NULL)
- goto invalid_frame;
-
TRY_CATCH (except, RETURN_MASK_ALL)
{
- prev_frame = get_prev_frame (frame);
- if (prev_frame == 0)
- {
- PyErr_SetString (PyExc_ValueError, _("\"FinishBreakpoint\" not " \
- "meaningful in the outermost "\
- "frame."));
- }
- else if (get_frame_type (prev_frame) == DUMMY_FRAME)
- {
- PyErr_SetString (PyExc_ValueError, _("\"FinishBreakpoint\" cannot "\
- "be set on a dummy frame."));
- }
+ /* Default frame to newest frame if necessary. */
+ if (frame_obj == NULL)
+ frame = get_current_frame ();
else
- {
- frame_id = get_frame_id (prev_frame);
- if (frame_id_eq (frame_id, null_frame_id))
- PyErr_SetString (PyExc_ValueError,
- _("Invalid ID for the `frame' object."));
- }
+ frame = frame_object_to_frame_info (frame_obj);
+
+ if (frame == NULL)
+ {
+ PyErr_SetString (PyExc_ValueError,
+ _("Invalid ID for the `frame' object."));
+ }
+ else
+ {
+ prev_frame = get_prev_frame (frame);
+ if (prev_frame == 0)
+ {
+ PyErr_SetString (PyExc_ValueError,
+ _("\"FinishBreakpoint\" not "
+ "meaningful in the outermost "
+ "frame."));
+ }
+ else if (get_frame_type (prev_frame) == DUMMY_FRAME)
+ {
+ PyErr_SetString (PyExc_ValueError,
+ _("\"FinishBreakpoint\" cannot "
+ "be set on a dummy frame."));
+ }
+ else
+ {
+ frame_id = get_frame_id (prev_frame);
+ if (frame_id_eq (frame_id, null_frame_id))
+ PyErr_SetString (PyExc_ValueError,
+ _("Invalid ID for the `frame' object."));
+ }
+ }
}
if (except.reason < 0)
{
if (internal)
{
internal_bp = PyObject_IsTrue (internal);
- if (internal_bp == -1)
+ if (internal_bp == -1)
{
- PyErr_SetString (PyExc_ValueError,
+ PyErr_SetString (PyExc_ValueError,
_("The value of `internal' must be a boolean."));
return -1;
}
0, 1, internal_bp, 0);
}
GDB_PY_SET_HANDLE_EXCEPTION (except);
-
+
self_bpfinish->py_bp.bp->frame_id = frame_id;
self_bpfinish->py_bp.is_finish_bp = 1;
-
+
/* Bind the breakpoint with the current program space. */
self_bpfinish->py_bp.bp->pspace = current_program_space;
return 0;
-
- invalid_frame:
- PyErr_SetString (PyExc_ValueError,
- _("Invalid ID for the `frame' object."));
- return -1;
}
/* Called when GDB notices that the finish breakpoint BP_OBJ is out of
static void
bpfinishpy_out_of_scope (struct finish_breakpoint_object *bpfinish_obj)
{
- breakpoint_object *bp_obj = (breakpoint_object *) bpfinish_obj;
+ gdbpy_breakpoint_object *bp_obj = (gdbpy_breakpoint_object *) bpfinish_obj;
PyObject *py_obj = (PyObject *) bp_obj;
if (bpfinish_obj->py_bp.bp->enable_state == bp_enabled
&& PyObject_HasAttrString (py_obj, outofscope_func))
{
- if (!PyObject_CallMethod (py_obj, outofscope_func, NULL))
- gdbpy_print_stack ();
+ PyObject *meth_result;
+
+ 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. */
if (py_bp != NULL && b->py_bp_object->is_finish_bp)
/* Initialize the Python finish breakpoint code. */
-void
+int
gdbpy_initialize_finishbreakpoints (void)
{
if (PyType_Ready (&finish_breakpoint_object_type) < 0)
- return;
-
- Py_INCREF (&finish_breakpoint_object_type);
- PyModule_AddObject (gdb_module, "FinishBreakpoint",
- (PyObject *) &finish_breakpoint_object_type);
-
+ return -1;
+
+ if (gdb_pymodule_addobject (gdb_module, "FinishBreakpoint",
+ (PyObject *) &finish_breakpoint_object_type) < 0)
+ return -1;
+
observer_attach_normal_stop (bpfinishpy_handle_stop);
observer_attach_inferior_exit (bpfinishpy_handle_exit);
+
+ return 0;
}
static PyGetSetDef finish_breakpoint_object_getset[] = {