diff options
author | Tom Tromey <tromey@adacore.com> | 2023-11-03 13:23:41 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2023-12-11 10:51:32 -0700 |
commit | e187e7c9696fbf66cf25d5fb8113bc3bc06b9e8b (patch) | |
tree | db8bf8c6a14650905a6831cb35de0fea3e504510 /gdb/python/py-stopevent.c | |
parent | f2e2493b1f892bd377b772307c5ad37bdcda4e12 (diff) | |
download | gdb-e187e7c9696fbf66cf25d5fb8113bc3bc06b9e8b.zip gdb-e187e7c9696fbf66cf25d5fb8113bc3bc06b9e8b.tar.gz gdb-e187e7c9696fbf66cf25d5fb8113bc3bc06b9e8b.tar.bz2 |
Emit stop reason details in Python stop events
This changes Python stop events to carry a "details" dictionary, that
holds any relevant information about the stop. The details are
constructed using more or less the same procedure as is done for MI.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=13587
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Diffstat (limited to 'gdb/python/py-stopevent.c')
-rw-r--r-- | gdb/python/py-stopevent.c | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/gdb/python/py-stopevent.c b/gdb/python/py-stopevent.c index 0aa9d53..f395e8c 100644 --- a/gdb/python/py-stopevent.c +++ b/gdb/python/py-stopevent.c @@ -19,12 +19,61 @@ #include "defs.h" #include "py-stopevent.h" +#include "py-uiout.h" gdbpy_ref<> -create_stop_event_object (PyTypeObject *py_type) +create_stop_event_object (PyTypeObject *py_type, const gdbpy_ref<> &dict) { gdbpy_ref<> thread = py_get_event_thread (inferior_ptid); - return create_thread_event_object (py_type, thread.get ()); + if (thread == nullptr) + return nullptr; + + gdbpy_ref<> result = create_thread_event_object (py_type, thread.get ()); + if (result == nullptr) + return nullptr; + + if (evpy_add_attribute (result.get (), "details", dict.get ()) < 0) + return nullptr; + + return result; +} + +/* Print BPSTAT to a new Python dictionary. Returns the dictionary, + or null if a Python exception occurred. */ + +static gdbpy_ref<> +py_print_bpstat (bpstat *bs, enum gdb_signal stop_signal) +{ + py_ui_out uiout; + + try + { + scoped_restore save_uiout = make_scoped_restore (¤t_uiout, &uiout); + + thread_info *tp = inferior_thread (); + if (tp->thread_fsm () != nullptr && tp->thread_fsm ()->finished_p ()) + { + async_reply_reason reason = tp->thread_fsm ()->async_reply_reason (); + uiout.field_string ("reason", async_reason_lookup (reason)); + } + + if (stop_signal != GDB_SIGNAL_0 && stop_signal != GDB_SIGNAL_TRAP) + print_signal_received_reason (&uiout, stop_signal); + else + { + struct target_waitstatus last; + get_last_target_status (nullptr, nullptr, &last); + + bpstat_print (bs, last.kind ()); + } + } + catch (const gdb_exception &except) + { + gdbpy_convert_exception (except); + return nullptr; + } + + return uiout.result (); } /* Callback observers when a stop event occurs. This function will create a @@ -45,6 +94,10 @@ emit_stop_event (struct bpstat *bs, enum gdb_signal stop_signal) if (evregpy_no_listeners_p (gdb_py_events.stop)) return 0; + gdbpy_ref<> dict = py_print_bpstat (bs, stop_signal); + if (dict == nullptr) + return -1; + /* Add any breakpoint set at this location to the list. */ for (current_bs = bs; current_bs != NULL; current_bs = current_bs->next) { @@ -71,7 +124,8 @@ emit_stop_event (struct bpstat *bs, enum gdb_signal stop_signal) if (list != NULL) { - stop_event_obj = create_breakpoint_event_object (list.get (), + stop_event_obj = create_breakpoint_event_object (dict, + list.get (), first_bp); if (stop_event_obj == NULL) return -1; @@ -81,7 +135,7 @@ emit_stop_event (struct bpstat *bs, enum gdb_signal stop_signal) if (stop_signal != GDB_SIGNAL_0 && stop_signal != GDB_SIGNAL_TRAP) { - stop_event_obj = create_signal_event_object (stop_signal); + stop_event_obj = create_signal_event_object (dict, stop_signal); if (stop_event_obj == NULL) return -1; } @@ -90,7 +144,8 @@ emit_stop_event (struct bpstat *bs, enum gdb_signal stop_signal) be known and this should eventually be unused. */ if (stop_event_obj == NULL) { - stop_event_obj = create_stop_event_object (&stop_event_object_type); + stop_event_obj = create_stop_event_object (&stop_event_object_type, + dict); if (stop_event_obj == NULL) return -1; } |