Skip to content

Commit

Permalink
Change how Python architecture and language are handled
Browse files Browse the repository at this point in the history
Currently, gdb's Python layer captures the current architecture and
language when "entering" Python code.  This has some undesirable
effects, and so this series changes how this is handled.

First, there is code like this:

  gdbpy_enter enter_py (python_gdbarch, python_language);

This is incorrect, because both of these are NULL when not otherwise
assigned.  This can cause crashes in some cases -- I've added one to
the test suite.  (Note that this crasher is just an example, other
ones along the same lines are possible.)

Second, when the language is captured in this way, it means that
Python code cannot affect the current language for its own purposes.
It's reasonable to want to write code like this:

    gdb.execute('set language mumble')
    ... stuff using the current language
    gdb.execute('set language previous-value')

However, this won't actually work, because the language is captured on
entry.  I've added a test to show this as well.

This patch changes gdb to try to avoid capturing the current values.
The Python concept of the current gdbarch is only set in those few
cases where a non-default value is computed or needed; and the
language is not captured at all -- instead, in the cases where it's
required, the current language is temporarily changed.
  • Loading branch information
tromey committed Jan 26, 2022
1 parent 8a782bb commit 1da5d0e
Show file tree
Hide file tree
Showing 20 changed files with 146 additions and 105 deletions.
19 changes: 6 additions & 13 deletions gdb/python/py-breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
const struct breakpoint_ops *ops =
breakpoint_ops_for_event_location (location.get (), false);

