Index: gdb/python/py-finishbreakpoint.c |
diff --git a/gdb/python/py-finishbreakpoint.c b/gdb/python/py-finishbreakpoint.c |
index 56ab77525c0fdaaf503df569fd5071bada3734cd..394ac1ed5c0cd767e8113b700c18330b20074b51 100644 |
--- a/gdb/python/py-finishbreakpoint.c |
+++ b/gdb/python/py-finishbreakpoint.c |
@@ -1,6 +1,6 @@ |
/* Python interface to finish breakpoints |
- Copyright (C) 2011-2012 Free Software Foundation, Inc. |
+ Copyright (C) 2011-2013 Free Software Foundation, Inc. |
This file is part of GDB. |
@@ -31,8 +31,6 @@ |
#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"; |
@@ -41,7 +39,7 @@ 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. */ |
@@ -55,6 +53,9 @@ struct finish_breakpoint_object |
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. */ |
@@ -89,7 +90,7 @@ bpfinishpy_dealloc (PyObject *self) |
`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; |
@@ -132,7 +133,7 @@ bpfinishpy_pre_stop_hook (struct 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; |
@@ -160,7 +161,8 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs) |
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; |
@@ -173,39 +175,43 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs) |
&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) |
{ |
@@ -226,9 +232,9 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs) |
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; |
} |
@@ -297,19 +303,14 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs) |
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 |
@@ -319,14 +320,18 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs) |
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); |
@@ -342,7 +347,7 @@ bpfinishpy_detect_out_scope_cb (struct breakpoint *b, void *args) |
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) |
@@ -392,7 +397,7 @@ bpfinishpy_handle_stop (struct bpstats *bs, int print_frame) |
static void |
bpfinishpy_handle_exit (struct inferior *inf) |
{ |
- struct cleanup *cleanup = ensure_python_env (target_gdbarch, |
+ struct cleanup *cleanup = ensure_python_env (target_gdbarch (), |
current_language); |
iterate_over_breakpoints (bpfinishpy_detect_out_scope_cb, NULL); |
@@ -402,18 +407,20 @@ bpfinishpy_handle_exit (struct inferior *inf) |
/* 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[] = { |
@@ -425,8 +432,7 @@ None otherwise.", NULL }, |
static PyTypeObject finish_breakpoint_object_type = |
{ |
- PyObject_HEAD_INIT (NULL) |
- 0, /*ob_size*/ |
+ PyVarObject_HEAD_INIT (NULL, 0) |
"gdb.FinishBreakpoint", /*tp_name*/ |
sizeof (struct finish_breakpoint_object), /*tp_basicsize*/ |
0, /*tp_itemsize*/ |