/* Python interface to breakpoints
- Copyright (C) 2008-2018 Free Software Foundation, Inc.
+ Copyright (C) 2008-2020 Free Software Foundation, Inc.
This file is part of GDB.
#include "breakpoint.h"
#include "gdbcmd.h"
#include "gdbthread.h"
-#include "observer.h"
+#include "observable.h"
#include "cli/cli-script.h"
#include "ada-lang.h"
#include "arch-utils.h"
if (cmp < 0)
return -1;
- TRY
+ try
{
if (cmp == 1)
enable_breakpoint (self_bp->bp);
else
disable_breakpoint (self_bp->bp);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
GDB_PY_SET_HANDLE_EXCEPTION (except);
}
- END_CATCH
return 0;
}
if (! gdb_py_int_as_long (newvalue, &id))
return -1;
- TRY
+ try
{
valid_id = valid_task_id (id);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
GDB_PY_SET_HANDLE_EXCEPTION (except);
}
- END_CATCH
if (! valid_id)
{
BPPY_REQUIRE_VALID (self_bp);
- TRY
+ try
{
delete_breakpoint (self_bp->bp);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
GDB_PY_HANDLE_EXCEPTION (except);
}
- END_CATCH
Py_RETURN_NONE;
}
if (value < 0)
value = 0;
- TRY
+ try
{
set_ignore_count (self_bp->number, (int) value, 0);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
GDB_PY_SET_HANDLE_EXCEPTION (except);
}
- END_CATCH
return 0;
}
static PyObject *
bppy_get_location (PyObject *self, void *closure)
{
- const char *str;
gdbpy_breakpoint_object *obj = (gdbpy_breakpoint_object *) self;
BPPY_REQUIRE_VALID (obj);
if (obj->bp->type != bp_breakpoint)
Py_RETURN_NONE;
- str = event_location_to_string (obj->bp->location.get ());
+ const char *str = event_location_to_string (obj->bp->location.get ());
if (! str)
str = "";
- return host_string_to_python_string (str);
+ return host_string_to_python_string (str).release ();
}
/* Python function to get the breakpoint expression. */
if (! str)
str = "";
- return host_string_to_python_string (str);
+ return host_string_to_python_string (str).release ();
}
/* Python function to get the condition expression of a breakpoint. */
if (! str)
Py_RETURN_NONE;
- return host_string_to_python_string (str);
+ return host_string_to_python_string (str).release ();
}
/* Returns 0 on success. Returns -1 on error, with a python exception set.
gdb::unique_xmalloc_ptr<char> exp_holder;
const char *exp = NULL;
gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
- struct gdb_exception except = exception_none;
+ struct gdb_exception except;
BPPY_SET_REQUIRE_VALID (self_bp);
exp = exp_holder.get ();
}
- TRY
+ try
{
set_breakpoint_condition (self_bp->bp, exp, 0);
}
- CATCH (ex, RETURN_MASK_ALL)
+ catch (gdb_exception &ex)
{
- except = ex;
+ except = std::move (ex);
}
- END_CATCH
GDB_PY_SET_HANDLE_EXCEPTION (except);
string_file stb;
current_uiout->redirect (&stb);
- TRY
+ try
{
print_command_lines (current_uiout, breakpoint_commands (bp), 0);
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
current_uiout->redirect (NULL);
gdbpy_convert_exception (except);
return NULL;
}
- END_CATCH
current_uiout->redirect (NULL);
- return host_string_to_python_string (stb.c_str ());
+ return host_string_to_python_string (stb.c_str ()).release ();
+}
+
+/* Set the commands attached to a breakpoint. Returns 0 on success.
+ Returns -1 on error, with a python exception set. */
+static int
+bppy_set_commands (PyObject *self, PyObject *newvalue, void *closure)
+{
+ gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
+ struct gdb_exception except;
+
+ BPPY_SET_REQUIRE_VALID (self_bp);
+
+ gdb::unique_xmalloc_ptr<char> commands
+ (python_string_to_host_string (newvalue));
+ if (commands == nullptr)
+ return -1;
+
+ try
+ {
+ bool first = true;
+ char *save_ptr = nullptr;
+ auto reader
+ = [&] ()
+ {
+ const char *result = strtok_r (first ? commands.get () : nullptr,
+ "\n", &save_ptr);
+ first = false;
+ return result;
+ };
+
+ counted_command_line lines = read_command_lines_1 (reader, 1, nullptr);
+ breakpoint_set_commands (self_bp->bp, std::move (lines));
+ }
+ catch (gdb_exception &ex)
+ {
+ except = std::move (ex);
+ }
+
+ GDB_PY_SET_HANDLE_EXCEPTION (except);
+
+ return 0;
}
/* Python function to get the breakpoint type. */
bppy_pending_object->number = -1;
bppy_pending_object->bp = NULL;
- TRY
+ try
{
switch (type)
{
location = new_explicit_location (&explicit_loc);
}
+ const struct breakpoint_ops *ops =
+ breakpoint_ops_for_event_location (location.get (), false);
+
create_breakpoint (python_gdbarch,
location.get (), NULL, -1, NULL,
0,
temporary_bp, bp_breakpoint,
0,
AUTO_BOOLEAN_TRUE,
- &bkpt_breakpoint_ops,
+ ops,
0, 1, internal_bp, 0);
break;
}
error(_("Do not understand breakpoint type to set."));
}
}
- CATCH (except, RETURN_MASK_ALL)
+ catch (const gdb_exception &except)
{
bppy_pending_object = NULL;
- PyErr_Format (except.reason == RETURN_QUIT
- ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
- "%s", except.message);
+ gdbpy_convert_exception (except);
return -1;
}
- END_CATCH
BPPY_SET_REQUIRE_VALID ((gdbpy_breakpoint_object *) self);
return 0;
\f
-static int
-build_bp_list (struct breakpoint *b, void *arg)
+static bool
+build_bp_list (struct breakpoint *b, PyObject *list)
{
- PyObject *list = (PyObject *) arg;
PyObject *bp = (PyObject *) b->py_bp_object;
int iserr = 0;
iserr = PyList_Append (list, bp);
if (iserr == -1)
- return 1;
+ return true;
- return 0;
+ return false;
}
/* Static function to return a tuple holding all breakpoints. */
/* If iterate_over_breakpoints returns non NULL it signals an error
condition. In that case abandon building the list and return
NULL. */
- if (iterate_over_breakpoints (build_bp_list, list.get ()) != NULL)
+ auto callback = [&] (breakpoint *bp)
+ {
+ return build_bp_list(bp, list.get ());
+ };
+ if (iterate_over_breakpoints (callback) != NULL)
return NULL;
return PyList_AsTuple (list.get ());
gdbpy_breakpoint_created (struct breakpoint *bp)
{
gdbpy_breakpoint_object *newbp;
- PyGILState_STATE state;
if (!user_breakpoint_p (bp) && bppy_pending_object == NULL)
return;
&& bp->type != bp_access_watchpoint)
return;
- state = PyGILState_Ensure ();
+ struct gdbarch *garch = bp->gdbarch ? bp->gdbarch : get_current_arch ();
+ gdbpy_enter enter_py (garch, current_language);
if (bppy_pending_object)
{
newbp = bppy_pending_object;
+ Py_INCREF (newbp);
bppy_pending_object = NULL;
}
else
newbp->bp = bp;
newbp->bp->py_bp_object = newbp;
newbp->is_finish_bp = 0;
- Py_INCREF (newbp);
++bppy_live;
}
else
gdb_py_events.breakpoint_created) < 0)
gdbpy_print_stack ();
}
-
- PyGILState_Release (state);
}
/* Callback that is used when a breakpoint is deleted. This will
gdbpy_breakpoint_deleted (struct breakpoint *b)
{
int num = b->number;
- PyGILState_STATE state;
struct breakpoint *bp = NULL;
- state = PyGILState_Ensure ();
bp = get_breakpoint (num);
if (bp)
{
+ struct gdbarch *garch = bp->gdbarch ? bp->gdbarch : get_current_arch ();
+ gdbpy_enter enter_py (garch, current_language);
+
gdbpy_ref<gdbpy_breakpoint_object> bp_obj (bp->py_bp_object);
if (bp_obj != NULL)
{
--bppy_live;
}
}
- PyGILState_Release (state);
}
/* Callback that is used when a breakpoint is modified. */
gdbpy_breakpoint_modified (struct breakpoint *b)
{
int num = b->number;
- PyGILState_STATE state;
struct breakpoint *bp = NULL;
- state = PyGILState_Ensure ();
bp = get_breakpoint (num);
if (bp)
{
+ struct gdbarch *garch = bp->gdbarch ? bp->gdbarch : get_current_arch ();
+ gdbpy_enter enter_py (garch, current_language);
+
PyObject *bp_obj = (PyObject *) bp->py_bp_object;
if (bp_obj)
{
}
}
}
- PyGILState_Release (state);
}
\f
(PyObject *) &breakpoint_object_type) < 0)
return -1;
- observer_attach_breakpoint_created (gdbpy_breakpoint_created);
- observer_attach_breakpoint_deleted (gdbpy_breakpoint_deleted);
- observer_attach_breakpoint_modified (gdbpy_breakpoint_modified);
+ gdb::observers::breakpoint_created.attach (gdbpy_breakpoint_created);
+ gdb::observers::breakpoint_deleted.attach (gdbpy_breakpoint_deleted);
+ gdb::observers::breakpoint_modified.attach (gdbpy_breakpoint_modified);
/* Add breakpoint types constants. */
for (i = 0; pybp_codes[i].name; ++i)
{
- if (PyModule_AddIntConstant (gdb_module,
- /* Cast needed for Python 2.4. */
- (char *) pybp_codes[i].name,
+ if (PyModule_AddIntConstant (gdb_module, pybp_codes[i].name,
pybp_codes[i].code) < 0)
return -1;
}
/* Add watchpoint types constants. */
for (i = 0; pybp_watch_types[i].name; ++i)
{
- if (PyModule_AddIntConstant (gdb_module,
- /* Cast needed for Python 2.4. */
- (char *) pybp_watch_types[i].name,
+ if (PyModule_AddIntConstant (gdb_module, pybp_watch_types[i].name,
pybp_watch_types[i].code) < 0)
return -1;
}
}
}
- return PyObject_GenericSetAttr ((PyObject *)self, name, v);
+ return PyObject_GenericSetAttr (self, name, v);
}
static gdb_PyGetSetDef breakpoint_object_getset[] = {
{ "condition", bppy_get_condition, bppy_set_condition,
"Condition of the breakpoint, as specified by the user,\
or None if no condition set."},
- { "commands", bppy_get_commands, NULL,
+ { "commands", bppy_get_commands, bppy_set_commands,
"Commands of the breakpoint, as specified by the user."},
{ "type", bppy_get_type, NULL,
"Type of breakpoint."},