create_breakpoint (python_gdbarch,
create_breakpoint (gdbpy_enter::get_gdbarch (),
location.get (), NULL, -1, NULL, false,
0,
temporary_bp, type,
Expand Down Expand Up @@ -954,15 +954,13 @@ gdbpy_breakpoint_cond_says_stop (const struct extension_language_defn *extlang,
int stop;
struct gdbpy_breakpoint_object *bp_obj = b->py_bp_object;
PyObject *py_bp = (PyObject *) bp_obj;
struct gdbarch *garch;

if (bp_obj == NULL)
return EXT_LANG_BP_STOP_UNSET;

stop = -1;
garch = b->gdbarch ? b->gdbarch : get_current_arch ();

gdbpy_enter enter_py (garch, current_language);
gdbpy_enter enter_py (b->gdbarch);

if (bp_obj->is_finish_bp)
bpfinishpy_pre_stop_hook (bp_obj);
Expand Down Expand Up @@ -1005,15 +1003,13 @@ gdbpy_breakpoint_has_cond (const struct extension_language_defn *extlang,
struct breakpoint *b)
{
PyObject *py_bp;
struct gdbarch *garch;

if (b->py_bp_object == NULL)
return 0;

py_bp = (PyObject *) b->py_bp_object;
garch = b->gdbarch ? b->gdbarch : get_current_arch ();

gdbpy_enter enter_py (garch, current_language);
gdbpy_enter enter_py (b->gdbarch);
return PyObject_HasAttrString (py_bp, stop_func);
}

Expand Down Expand Up @@ -1048,8 +1044,7 @@ gdbpy_breakpoint_created (struct breakpoint *bp)
return;
}

struct gdbarch *garch = bp->gdbarch ? bp->gdbarch : get_current_arch ();
gdbpy_enter enter_py (garch, current_language);
gdbpy_enter enter_py (bp->gdbarch);

if (bppy_pending_object)
{
Expand Down Expand Up @@ -1099,8 +1094,7 @@ gdbpy_breakpoint_deleted (struct breakpoint *b)
bp = get_breakpoint (num);
if (bp)
{
struct gdbarch *garch = bp->gdbarch ? bp->gdbarch : get_current_arch ();
gdbpy_enter enter_py (garch, current_language);
gdbpy_enter enter_py (b->gdbarch);

gdbpy_ref<gdbpy_breakpoint_object> bp_obj (bp->py_bp_object);
if (bp_obj != NULL)
Expand Down Expand Up @@ -1131,8 +1125,7 @@ gdbpy_breakpoint_modified (struct breakpoint *b)
bp = get_breakpoint (num);
if (bp)
{
struct gdbarch *garch = bp->gdbarch ? bp->gdbarch : get_current_arch ();
gdbpy_enter enter_py (garch, current_language);
gdbpy_enter enter_py (b->gdbarch);

PyObject *bp_obj = (PyObject *) bp->py_bp_object;
if (bp_obj)
Expand Down
8 changes: 4 additions & 4 deletions gdb/python/py-cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ cmdpy_dont_repeat (PyObject *self, PyObject *args)
static void
cmdpy_destroyer (struct cmd_list_element *self, void *context)
{
gdbpy_enter enter_py (get_current_arch (), current_language);
gdbpy_enter enter_py;

/* Release our hold on the command object. */
gdbpy_ref<cmdpy_object> cmd ((cmdpy_object *) context);
Expand All @@ -104,7 +104,7 @@ cmdpy_function (const char *args, int from_tty, cmd_list_element *command)
{
cmdpy_object *obj = (cmdpy_object *) command->context ();

gdbpy_enter enter_py (get_current_arch (), current_language);
gdbpy_enter enter_py;

if (! obj)
error (_("Invalid invocation of Python command object."));
Expand Down Expand Up @@ -223,7 +223,7 @@ cmdpy_completer_handle_brkchars (struct cmd_list_element *command,
completion_tracker &tracker,
const char *text, const char *word)
{
gdbpy_enter enter_py (get_current_arch (), current_language);
gdbpy_enter enter_py;

/* Calling our helper to obtain a reference to the PyObject of the Python
function. */
Expand Down Expand Up @@ -266,7 +266,7 @@ cmdpy_completer (struct cmd_list_element *command,
completion_tracker &tracker,
const char *text, const char *word)
{
gdbpy_enter enter_py (get_current_arch (), current_language);
gdbpy_enter enter_py;

/* Calling our helper to obtain a reference to the PyObject of the Python
function. */
Expand Down
2 changes: 1 addition & 1 deletion gdb/python/py-connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ connpy_connection_removed (process_stratum_target *target)
if (!gdb_python_initialized)
return;

gdbpy_enter enter_py (get_current_arch (), current_language);
gdbpy_enter enter_py;

if (!evregpy_no_listeners_p (gdb_py_events.connection_removed))
if (emit_connection_event (target, gdb_py_events.connection_removed) < 0)
Expand Down
6 changes: 3 additions & 3 deletions gdb/python/py-finishbreakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ bpfinishpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
/* Set a breakpoint on the return address. */
event_location_up location
= new_address_location (get_frame_pc (prev_frame), NULL, 0);
create_breakpoint (python_gdbarch,
create_breakpoint (gdbpy_enter::get_gdbarch (),
location.get (), NULL, thread, NULL, false,
0,
1 /*temp_flag*/,
Expand Down Expand Up @@ -380,7 +380,7 @@ bpfinishpy_detect_out_scope_cb (struct breakpoint *b,
static void
bpfinishpy_handle_stop (struct bpstat *bs, int print_frame)
{
gdbpy_enter enter_py (get_current_arch (), current_language);
gdbpy_enter enter_py;

for (breakpoint *bp : all_breakpoints_safe ())
bpfinishpy_detect_out_scope_cb (bp, bs == NULL ? NULL : bs->breakpoint_at);
Expand All @@ -392,7 +392,7 @@ bpfinishpy_handle_stop (struct bpstat *bs, int print_frame)
static void
bpfinishpy_handle_exit (struct inferior *inf)
{
gdbpy_enter enter_py (target_gdbarch (), current_language);
gdbpy_enter enter_py (target_gdbarch ());

for (breakpoint *bp : all_breakpoints_safe ())
bpfinishpy_detect_out_scope_cb (bp, nullptr);
Expand Down
12 changes: 6 additions & 6 deletions gdb/python/py-framefilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ extract_sym (PyObject *obj, gdb::unique_xmalloc_ptr<char> *name,
if (*name == NULL)
return EXT_LANG_BT_ERROR;
/* If the API returns a string (and not a symbol), then there is
no symbol derived language available and the frame filter has
either overridden the symbol with a string, or supplied a
entirely synthetic symbol/value pairing. In that case, use
python_language. */
*language = python_language;
no symbol derived language available and the frame filter has
either overridden the symbol with a string, or supplied a
entirely synthetic symbol/value pairing. In that case, use
the current language. */
*language = current_language;
*sym = NULL;
*sym_block = NULL;
}
Expand Down Expand Up @@ -1157,7 +1157,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
return EXT_LANG_BT_NO_FILTERS;
}

gdbpy_enter enter_py (gdbarch, current_language);
gdbpy_enter enter_py (gdbarch);

/* When we're limiting the number of frames, be careful to request
one extra frame, so that we can print a message if there are more
Expand Down
27 changes: 13 additions & 14 deletions gdb/python/py-inferior.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ python_on_normal_stop (struct bpstat *bs, int print_frame)

stop_signal = inferior_thread ()->stop_signal ();

gdbpy_enter enter_py (get_current_arch (), current_language);
gdbpy_enter enter_py;

if (emit_stop_event (bs, stop_signal) < 0)
gdbpy_print_stack ();
Expand All @@ -98,7 +98,7 @@ python_on_resume (ptid_t ptid)
if (!gdb_python_initialized)
return;

gdbpy_enter enter_py (target_gdbarch (), current_language);
gdbpy_enter enter_py (target_gdbarch ());

if (emit_continue_event (ptid) < 0)
gdbpy_print_stack ();
Expand All @@ -110,7 +110,7 @@ python_on_resume (ptid_t ptid)
static void
python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
{
gdbpy_enter enter_py (target_gdbarch (), current_language);
gdbpy_enter enter_py (target_gdbarch ());

if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0)
gdbpy_print_stack ();
Expand All @@ -122,7 +122,7 @@ python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
static void
python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
{
gdbpy_enter enter_py (target_gdbarch (), current_language);
gdbpy_enter enter_py (target_gdbarch ());

if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0)
gdbpy_print_stack ();
Expand All @@ -135,7 +135,7 @@ python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
static void
python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
{
gdbpy_enter enter_py (target_gdbarch (), current_language);
gdbpy_enter enter_py (target_gdbarch ());

if (emit_memory_changed_event (addr, len) < 0)
gdbpy_print_stack ();
Expand All @@ -148,7 +148,7 @@ python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len,
static void
python_on_register_change (struct frame_info *frame, int regnum)
{
gdbpy_enter enter_py (target_gdbarch (), current_language);
gdbpy_enter enter_py (target_gdbarch ());

if (emit_register_changed_event (frame, regnum) < 0)
gdbpy_print_stack ();
Expand All @@ -162,7 +162,7 @@ python_inferior_exit (struct inferior *inf)
if (!gdb_python_initialized)
return;

gdbpy_enter enter_py (target_gdbarch (), current_language);
gdbpy_enter enter_py (target_gdbarch ());

if (inf->has_exit_code)
exit_code = &inf->exit_code;
Expand All @@ -183,8 +183,7 @@ python_new_objfile (struct objfile *objfile)

gdbpy_enter enter_py (objfile != NULL
? objfile->arch ()
: target_gdbarch (),
current_language);
: target_gdbarch ());

if (objfile == NULL)
{
Expand Down Expand Up @@ -237,7 +236,7 @@ python_new_inferior (struct inferior *inf)
if (!gdb_python_initialized)
return;

gdbpy_enter enter_py (python_gdbarch, python_language);
gdbpy_enter enter_py;

if (evregpy_no_listeners_p (gdb_py_events.new_inferior))
return;
Expand Down Expand Up @@ -265,7 +264,7 @@ python_inferior_deleted (struct inferior *inf)
if (!gdb_python_initialized)
return;

gdbpy_enter enter_py (python_gdbarch, python_language);
gdbpy_enter enter_py;

if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted))
return;
Expand Down Expand Up @@ -312,7 +311,7 @@ add_thread_object (struct thread_info *tp)
if (!gdb_python_initialized)
return;

gdbpy_enter enter_py (python_gdbarch, python_language);
gdbpy_enter enter_py;

gdbpy_ref<thread_object> thread_obj = create_thread_object (tp);
if (thread_obj == NULL)
Expand Down Expand Up @@ -348,7 +347,7 @@ delete_thread_object (struct thread_info *tp, int ignore)
if (!gdb_python_initialized)
return;

gdbpy_enter enter_py (python_gdbarch, python_language);
gdbpy_enter enter_py;

gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf);
if (inf_obj == NULL)
Expand Down Expand Up @@ -792,7 +791,7 @@ py_free_inferior (struct inferior *inf, void *datum)
if (!gdb_python_initialized)
return;

gdbpy_enter enter_py (python_gdbarch, python_language);
gdbpy_enter enter_py;
gdbpy_ref<inferior_object> inf_obj ((inferior_object *) datum);

inf_obj->inferior = NULL;
Expand Down
3 changes: 2 additions & 1 deletion gdb/python/py-membuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ mbpy_str (PyObject *self)

return PyString_FromFormat (_("Memory buffer for address %s, \
which is %s bytes long."),
paddress (python_gdbarch, membuf_obj->addr),
paddress (gdbpy_enter::get_gdbarch (),
membuf_obj->addr),
pulongest (membuf_obj->length));
}

Expand Down
2 changes: 1 addition & 1 deletion gdb/python/py-objfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@ gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw)
static void
py_free_objfile (struct objfile *objfile, void *datum)
{
gdbpy_enter enter_py (objfile->arch (), current_language);
gdbpy_enter enter_py (objfile->arch ());
gdbpy_ref<objfile_object> object ((objfile_object *) datum);
object->objfile = NULL;
}
Expand Down
4 changes: 2 additions & 2 deletions gdb/python/py-param.c
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ get_set_value (const char *args, int from_tty,
PyObject *obj = (PyObject *) c->context ();
gdb::unique_xmalloc_ptr<char> set_doc_string;

gdbpy_enter enter_py (get_current_arch (), current_language);
gdbpy_enter enter_py;
gdbpy_ref<> set_doc_func (PyString_FromString ("get_set_string"));

if (set_doc_func == NULL)
Expand Down Expand Up @@ -431,7 +431,7 @@ get_show_value (struct ui_file *file, int from_tty,
PyObject *obj = (PyObject *) c->context ();
gdb::unique_xmalloc_ptr<char> show_doc_string;

gdbpy_enter enter_py (get_current_arch (), current_language);
gdbpy_enter enter_py;
gdbpy_ref<> show_doc_func (PyString_FromString ("get_show_string"));

if (show_doc_func == NULL)
Expand Down
2 changes: 1 addition & 1 deletion gdb/python/py-progspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ py_free_pspace (struct program_space *pspace, void *datum)
being deleted. */
struct gdbarch *arch = target_gdbarch ();

gdbpy_enter enter_py (arch, current_language);
gdbpy_enter enter_py (arch);
gdbpy_ref<pspace_object> object ((pspace_object *) datum);
object->pspace = NULL;
}
Expand Down
Loading

0 comments on commit 1da5d0e

Please sign in to comment.