Simplify DAP make_source callers
[binutils-gdb.git] / gdb / python / py-micmd.c
blob54427d4633b192b5d73965a7c66f44e813f894c3
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"
24 #include "charset.h"
25 #include "language.h"
26 #include "mi/mi-cmds.h"
27 #include "mi/mi-parse.h"
28 #include "cli/cli-cmds.h"
29 #include <string>
31 /* Debugging of Python MI commands. */
33 static bool pymicmd_debug;
35 /* Implementation of "show debug py-micmd". */
37 static void
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")
54 struct mi_command_py;
56 /* Representation of a Python gdb.MICommand object. */
58 struct micmdpy_object
60 PyObject_HEAD
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
69 initialised.
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;
96 ~mi_command_py ()
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++
101 object.
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
154 object. */
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;
161 private:
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. */
178 void
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 (),
189 parse->args ());
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);
211 gdbpy_ref<> results
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. */
228 void
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
243 nullptr. */
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. */
255 static int
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
267 backlink in OBJ. */
268 bool removed = remove_mi_cmd_entry (obj->mi_command->name ());
269 gdb_assert (removed);
270 gdb_assert (obj->mi_command == nullptr);
272 return 0;
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
283 references. */
285 static int
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
296 already exist. */
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"));
306 return -1;
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);
315 else
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));
322 gdb_assert (result);
325 return 0;
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. */
332 static int
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 };
340 const char *name;
342 if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "s", keywords,
343 &name))
344 return -1;
346 /* Validate command name */
347 const int name_len = strlen (name);
348 if (name_len == 0)
350 PyErr_SetString (PyExc_ValueError, _("MI command name is empty."));
351 return -1;
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."));
358 return -1;
360 else
362 for (int i = 2; i < name_len; i++)
364 if (!isalnum (name[i]) && name[i] != '-')
366 PyErr_Format
367 (PyExc_ValueError,
368 _("MI command name contains invalid character: %c."),
369 name[i]);
370 return -1;
374 /* Skip over the leading dash. For the rest of this function the
375 dash is not important. */
376 ++name;
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)
393 PyErr_SetString
394 (PyExc_ValueError,
395 _("can't reinitialize object with a different command name"));
396 return -1;
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);
405 return 0;
408 else
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. */
417 static void
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
425 be nullptr. */
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
433 hold. */
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 (PyType_Ready (&micmdpy_object_type) < 0)
451 return -1;
453 if (gdb_pymodule_addobject (gdb_module, "MICommand",
454 (PyObject *) &micmdpy_object_type)
455 < 0)
456 return -1;
458 invoke_cst = PyUnicode_FromString ("invoke");
459 if (invoke_cst == nullptr)
460 return -1;
462 return 0;
465 /* Cleanup just before GDB shuts down the Python interpreter. */
467 static void
468 gdbpy_finalize_micommands ()
470 /* mi_command_py objects hold references to micmdpy_object objects. They must
471 be dropped before the Python interpreter is finalized. Do so by removing
472 those MI command entries, thus deleting the mi_command_py objects. */
473 remove_mi_cmd_entries ([] (mi_command *cmd)
475 return as_mi_command_py (cmd) != nullptr;
479 /* Get the gdb.MICommand.name attribute, returns a string, the name of this
480 MI command. */
482 static PyObject *
483 micmdpy_get_name (PyObject *self, void *closure)
485 struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self;
487 gdb_assert (micmd_obj->mi_command_name != nullptr);
488 std::string name_str = string_printf ("-%s", micmd_obj->mi_command_name);
489 return PyUnicode_FromString (name_str.c_str ());
492 /* Get the gdb.MICommand.installed property. Returns true if this MI
493 command is installed into the MI command table, otherwise returns
494 false. */
496 static PyObject *
497 micmdpy_get_installed (PyObject *self, void *closure)
499 struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self;
501 if (micmd_obj->mi_command == nullptr)
502 Py_RETURN_FALSE;
503 Py_RETURN_TRUE;
506 /* Set the gdb.MICommand.installed property. The property can be set to
507 either true or false. Setting the property to true will cause the
508 command to be installed into the MI command table (if it isn't
509 already), while setting this property to false will cause the command
510 to be removed from the MI command table (if it is present). */
512 static int
513 micmdpy_set_installed (PyObject *self, PyObject *newvalue, void *closure)
515 struct micmdpy_object *micmd_obj = (struct micmdpy_object *) self;
517 bool installed_p = PyObject_IsTrue (newvalue);
518 if (installed_p == (micmd_obj->mi_command != nullptr))
519 return 0;
521 if (installed_p)
522 return micmdpy_install_command (micmd_obj);
523 else
524 return micmdpy_uninstall_command (micmd_obj);
527 /* The gdb.MICommand properties. */
529 static gdb_PyGetSetDef micmdpy_object_getset[] = {
530 { "name", micmdpy_get_name, nullptr, "The command's name.", nullptr },
531 { "installed", micmdpy_get_installed, micmdpy_set_installed,
532 "Is this command installed for use.", nullptr },
533 { nullptr } /* Sentinel. */
536 /* The gdb.MICommand descriptor. */
538 PyTypeObject micmdpy_object_type = {
539 PyVarObject_HEAD_INIT (nullptr, 0) "gdb.MICommand", /*tp_name */
540 sizeof (micmdpy_object), /*tp_basicsize */
541 0, /*tp_itemsize */
542 micmdpy_dealloc, /*tp_dealloc */
543 0, /*tp_print */
544 0, /*tp_getattr */
545 0, /*tp_setattr */
546 0, /*tp_compare */
547 0, /*tp_repr */
548 0, /*tp_as_number */
549 0, /*tp_as_sequence */
550 0, /*tp_as_mapping */
551 0, /*tp_hash */
552 0, /*tp_call */
553 0, /*tp_str */
554 0, /*tp_getattro */
555 0, /*tp_setattro */
556 0, /*tp_as_buffer */
557 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags */
558 "GDB mi-command object", /* tp_doc */
559 0, /* tp_traverse */
560 0, /* tp_clear */
561 0, /* tp_richcompare */
562 0, /* tp_weaklistoffset */
563 0, /* tp_iter */
564 0, /* tp_iternext */
565 0, /* tp_methods */
566 0, /* tp_members */
567 micmdpy_object_getset, /* tp_getset */
568 0, /* tp_base */
569 0, /* tp_dict */
570 0, /* tp_descr_get */
571 0, /* tp_descr_set */
572 0, /* tp_dictoffset */
573 micmdpy_init, /* tp_init */
574 0, /* tp_alloc */
577 void _initialize_py_micmd ();
578 void
579 _initialize_py_micmd ()
581 add_setshow_boolean_cmd
582 ("py-micmd", class_maintenance, &pymicmd_debug,
583 _("Set Python micmd debugging."),
584 _("Show Python micmd debugging."),
585 _("When on, Python micmd debugging is enabled."),
586 nullptr,
587 show_pymicmd_debug,
588 &setdebuglist, &showdebuglist);
591 GDBPY_INITIALIZE_FILE (gdbpy_initialize_micommands, gdbpy_finalize_micommands);