1 /* MI Command Set for GDB, the GNU debugger.
3 Copyright (C) 2019-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* GDB/MI commands implemented in Python. */
22 #include "python-internal.h"
23 #include "arch-utils.h"
26 #include "mi/mi-cmds.h"
27 #include "mi/mi-parse.h"
28 #include "cli/cli-cmds.h"
31 /* Debugging of Python MI commands. */
33 static bool pymicmd_debug
;
35 /* Implementation of "show debug py-micmd". */
38 show_pymicmd_debug (struct ui_file
*file
, int from_tty
,
39 struct cmd_list_element
*c
, const char *value
)
41 gdb_printf (file
, _("Python MI command debugging is %s.\n"), value
);
44 /* Print a "py-micmd" debug statement. */
46 #define pymicmd_debug_printf(fmt, ...) \
47 debug_prefixed_printf_cond (pymicmd_debug, "py-micmd", fmt, ##__VA_ARGS__)
49 /* Print a "py-micmd" enter/exit debug statements. */
51 #define PYMICMD_SCOPED_DEBUG_ENTER_EXIT \
52 scoped_debug_enter_exit (pymicmd_debug, "py-micmd")
56 /* Representation of a Python gdb.MICommand object. */
62 /* The object representing this command in the MI command table. This
63 pointer can be nullptr if the command is not currently installed into
64 the MI command table (see gdb.MICommand.installed property). */
65 struct mi_command_py
*mi_command
;
67 /* The string representing the name of this command, without the leading
68 dash. This string is never nullptr once the Python object has been
71 The memory for this string was allocated with malloc, and needs to be
72 deallocated with free when the Python object is deallocated.
74 When the MI_COMMAND field is not nullptr, then the mi_command_py
75 object's name will point back to this string. */
76 char *mi_command_name
;
79 /* The MI command implemented in Python. */
81 struct mi_command_py
: public mi_command
83 /* Constructs a new mi_command_py object. NAME is command name without
84 leading dash. OBJECT is a reference to a Python object implementing
85 the command. This object must inherit from gdb.MICommand and must
86 implement the invoke method. */
88 mi_command_py (const char *name
, micmdpy_object
*object
)
89 : mi_command (name
, nullptr),
90 m_pyobj (gdbpy_ref
<micmdpy_object
>::new_reference (object
))
92 pymicmd_debug_printf ("this = %p", this);
93 m_pyobj
->mi_command
= this;
98 /* The Python object representing a MI command contains a pointer back
99 to this c++ object. We can safely set this pointer back to nullptr
100 now, to indicate the Python object no longer references a valid c++
103 However, the Python object also holds the storage for our name
104 string. We can't clear that here as our parent's destructor might
105 still want to reference that string. Instead we rely on the Python
106 object deallocator to free that memory, and reset the pointer. */
107 m_pyobj
->mi_command
= nullptr;
109 pymicmd_debug_printf ("this = %p", this);
112 /* Validate that CMD_OBJ, a non-nullptr pointer, is installed into the MI
113 command table correctly. This function looks up the command in the MI
114 command table and checks that the object we get back references
115 CMD_OBJ. This function is only intended for calling within a
116 gdb_assert. This function performs many assertions internally, and
117 then always returns true. */
118 static void validate_installation (micmdpy_object
*cmd_obj
);
120 /* Update M_PYOBJ to NEW_PYOBJ. The pointer from M_PYOBJ that points
121 back to this object is swapped with the pointer in NEW_PYOBJ, which
122 must be nullptr, so that NEW_PYOBJ now points back to this object.
123 Additionally our parent's name string is stored in M_PYOBJ, so we
124 swap the name string with NEW_PYOBJ.
126 Before this call M_PYOBJ is the Python object representing this MI
127 command object. After this call has completed, NEW_PYOBJ now
128 represents this MI command object. */
129 void swap_python_object (micmdpy_object
*new_pyobj
)
131 /* Current object has a backlink, new object doesn't have a backlink. */
132 gdb_assert (m_pyobj
->mi_command
!= nullptr);
133 gdb_assert (new_pyobj
->mi_command
== nullptr);
135 /* Clear the current M_PYOBJ's backlink, set NEW_PYOBJ's backlink. */
136 std::swap (new_pyobj
->mi_command
, m_pyobj
->mi_command
);
138 /* Both object have names. */
139 gdb_assert (m_pyobj
->mi_command_name
!= nullptr);
140 gdb_assert (new_pyobj
->mi_command_name
!= nullptr);
142 /* mi_command::m_name is the string owned by the current object. */
143 gdb_assert (m_pyobj
->mi_command_name
== this->name ());
145 /* The name in mi_command::m_name is owned by the current object. Rather
146 than changing the value of mi_command::m_name (which is not accessible
147 from here) to point to the name owned by the new object, swap the names
148 of the two objects, since we know they are identical strings. */
149 gdb_assert (strcmp (new_pyobj
->mi_command_name
,
150 m_pyobj
->mi_command_name
) == 0);
151 std::swap (new_pyobj
->mi_command_name
, m_pyobj
->mi_command_name
);
153 /* Take a reference to the new object, drop the reference to the current
155 m_pyobj
= gdbpy_ref
<micmdpy_object
>::new_reference (new_pyobj
);
158 /* Called when the MI command is invoked. */
159 virtual void invoke(struct mi_parse
*parse
) const override
;
162 /* The Python object representing this MI command. */
163 gdbpy_ref
<micmdpy_object
> m_pyobj
;
166 using mi_command_py_up
= std::unique_ptr
<mi_command_py
>;
168 extern PyTypeObject micmdpy_object_type
169 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("micmdpy_object");
171 /* Holds a Python object containing the string 'invoke'. */
173 static PyObject
*invoke_cst
;
175 /* Called when the MI command is invoked. PARSE contains the parsed
176 command line arguments from the user. */
179 mi_command_py::invoke (struct mi_parse
*parse
) const
181 PYMICMD_SCOPED_DEBUG_ENTER_EXIT
;
183 pymicmd_debug_printf ("this = %p, name = %s", this, name ());
185 parse
->parse_argv ();
187 if (parse
->argv
== nullptr)
188 error (_("Problem parsing arguments: %s %s"), parse
->command
.get (),
192 gdbpy_enter enter_py
;
194 /* Place all the arguments into a list which we pass as a single argument
195 to the MI command's invoke method. */
196 gdbpy_ref
<> argobj (PyList_New (parse
->argc
));
197 if (argobj
== nullptr)
198 gdbpy_handle_exception ();
200 for (int i
= 0; i
< parse
->argc
; ++i
)
202 gdbpy_ref
<> str (PyUnicode_Decode (parse
->argv
[i
],
203 strlen (parse
->argv
[i
]),
204 host_charset (), nullptr));
205 if (PyList_SetItem (argobj
.get (), i
, str
.release ()) < 0)
206 gdbpy_handle_exception ();
209 gdb_assert (this->m_pyobj
!= nullptr);
210 gdb_assert (PyErr_Occurred () == nullptr);
212 (PyObject_CallMethodObjArgs ((PyObject
*) this->m_pyobj
.get (), invoke_cst
,
213 argobj
.get (), nullptr));
214 if (results
== nullptr)
215 gdbpy_handle_exception ();
217 if (results
!= Py_None
)
219 /* At the top-level, the results must be a dictionary. */
220 if (!PyDict_Check (results
.get ()))
221 gdbpy_error (_("Result from invoke must be a dictionary"));
222 serialize_mi_results (results
.get ());
226 /* See declaration above. */
229 mi_command_py::validate_installation (micmdpy_object
*cmd_obj
)
231 gdb_assert (cmd_obj
!= nullptr);
232 mi_command_py
*cmd
= cmd_obj
->mi_command
;
233 gdb_assert (cmd
!= nullptr);
234 const char *name
= cmd_obj
->mi_command_name
;
235 gdb_assert (name
!= nullptr);
236 gdb_assert (name
== cmd
->name ());
237 mi_command
*mi_cmd
= mi_cmd_lookup (name
);
238 gdb_assert (mi_cmd
== cmd
);
239 gdb_assert (cmd
->m_pyobj
== cmd_obj
);
242 /* Return CMD as an mi_command_py if it is a Python MI command, else
245 static mi_command_py
*
246 as_mi_command_py (mi_command
*cmd
)
248 return dynamic_cast<mi_command_py
*> (cmd
);
251 /* Uninstall OBJ, making the MI command represented by OBJ unavailable for
252 use by the user. On success 0 is returned, otherwise -1 is returned
253 and a Python exception will be set. */
256 micmdpy_uninstall_command (micmdpy_object
*obj
)
258 PYMICMD_SCOPED_DEBUG_ENTER_EXIT
;
260 gdb_assert (obj
->mi_command
!= nullptr);
261 gdb_assert (obj
->mi_command_name
!= nullptr);
263 pymicmd_debug_printf ("name = %s", obj
->mi_command_name
);
265 /* Remove the command from the internal MI table of commands. This will
266 cause the mi_command_py object to be deleted, which will clear the
268 bool removed
= remove_mi_cmd_entry (obj
->mi_command
->name ());
269 gdb_assert (removed
);
270 gdb_assert (obj
->mi_command
== nullptr);
275 /* Install OBJ as a usable MI command. Return 0 on success, and -1 on
276 error, in which case, a Python error will have been set.
278 After successful completion the command name associated with OBJ will
279 be installed in the MI command table (so it can be found if the user
280 enters that command name), additionally, OBJ will have been added to
281 the gdb._mi_commands dictionary (using the command name as its key),
282 this will ensure that OBJ remains live even if the user gives up all
286 micmdpy_install_command (micmdpy_object
*obj
)
288 PYMICMD_SCOPED_DEBUG_ENTER_EXIT
;
290 gdb_assert (obj
->mi_command
== nullptr);
291 gdb_assert (obj
->mi_command_name
!= nullptr);
293 pymicmd_debug_printf ("name = %s", obj
->mi_command_name
);
295 /* Look up this command name in MI_COMMANDS, a command with this name may
297 mi_command
*cmd
= mi_cmd_lookup (obj
->mi_command_name
);
298 mi_command_py
*cmd_py
= as_mi_command_py (cmd
);
300 if (cmd
!= nullptr && cmd_py
== nullptr)
302 /* There is already an MI command registered with that name, and it's not
303 a Python one. Forbid replacing a non-Python MI command. */
304 PyErr_SetString (PyExc_RuntimeError
,
305 _("unable to add command, name is already in use"));
309 if (cmd_py
!= nullptr)
311 /* There is already a Python MI command registered with that name, swap
312 in the new gdb.MICommand implementation. */
313 cmd_py
->swap_python_object (obj
);
317 /* There's no MI command registered with that name at all, create one. */
318 mi_command_py_up
mi_cmd (new mi_command_py (obj
->mi_command_name
, obj
));
320 /* Add the command to the gdb internal MI command table. */
321 bool result
= insert_mi_cmd_entry (std::move (mi_cmd
));
328 /* Implement gdb.MICommand.__init__. The init method takes the name of
329 the MI command as the first argument, which must be a string, starting
330 with a single dash. */
333 micmdpy_init (PyObject
*self
, PyObject
*args
, PyObject
*kwargs
)
335 PYMICMD_SCOPED_DEBUG_ENTER_EXIT
;
337 micmdpy_object
*cmd
= (micmdpy_object
*) self
;
339 static const char *keywords
[] = { "name", nullptr };
342 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kwargs
, "s", keywords
,
346 /* Validate command name */
347 const int name_len
= strlen (name
);
350 PyErr_SetString (PyExc_ValueError
, _("MI command name is empty."));
353 else if ((name_len
< 2) || (name
[0] != '-') || !isalnum (name
[1]))
355 PyErr_SetString (PyExc_ValueError
,
356 _("MI command name does not start with '-'"
357 " followed by at least one letter or digit."));
362 for (int i
= 2; i
< name_len
; i
++)
364 if (!isalnum (name
[i
]) && name
[i
] != '-')
368 _("MI command name contains invalid character: %c."),
374 /* Skip over the leading dash. For the rest of this function the
375 dash is not important. */
379 /* If this object already has a name set, then this object has been
380 initialized before. We handle this case a little differently. */
381 if (cmd
->mi_command_name
!= nullptr)
383 /* First, we don't allow the user to change the MI command name.
384 Supporting this would be tricky as we would need to delete the
385 mi_command_py from the MI command table, however, the user might
386 be trying to perform this reinitialization from within the very
387 command we're about to delete... it all gets very messy.
389 So, for now at least, we don't allow this. This doesn't seem like
390 an excessive restriction. */
391 if (strcmp (cmd
->mi_command_name
, name
) != 0)
395 _("can't reinitialize object with a different command name"));
399 /* If there's already an object registered with the MI command table,
400 then we're done. That object must be a mi_command_py, which
401 should reference back to this micmdpy_object. */
402 if (cmd
->mi_command
!= nullptr)
404 mi_command_py::validate_installation (cmd
);
409 cmd
->mi_command_name
= xstrdup (name
);
411 /* Now we can install this mi_command_py in the MI command table. */
412 return micmdpy_install_command (cmd
);
415 /* Called when a gdb.MICommand object is deallocated. */
418 micmdpy_dealloc (PyObject
*obj
)
420 PYMICMD_SCOPED_DEBUG_ENTER_EXIT
;
422 micmdpy_object
*cmd
= (micmdpy_object
*) obj
;
424 /* If the Python object failed to initialize, then the name field might
426 pymicmd_debug_printf ("obj = %p, name = %s", cmd
,
427 (cmd
->mi_command_name
== nullptr
428 ? "(null)" : cmd
->mi_command_name
));
430 /* As the mi_command_py object holds a reference to the micmdpy_object,
431 the only way the dealloc function can be called is if the mi_command_py
432 object has been deleted, in which case the following assert will
434 gdb_assert (cmd
->mi_command
== nullptr);
436 /* Free the memory that holds the command name. */
437 xfree (cmd
->mi_command_name
);
438 cmd
->mi_command_name
= nullptr;
440 /* Finally, free the memory for this Python object. */
441 Py_TYPE (obj
)->tp_free (obj
);
444 /* Python initialization for the MI commands components. */
446 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
447 gdbpy_initialize_micommands ()
449 micmdpy_object_type
.tp_new
= PyType_GenericNew
;
450 if (gdbpy_type_ready (&micmdpy_object_type
) < 0)
453 invoke_cst
= PyUnicode_FromString ("invoke");
454 if (invoke_cst
== nullptr)
460 /* Cleanup just before GDB shuts down the Python interpreter. */
463 gdbpy_finalize_micommands ()
465 /* mi_command_py objects hold references to micmdpy_object objects. They must
466 be dropped before the Python interpreter is finalized. Do so by removing
467 those MI command entries, thus deleting the mi_command_py objects. */
468 remove_mi_cmd_entries ([] (mi_command
*cmd
)
470 return as_mi_command_py (cmd
) != nullptr;
474 /* Get the gdb.MICommand.name attribute, returns a string, the name of this
478 micmdpy_get_name (PyObject
*self
, void *closure
)
480 struct micmdpy_object
*micmd_obj
= (struct micmdpy_object
*) self
;
482 gdb_assert (micmd_obj
->mi_command_name
!= nullptr);
483 std::string name_str
= string_printf ("-%s", micmd_obj
->mi_command_name
);
484 return PyUnicode_FromString (name_str
.c_str ());
487 /* Get the gdb.MICommand.installed property. Returns true if this MI
488 command is installed into the MI command table, otherwise returns
492 micmdpy_get_installed (PyObject
*self
, void *closure
)
494 struct micmdpy_object
*micmd_obj
= (struct micmdpy_object
*) self
;
496 if (micmd_obj
->mi_command
== nullptr)
501 /* Set the gdb.MICommand.installed property. The property can be set to
502 either true or false. Setting the property to true will cause the
503 command to be installed into the MI command table (if it isn't
504 already), while setting this property to false will cause the command
505 to be removed from the MI command table (if it is present). */
508 micmdpy_set_installed (PyObject
*self
, PyObject
*newvalue
, void *closure
)
510 struct micmdpy_object
*micmd_obj
= (struct micmdpy_object
*) self
;
512 if (!PyBool_Check (newvalue
))
514 PyErr_Format (PyExc_TypeError
,
515 _("gdb.MICommand.installed must be set to a bool, not %s"),
516 newvalue
== Py_None
? "None" : Py_TYPE(newvalue
)->tp_name
);
520 bool installed_p
= newvalue
== Py_True
;
522 if (installed_p
== (micmd_obj
->mi_command
!= nullptr))
526 return micmdpy_install_command (micmd_obj
);
528 return micmdpy_uninstall_command (micmd_obj
);
531 /* The gdb.MICommand properties. */
533 static gdb_PyGetSetDef micmdpy_object_getset
[] = {
534 { "name", micmdpy_get_name
, nullptr, "The command's name.", nullptr },
535 { "installed", micmdpy_get_installed
, micmdpy_set_installed
,
536 "Is this command installed for use.", nullptr },
537 { nullptr } /* Sentinel. */
540 /* The gdb.MICommand descriptor. */
542 PyTypeObject micmdpy_object_type
= {
543 PyVarObject_HEAD_INIT (nullptr, 0) "gdb.MICommand", /*tp_name */
544 sizeof (micmdpy_object
), /*tp_basicsize */
546 micmdpy_dealloc
, /*tp_dealloc */
553 0, /*tp_as_sequence */
554 0, /*tp_as_mapping */
561 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /*tp_flags */
562 "GDB mi-command object", /* tp_doc */
565 0, /* tp_richcompare */
566 0, /* tp_weaklistoffset */
571 micmdpy_object_getset
, /* tp_getset */
574 0, /* tp_descr_get */
575 0, /* tp_descr_set */
576 0, /* tp_dictoffset */
577 micmdpy_init
, /* tp_init */
581 void _initialize_py_micmd ();
583 _initialize_py_micmd ()
585 add_setshow_boolean_cmd
586 ("py-micmd", class_maintenance
, &pymicmd_debug
,
587 _("Set Python micmd debugging."),
588 _("Show Python micmd debugging."),
589 _("When on, Python micmd debugging is enabled."),
592 &setdebuglist
, &showdebuglist
);
595 GDBPY_INITIALIZE_FILE (gdbpy_initialize_micommands
, gdbpy_finalize_micommands
);