[PATCH 2/4] Convert gdbpy_newest_frame and gdbpy_selected_frame to safety API
Tom Tromey <[email protected]>
| Newsgroups | gmane.comp.gdb.patches |
|---|---|
| Message-ID | <[email protected]> |
This convert gdbpy_newest_frame and gdbpy_selected_frame to the Python
safety API. Some extra work was needed in py-inferior.c; note that
the code there is "temporary" -- once event emission is converted, the
try/catch can be removed. Also, a new noargs_function wrapper was
needed.
---
gdb/python/py-frame.c | 44 ++++++++++++++++----------------------------
gdb/python/py-inferior.c | 24 ++++++++++++++++++------
gdb/python/py-safety.h | 21 +++++++++++++++++++++
gdb/python/python-internal.h | 4 ++--
gdb/python/python.c | 8 ++++----
5 files changed, 61 insertions(+), 40 deletions(-)
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index 5c5ff8cf0de..3910f19ef83 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -438,41 +438,29 @@ frame_object::static_link ()
/* Implementation of gdb.newest_frame () -> gdb.Frame.
Returns the newest frame object. */
-PyObject *
-gdbpy_newest_frame (PyObject *self, PyObject *args)
+gdbpy_ref<>
+gdbpy_newest_frame ()
{
- frame_info_ptr frame = NULL;
-
- try
- {
- frame = get_current_frame ();
- }
- catch (const gdb_exception &except)
- {
- return gdbpy_handle_gdb_exception (nullptr, except);
- }
-
- return frame_info_to_frame_object (frame).release ();
+ /* FIXME: Python safety. Convert frame_info_to_frame_object. */
+ gdbpy_ref<> result = frame_info_to_frame_object (get_current_frame ());
+ if (result == nullptr)
+ throw gdb_python_exception ();
+ return result;
}
/* Implementation of gdb.selected_frame () -> gdb.Frame.
Returns the selected frame object. */
-PyObject *
-gdbpy_selected_frame (PyObject *self, PyObject *args)
+gdbpy_ref<>
+gdbpy_selected_frame ()
{
- frame_info_ptr frame = NULL;
-
- try
- {
- frame = get_selected_frame ("No frame is currently selected.");
- }
- catch (const gdb_exception &except)
- {
- return gdbpy_handle_gdb_exception (nullptr, except);
- }
-
- return frame_info_to_frame_object (frame).release ();
+ frame_info_ptr frame
+ = get_selected_frame ("No frame is currently selected.");
+ /* FIXME: Python safety. Convert frame_info_to_frame_object. */
+ gdbpy_ref<> result = frame_info_to_frame_object (frame);
+ if (result == nullptr)
+ throw gdb_python_exception ();
+ return result;
}
/* Implementation of gdb.stop_reason_string (Integer) -> String.
diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
index 426aec31e9e..780f7271c09 100644
--- a/gdb/python/py-inferior.c
+++ b/gdb/python/py-inferior.c
@@ -1023,13 +1023,25 @@ python_context_changed (user_selected_what selection)
}
gdbpy_ref<> frame_obj;
- if (has_stack_frames ())
- frame_obj = gdbpy_ref<> (gdbpy_selected_frame (nullptr, nullptr));
- else
- frame_obj = py_none ();
-
- if (frame_obj == nullptr)
+ /* FIXME: Python safety. Eventually this function will be converted
+ and this try/catch can be removed. */
+ try
+ {
+ if (has_stack_frames ())
+ frame_obj = gdbpy_selected_frame ();
+ else
+ frame_obj = py_none ();
+ }
+ catch (const gdb_python_exception &e)
+ {
+ gdbpy_print_stack ();
+ return;
+ }
+ catch (const gdb_exception &exc)
{
+ /* This is a bit roundabout but we're going to be deleting this
+ code someday anyway. */
+ (void) gdbpy_handle_gdb_exception (nullptr, exc);
gdbpy_print_stack ();
return;
}
diff --git a/gdb/python/py-safety.h b/gdb/python/py-safety.h
index 3294f38c8b6..06324868817 100644
--- a/gdb/python/py-safety.h
+++ b/gdb/python/py-safety.h
@@ -233,6 +233,27 @@ varargs_wrapper (PyObject *self, PyObject *args, PyObject *kw)
} /* namespace safety_details */
+/* Create a PyMethodDef for a no-argument function. It takes the
+ underlying function F as template parameters, and the name and
+ documentation as arguments. The function F is wrapped to call
+ to_python and to catch exceptions per the safety protocol. F
+ should not accept any arguments. */
+template<auto F>
+constexpr PyMethodDef
+noargs_function (const char *name, const char *doc)
+{
+ using namespace safety_details;
+ return {
+ name,
+ [] (PyObject *self, PyObject *args) -> PyObject *
+ {
+ return wrapped_function<F> ();
+ },
+ METH_NOARGS,
+ doc,
+ };
+}
+
/* Create a PyMethodDef for a no-argument method. It takes the
underlying class C and a pointer-to-method M as template
parameters, and the name and documentation as arguments. The
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 5529e9fd4d7..76ccdc6b0c6 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -477,8 +477,8 @@ gdbpy_ref<> gdbpy_lookup_static_symbols (gdbpy_borrowed_ref<> args,
PyObject *gdbpy_start_recording (PyObject *self, PyObject *args);
PyObject *gdbpy_current_recording (PyObject *self, PyObject *args);
PyObject *gdbpy_stop_recording (PyObject *self, PyObject *args);
-PyObject *gdbpy_newest_frame (PyObject *self, PyObject *args);
-PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
+gdbpy_ref<> gdbpy_newest_frame ();
+gdbpy_ref<> gdbpy_selected_frame ();
PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw);
int gdbpy_is_field (PyObject *obj);
PyObject *gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 14c243b135e..72c2d7bb10d 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -3159,12 +3159,12 @@ Arguments (also strings) are passed to the command." },
{ "current_objfile", gdbpy_get_current_objfile, METH_NOARGS,
"Return the current Objfile being loaded, or None." },
- { "newest_frame", gdbpy_newest_frame, METH_NOARGS,
+ noargs_function<gdbpy_newest_frame> ("newest_frame",
"newest_frame () -> gdb.Frame.\n\
-Return the newest frame object." },
- { "selected_frame", gdbpy_selected_frame, METH_NOARGS,
+Return the newest frame object."),
+ noargs_function<gdbpy_selected_frame> ("selected_frame",
"selected_frame () -> gdb.Frame.\n\
-Return the selected frame object." },
+Return the selected frame object."),
{ "frame_stop_reason_string", gdbpy_frame_stop_reason_string, METH_VARARGS,
"stop_reason_string (Integer) -> String.\n\
Return a string explaining unwind stop reason." },
--
2.49.0