Change how Python architecture and language are handled
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.
This commit is contained in:
parent
8a782bbf70
commit
1da5d0e664
20 changed files with 146 additions and 105 deletions
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
@ -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."));
|
||||
|
@ -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. */
|
||||
|
@ -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. */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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*/,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
|
|
@ -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 ();
|
||||
|
@ -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 ();
|
||||
|
@ -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 ();
|
||||
|
@ -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 ();
|
||||
|
@ -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 ();
|
||||
|
@ -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 ();
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -155,7 +155,7 @@ gdbpy_tui_window::is_valid () const
|
|||
|
||||
tui_py_window::~tui_py_window ()
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
/* This can be null if the user-provided Python construction
|
||||
function failed. */
|
||||
|
@ -181,7 +181,7 @@ tui_py_window::rerender ()
|
|||
{
|
||||
tui_win_info::rerender ();
|
||||
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
int h = viewport_height ();
|
||||
int w = viewport_width ();
|
||||
|
@ -206,7 +206,7 @@ tui_py_window::rerender ()
|
|||
void
|
||||
tui_py_window::do_scroll_horizontal (int num_to_scroll)
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
if (PyObject_HasAttrString (m_window.get (), "hscroll"))
|
||||
{
|
||||
|
@ -220,7 +220,7 @@ tui_py_window::do_scroll_horizontal (int num_to_scroll)
|
|||
void
|
||||
tui_py_window::do_scroll_vertical (int num_to_scroll)
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
if (PyObject_HasAttrString (m_window.get (), "vscroll"))
|
||||
{
|
||||
|
@ -234,7 +234,7 @@ tui_py_window::do_scroll_vertical (int num_to_scroll)
|
|||
void
|
||||
tui_py_window::click (int mouse_x, int mouse_y, int mouse_button)
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
if (PyObject_HasAttrString (m_window.get (), "click"))
|
||||
{
|
||||
|
@ -285,7 +285,7 @@ public:
|
|||
|
||||
gdbpy_tui_window_maker (const gdbpy_tui_window_maker &other)
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
m_constr = other.m_constr;
|
||||
}
|
||||
|
||||
|
@ -297,7 +297,7 @@ public:
|
|||
|
||||
gdbpy_tui_window_maker &operator= (const gdbpy_tui_window_maker &other)
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
m_constr = other.m_constr;
|
||||
return *this;
|
||||
}
|
||||
|
@ -312,14 +312,14 @@ private:
|
|||
|
||||
gdbpy_tui_window_maker::~gdbpy_tui_window_maker ()
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
m_constr.reset (nullptr);
|
||||
}
|
||||
|
||||
tui_win_info *
|
||||
gdbpy_tui_window_maker::operator() (const char *win_name)
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
gdbpy_ref<gdbpy_tui_window> wrapper
|
||||
(PyObject_New (gdbpy_tui_window, &gdbpy_tui_window_object_type));
|
||||
|
|
|
@ -799,7 +799,7 @@ typy_lookup_typename (const char *type_name, const struct block *block)
|
|||
else if (startswith (type_name, "enum "))
|
||||
type = lookup_enum (type_name + 5, NULL);
|
||||
else
|
||||
type = lookup_typename (python_language,
|
||||
type = lookup_typename (current_language,
|
||||
type_name, block, 0);
|
||||
}
|
||||
catch (const gdb_exception &except)
|
||||
|
@ -1089,7 +1089,7 @@ save_objfile_types (struct objfile *objfile, void *datum)
|
|||
|
||||
/* This prevents another thread from freeing the objects we're
|
||||
operating on. */
|
||||
gdbpy_enter enter_py (objfile->arch (), current_language);
|
||||
gdbpy_enter enter_py (objfile->arch ());
|
||||
|
||||
htab_up copied_types = create_copied_types_hash (objfile);
|
||||
|
||||
|
|
|
@ -524,7 +524,7 @@ pyuw_sniffer (const struct frame_unwind *self, struct frame_info *this_frame,
|
|||
struct gdbarch *gdbarch = (struct gdbarch *) (self->unwind_data);
|
||||
cached_frame_info *cached_frame;
|
||||
|
||||
gdbpy_enter enter_py (gdbarch, current_language);
|
||||
gdbpy_enter enter_py (gdbarch);
|
||||
|
||||
pyuw_debug_printf ("frame=%d, sp=%s, pc=%s",
|
||||
frame_relative_level (this_frame),
|
||||
|
|
|
@ -93,8 +93,9 @@ unicode_to_encoded_python_string (PyObject *unicode_str, const char *charset)
|
|||
gdb::unique_xmalloc_ptr<char>
|
||||
unicode_to_target_string (PyObject *unicode_str)
|
||||
{
|
||||
return unicode_to_encoded_string (unicode_str,
|
||||
target_charset (python_gdbarch));
|
||||
return (unicode_to_encoded_string
|
||||
(unicode_str,
|
||||
target_charset (gdbpy_enter::get_gdbarch ())));
|
||||
}
|
||||
|
||||
/* Returns a PyObject with the contents of the given unicode string
|
||||
|
@ -104,8 +105,9 @@ unicode_to_target_string (PyObject *unicode_str)
|
|||
static gdbpy_ref<>
|
||||
unicode_to_target_python_string (PyObject *unicode_str)
|
||||
{
|
||||
return unicode_to_encoded_python_string (unicode_str,
|
||||
target_charset (python_gdbarch));
|
||||
return (unicode_to_encoded_python_string
|
||||
(unicode_str,
|
||||
target_charset (gdbpy_enter::get_gdbarch ())));
|
||||
}
|
||||
|
||||
/* Converts a python string (8-bit or unicode) to a target string in
|
||||
|
|
|
@ -35,23 +35,26 @@
|
|||
GDB (which uses target arithmetic). */
|
||||
|
||||
/* Python's integer type corresponds to C's long type. */
|
||||
#define builtin_type_pyint builtin_type (python_gdbarch)->builtin_long
|
||||
#define builtin_type_pyint \
|
||||
builtin_type (gdbpy_enter::get_gdbarch ())->builtin_long
|
||||
|
||||
/* Python's float type corresponds to C's double type. */
|
||||
#define builtin_type_pyfloat builtin_type (python_gdbarch)->builtin_double
|
||||
#define builtin_type_pyfloat \
|
||||
builtin_type (gdbpy_enter::get_gdbarch ())->builtin_double
|
||||
|
||||
/* Python's long type corresponds to C's long long type. */
|
||||
#define builtin_type_pylong builtin_type (python_gdbarch)->builtin_long_long
|
||||
#define builtin_type_pylong \
|
||||
builtin_type (gdbpy_enter::get_gdbarch ())->builtin_long_long
|
||||
|
||||
/* Python's long type corresponds to C's long long type. Unsigned version. */
|
||||
#define builtin_type_upylong builtin_type \
|
||||
(python_gdbarch)->builtin_unsigned_long_long
|
||||
(gdbpy_enter::get_gdbarch ())->builtin_unsigned_long_long
|
||||
|
||||
#define builtin_type_pybool \
|
||||
language_bool_type (python_language, python_gdbarch)
|
||||
language_bool_type (current_language, gdbpy_enter::get_gdbarch ())
|
||||
|
||||
#define builtin_type_pychar \
|
||||
language_string_char_type (python_language, python_gdbarch)
|
||||
language_string_char_type (current_language, gdbpy_enter::get_gdbarch ())
|
||||
|
||||
struct value_object {
|
||||
PyObject_HEAD
|
||||
|
@ -754,7 +757,7 @@ valpy_format_string (PyObject *self, PyObject *args, PyObject *kw)
|
|||
try
|
||||
{
|
||||
common_val_print (((value_object *) self)->value, &stb, 0,
|
||||
&opts, python_language);
|
||||
&opts, current_language);
|
||||
}
|
||||
catch (const gdb_exception &except)
|
||||
{
|
||||
|
@ -1160,7 +1163,7 @@ valpy_str (PyObject *self)
|
|||
try
|
||||
{
|
||||
common_val_print (((value_object *) self)->value, &stb, 0,
|
||||
&opts, python_language);
|
||||
&opts, current_language);
|
||||
}
|
||||
catch (const gdb_exception &except)
|
||||
{
|
||||
|
@ -2025,7 +2028,7 @@ gdbpy_convenience_variable (PyObject *self, PyObject *args)
|
|||
|
||||
if (var != NULL)
|
||||
{
|
||||
res_val = value_of_internalvar (python_gdbarch, var);
|
||||
res_val = value_of_internalvar (gdbpy_enter::get_gdbarch (), var);
|
||||
if (value_type (res_val)->code () == TYPE_CODE_VOID)
|
||||
res_val = NULL;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ private:
|
|||
python_xmethod_worker::~python_xmethod_worker ()
|
||||
{
|
||||
/* We don't do much here, but we still need the GIL. */
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
Py_DECREF (m_py_worker);
|
||||
Py_DECREF (m_this_type);
|
||||
|
@ -122,7 +122,7 @@ gdbpy_get_matching_xmethod_workers
|
|||
{
|
||||
gdb_assert (obj_type != NULL && method_name != NULL);
|
||||
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
gdbpy_ref<> py_type (type_to_type_object (obj_type));
|
||||
if (py_type == NULL)
|
||||
|
@ -294,7 +294,7 @@ python_xmethod_worker::do_get_arg_types (std::vector<type *> *arg_types)
|
|||
{
|
||||
/* The gdbpy_enter object needs to be placed first, so that it's the last to
|
||||
be destroyed. */
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
struct type *obj_type;
|
||||
int i = 1, arg_count;
|
||||
gdbpy_ref<> list_iter;
|
||||
|
@ -410,7 +410,7 @@ python_xmethod_worker::do_get_result_type (value *obj,
|
|||
struct type *obj_type, *this_type;
|
||||
int i;
|
||||
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
/* First see if there is a get_result_type method.
|
||||
If not this could be an old xmethod (pre 7.9.1). */
|
||||
|
@ -502,7 +502,7 @@ struct value *
|
|||
python_xmethod_worker::invoke (struct value *obj,
|
||||
gdb::array_view<value *> args)
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
int i;
|
||||
struct type *obj_type, *this_type;
|
||||
|
@ -580,7 +580,7 @@ python_xmethod_worker::invoke (struct value *obj,
|
|||
}
|
||||
else
|
||||
{
|
||||
res = allocate_value (lookup_typename (python_language,
|
||||
res = allocate_value (lookup_typename (current_language,
|
||||
"void", NULL, 0));
|
||||
}
|
||||
|
||||
|
|
|
@ -625,14 +625,36 @@ class gdbpy_enter
|
|||
{
|
||||
public:
|
||||
|
||||
gdbpy_enter (struct gdbarch *gdbarch, const struct language_defn *language);
|
||||
/* Set the ambient Python architecture to GDBARCH and the language
|
||||
to LANGUAGE. If GDBARCH is nullptr, then the architecture will
|
||||
be computed, when needed, using get_current_arch; see the
|
||||
get_gdbarch method. If LANGUAGE is not nullptr, then the current
|
||||
language at time of construction will be saved (to be restored on
|
||||
destruction), and the current language will be set to
|
||||
LANGUAGE. */
|
||||
explicit gdbpy_enter (struct gdbarch *gdbarch = nullptr,
|
||||
const struct language_defn *language = nullptr);
|
||||
|
||||
~gdbpy_enter ();
|
||||
|
||||
DISABLE_COPY_AND_ASSIGN (gdbpy_enter);
|
||||
|
||||
/* Return the current gdbarch, as known to the Python layer. This
|
||||
is either python_gdbarch (which comes from the most recent call
|
||||
to the gdbpy_enter constructor), or, if that is nullptr, the
|
||||
result of get_current_arch. */
|
||||
static struct gdbarch *get_gdbarch ();
|
||||
|
||||
/* Called only during gdb shutdown. This sets python_gdbarch to an
|
||||
acceptable value. */
|
||||
static void finalize ();
|
||||
|
||||
private:
|
||||
|
||||
/* The current gdbarch, according to Python. This can be
|
||||
nullptr. */
|
||||
static struct gdbarch *python_gdbarch;
|
||||
|
||||
struct active_ext_lang_state *m_previous_active;
|
||||
PyGILState_STATE m_state;
|
||||
struct gdbarch *m_gdbarch;
|
||||
|
@ -680,9 +702,6 @@ private:
|
|||
PyThreadState *m_save;
|
||||
};
|
||||
|
||||
extern struct gdbarch *python_gdbarch;
|
||||
extern const struct language_defn *python_language;
|
||||
|
||||
/* Use this after a TRY_EXCEPT to throw the appropriate Python
|
||||
exception. */
|
||||
#define GDB_PY_HANDLE_EXCEPTION(Exception) \
|
||||
|
|
|
@ -192,13 +192,12 @@ const struct extension_language_defn extension_language_python =
|
|||
|
||||
/* Architecture and language to be used in callbacks from
|
||||
the Python interpreter. */
|
||||
struct gdbarch *python_gdbarch;
|
||||
const struct language_defn *python_language;
|
||||
struct gdbarch *gdbpy_enter::python_gdbarch;
|
||||
|
||||
gdbpy_enter::gdbpy_enter (struct gdbarch *gdbarch,
|
||||
const struct language_defn *language)
|
||||
: m_gdbarch (python_gdbarch),
|
||||
m_language (python_language)
|
||||
m_language (language == nullptr ? nullptr : current_language)
|
||||
{
|
||||
/* We should not ever enter Python unless initialized. */
|
||||
if (!gdb_python_initialized)
|
||||
|
@ -209,7 +208,8 @@ gdbpy_enter::gdbpy_enter (struct gdbarch *gdbarch,
|
|||
m_state = PyGILState_Ensure ();
|
||||
|
||||
python_gdbarch = gdbarch;
|
||||
python_language = language;
|
||||
if (language != nullptr)
|
||||
set_language (language->la_language);
|
||||
|
||||
/* Save it and ensure ! PyErr_Occurred () afterwards. */
|
||||
m_error.emplace ();
|
||||
|
@ -228,12 +228,27 @@ gdbpy_enter::~gdbpy_enter ()
|
|||
m_error->restore ();
|
||||
|
||||
python_gdbarch = m_gdbarch;
|
||||
python_language = m_language;
|
||||
if (m_language != nullptr)
|
||||
set_language (m_language->la_language);
|
||||
|
||||
restore_active_ext_lang (m_previous_active);
|
||||
PyGILState_Release (m_state);
|
||||
}
|
||||
|
||||
struct gdbarch *
|
||||
gdbpy_enter::get_gdbarch ()
|
||||
{
|
||||
if (python_gdbarch != nullptr)
|
||||
return python_gdbarch;
|
||||
return get_current_arch ();
|
||||
}
|
||||
|
||||
void
|
||||
gdbpy_enter::finalize ()
|
||||
{
|
||||
python_gdbarch = target_gdbarch ();
|
||||
}
|
||||
|
||||
/* A helper class to save and restore the GIL, but without touching
|
||||
the other globals that are handled by gdbpy_enter. */
|
||||
|
||||
|
@ -318,7 +333,7 @@ python_interactive_command (const char *arg, int from_tty)
|
|||
|
||||
arg = skip_spaces (arg);
|
||||
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
if (arg && *arg)
|
||||
{
|
||||
|
@ -412,7 +427,7 @@ gdbpy_eval_from_control_command (const struct extension_language_defn *extlang,
|
|||
if (cmd->body_list_1 != nullptr)
|
||||
error (_("Invalid \"python\" block structure."));
|
||||
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
std::string script = compute_python_string (cmd->body_list_0.get ());
|
||||
ret = PyRun_SimpleString (script.c_str ());
|
||||
|
@ -425,7 +440,7 @@ gdbpy_eval_from_control_command (const struct extension_language_defn *extlang,
|
|||
static void
|
||||
python_command (const char *arg, int from_tty)
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
|
||||
|
||||
|
@ -556,7 +571,7 @@ gdbpy_parameter (PyObject *self, PyObject *args)
|
|||
static PyObject *
|
||||
gdbpy_target_charset (PyObject *self, PyObject *args)
|
||||
{
|
||||
const char *cset = target_charset (python_gdbarch);
|
||||
const char *cset = target_charset (gdbpy_enter::get_gdbarch ());
|
||||
|
||||
return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL);
|
||||
}
|
||||
|
@ -566,7 +581,7 @@ gdbpy_target_charset (PyObject *self, PyObject *args)
|
|||
static PyObject *
|
||||
gdbpy_target_wide_charset (PyObject *self, PyObject *args)
|
||||
{
|
||||
const char *cset = target_wide_charset (python_gdbarch);
|
||||
const char *cset = target_wide_charset (gdbpy_enter::get_gdbarch ());
|
||||
|
||||
return PyUnicode_Decode (cset, strlen (cset), host_charset (), NULL);
|
||||
}
|
||||
|
@ -867,7 +882,7 @@ gdbpy_decode_line (PyObject *self, PyObject *args)
|
|||
}
|
||||
|
||||
if (arg != NULL)
|
||||
location = string_to_event_location_basic (&arg, python_language,
|
||||
location = string_to_event_location_basic (&arg, current_language,
|
||||
symbol_name_match_type::WILD);
|
||||
|
||||
std::vector<symtab_and_line> decoded_sals;
|
||||
|
@ -972,7 +987,7 @@ static void
|
|||
gdbpy_source_script (const struct extension_language_defn *extlang,
|
||||
FILE *file, const char *filename)
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
python_run_simple_file (file, filename);
|
||||
}
|
||||
|
||||
|
@ -1011,7 +1026,7 @@ struct gdbpy_event
|
|||
|
||||
void operator() ()
|
||||
{
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
gdbpy_ref<> call_result (PyObject_CallObject (m_func, NULL));
|
||||
if (call_result == NULL)
|
||||
|
@ -1060,7 +1075,7 @@ gdbpy_before_prompt_hook (const struct extension_language_defn *extlang,
|
|||
if (!gdb_python_initialized)
|
||||
return EXT_LANG_RC_NOP;
|
||||
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
if (!evregpy_no_listeners_p (gdb_py_events.before_prompt)
|
||||
&& evpy_emit_event (NULL, gdb_py_events.before_prompt) < 0)
|
||||
|
@ -1135,7 +1150,7 @@ gdbpy_colorize (const std::string &filename, const std::string &contents)
|
|||
if (!gdb_python_initialized)
|
||||
return {};
|
||||
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
if (gdb_python_module == nullptr
|
||||
|| !PyObject_HasAttrString (gdb_python_module, "colorize"))
|
||||
|
@ -1400,7 +1415,7 @@ gdbpy_source_objfile_script (const struct extension_language_defn *extlang,
|
|||
if (!gdb_python_initialized)
|
||||
return;
|
||||
|
||||
gdbpy_enter enter_py (objfile->arch (), current_language);
|
||||
gdbpy_enter enter_py (objfile->arch ());
|
||||
scoped_restore restire_current_objfile
|
||||
= make_scoped_restore (&gdbpy_current_objfile, objfile);
|
||||
|
||||
|
@ -1421,7 +1436,7 @@ gdbpy_execute_objfile_script (const struct extension_language_defn *extlang,
|
|||
if (!gdb_python_initialized)
|
||||
return;
|
||||
|
||||
gdbpy_enter enter_py (objfile->arch (), current_language);
|
||||
gdbpy_enter enter_py (objfile->arch ());
|
||||
scoped_restore restire_current_objfile
|
||||
= make_scoped_restore (&gdbpy_current_objfile, objfile);
|
||||
|
||||
|
@ -1453,7 +1468,7 @@ gdbpy_start_type_printers (const struct extension_language_defn *extlang,
|
|||
if (!gdb_python_initialized)
|
||||
return;
|
||||
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
gdbpy_ref<> type_module (PyImport_ImportModule ("gdb.types"));
|
||||
if (type_module == NULL)
|
||||
|
@ -1498,7 +1513,7 @@ gdbpy_apply_type_printers (const struct extension_language_defn *extlang,
|
|||
if (!gdb_python_initialized)
|
||||
return EXT_LANG_RC_NOP;
|
||||
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
gdbpy_ref<> type_obj (type_to_type_object (type));
|
||||
if (type_obj == NULL)
|
||||
|
@ -1561,7 +1576,7 @@ gdbpy_free_type_printers (const struct extension_language_defn *extlang,
|
|||
if (!gdb_python_initialized)
|
||||
return;
|
||||
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
Py_DECREF (printers);
|
||||
}
|
||||
|
||||
|
@ -1696,8 +1711,7 @@ finalize_python (void *ignore)
|
|||
previous_active = set_active_ext_lang (&extension_language_python);
|
||||
|
||||
(void) PyGILState_Ensure ();
|
||||
python_gdbarch = target_gdbarch ();
|
||||
python_language = current_language;
|
||||
gdbpy_enter::finalize ();
|
||||
|
||||
Py_Finalize ();
|
||||
|
||||
|
@ -1756,7 +1770,7 @@ gdbpy_gdb_exiting (int exit_code)
|
|||
if (!gdb_python_initialized)
|
||||
return;
|
||||
|
||||
gdbpy_enter enter_py (python_gdbarch, python_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
if (emit_exiting_event (exit_code) < 0)
|
||||
gdbpy_print_stack ();
|
||||
|
@ -2174,7 +2188,7 @@ gdbpy_initialize (const struct extension_language_defn *extlang)
|
|||
if (!do_start_initialization () && PyErr_Occurred ())
|
||||
gdbpy_print_stack ();
|
||||
|
||||
gdbpy_enter enter_py (get_current_arch (), current_language);
|
||||
gdbpy_enter enter_py;
|
||||
|
||||
if (!do_initialize (extlang))
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue