1 1.1 christos /* Python interface to MI commands 2 1.1 christos 3 1.1 christos Copyright (C) 2023-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of GDB. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos #include "python-internal.h" 21 1.1 christos #include "py-uiout.h" 22 1.1 christos #include "utils.h" 23 1.1 christos #include "ui.h" 24 1.1 christos #include "interps.h" 25 1.1 christos #include "target.h" 26 1.1 christos #include "mi/mi-parse.h" 27 1.1 christos #include "mi/mi-console.h" 28 1.1 christos #include "mi/mi-interp.h" 29 1.1 christos 30 1.1 christos void 31 1.1 christos py_ui_out::add_field (const char *name, const gdbpy_ref<> &obj) 32 1.1 christos { 33 1.1 christos if (obj == nullptr) 34 1.1 christos { 35 1.1 christos m_error.emplace (); 36 1.1 christos return; 37 1.1 christos } 38 1.1 christos 39 1.1 christos object_desc &desc = current (); 40 1.1 christos if (desc.type == ui_out_type_list) 41 1.1 christos { 42 1.1 christos if (PyList_Append (desc.obj.get (), obj.get ()) < 0) 43 1.1 christos m_error.emplace (); 44 1.1 christos } 45 1.1 christos else 46 1.1 christos { 47 1.1 christos if (PyDict_SetItemString (desc.obj.get (), name, obj.get ()) < 0) 48 1.1 christos m_error.emplace (); 49 1.1 christos } 50 1.1 christos } 51 1.1 christos 52 1.1 christos void 53 1.1 christos py_ui_out::do_begin (ui_out_type type, const char *id) 54 1.1 christos { 55 1.1 christos if (m_error.has_value ()) 56 1.1 christos return; 57 1.1 christos 58 1.1 christos gdbpy_ref<> new_obj (type == ui_out_type_list 59 1.1 christos ? PyList_New (0) 60 1.1 christos : PyDict_New ()); 61 1.1 christos if (new_obj == nullptr) 62 1.1 christos { 63 1.1 christos m_error.emplace (); 64 1.1 christos return; 65 1.1 christos } 66 1.1 christos 67 1.1 christos object_desc new_desc; 68 1.1 christos if (id != nullptr) 69 1.1 christos new_desc.field_name = id; 70 1.1 christos new_desc.obj = std::move (new_obj); 71 1.1 christos new_desc.type = type; 72 1.1 christos 73 1.1 christos m_objects.push_back (std::move (new_desc)); 74 1.1 christos } 75 1.1 christos 76 1.1 christos void 77 1.1 christos py_ui_out::do_end (ui_out_type type) 78 1.1 christos { 79 1.1 christos if (m_error.has_value ()) 80 1.1 christos return; 81 1.1 christos 82 1.1 christos object_desc new_obj = std::move (current ()); 83 1.1 christos m_objects.pop_back (); 84 1.1 christos add_field (new_obj.field_name.c_str (), new_obj.obj); 85 1.1 christos } 86 1.1 christos 87 1.1 christos void 88 1.1 christos py_ui_out::do_field_signed (int fldno, int width, ui_align align, 89 1.1 christos const char *fldname, LONGEST value) 90 1.1 christos { 91 1.1 christos if (m_error.has_value ()) 92 1.1 christos return; 93 1.1 christos 94 1.1 christos gdbpy_ref<> val = gdb_py_object_from_longest (value); 95 1.1 christos add_field (fldname, val); 96 1.1 christos } 97 1.1 christos 98 1.1 christos void 99 1.1 christos py_ui_out::do_field_unsigned (int fldno, int width, ui_align align, 100 1.1 christos const char *fldname, ULONGEST value) 101 1.1 christos { 102 1.1 christos if (m_error.has_value ()) 103 1.1 christos return; 104 1.1 christos 105 1.1 christos gdbpy_ref<> val = gdb_py_object_from_ulongest (value); 106 1.1 christos add_field (fldname, val); 107 1.1 christos } 108 1.1 christos 109 1.1 christos void 110 1.1 christos py_ui_out::do_field_string (int fldno, int width, ui_align align, 111 1.1 christos const char *fldname, const char *string, 112 1.1 christos const ui_file_style &style) 113 1.1 christos { 114 1.1 christos if (m_error.has_value ()) 115 1.1 christos return; 116 1.1 christos 117 1.1 christos gdbpy_ref<> val = host_string_to_python_string (string); 118 1.1 christos add_field (fldname, val); 119 1.1 christos } 120 1.1 christos 121 1.1 christos void 122 1.1 christos py_ui_out::do_field_fmt (int fldno, int width, ui_align align, 123 1.1 christos const char *fldname, const ui_file_style &style, 124 1.1 christos const char *format, va_list args) 125 1.1 christos { 126 1.1 christos if (m_error.has_value ()) 127 1.1 christos return; 128 1.1 christos 129 1.1 christos std::string str = string_vprintf (format, args); 130 1.1 christos do_field_string (fldno, width, align, fldname, str.c_str (), style); 131 1.1 christos } 132 1.1 christos 133 1.1 christos /* Implementation of the gdb.execute_mi command. */ 134 1.1 christos 135 1.1 christos PyObject * 136 1.1 christos gdbpy_execute_mi_command (PyObject *self, PyObject *args, PyObject *kw) 137 1.1 christos { 138 1.1 christos gdb::unique_xmalloc_ptr<char> mi_command; 139 1.1 christos std::vector<gdb::unique_xmalloc_ptr<char>> arg_strings; 140 1.1 christos 141 1.1 christos Py_ssize_t n_args = PyTuple_Size (args); 142 1.1 christos if (n_args < 0) 143 1.1 christos return nullptr; 144 1.1 christos 145 1.1 christos for (Py_ssize_t i = 0; i < n_args; ++i) 146 1.1 christos { 147 1.1 christos /* Note this returns a borrowed reference. */ 148 1.1 christos PyObject *arg = PyTuple_GetItem (args, i); 149 1.1 christos if (arg == nullptr) 150 1.1 christos return nullptr; 151 1.1 christos gdb::unique_xmalloc_ptr<char> str = python_string_to_host_string (arg); 152 1.1 christos if (str == nullptr) 153 1.1 christos return nullptr; 154 1.1 christos if (i == 0) 155 1.1 christos mi_command = std::move (str); 156 1.1 christos else 157 1.1 christos arg_strings.push_back (std::move (str)); 158 1.1 christos } 159 1.1 christos 160 1.1 christos py_ui_out uiout; 161 1.1 christos 162 1.1 christos try 163 1.1 christos { 164 1.1 christos scoped_restore save_uiout = make_scoped_restore (¤t_uiout, &uiout); 165 1.1 christos auto parser = std::make_unique<mi_parse> (std::move (mi_command), 166 1.1 christos std::move (arg_strings)); 167 1.1 christos mi_execute_command (parser.get ()); 168 1.1 christos } 169 1.1 christos catch (const gdb_exception &except) 170 1.1 christos { 171 1.1 christos gdbpy_convert_exception (except); 172 1.1 christos return nullptr; 173 1.1 christos } 174 1.1 christos 175 1.1 christos return uiout.result ().release (); 176 1.1 christos } 177 1.1 christos 178 1.1 christos /* Convert KEY_OBJ into a string that can be used as a field name in MI 179 1.1 christos output. KEY_OBJ must be a Python string object, and must only contain 180 1.1 christos characters suitable for use as an MI field name. 181 1.1 christos 182 1.1 christos If KEY_OBJ is not a string, or if KEY_OBJ contains invalid characters, 183 1.1 christos then an error is thrown. Otherwise, KEY_OBJ is converted to a string 184 1.1 christos and returned. */ 185 1.1 christos 186 1.1 christos static gdb::unique_xmalloc_ptr<char> 187 1.1 christos py_object_to_mi_key (PyObject *key_obj) 188 1.1 christos { 189 1.1 christos /* The key must be a string. */ 190 1.1 christos if (!PyUnicode_Check (key_obj)) 191 1.1 christos { 192 1.1 christos gdbpy_ref<> key_repr (PyObject_Repr (key_obj)); 193 1.1 christos gdb::unique_xmalloc_ptr<char> key_repr_string; 194 1.1 christos if (key_repr != nullptr) 195 1.1 christos key_repr_string = python_string_to_target_string (key_repr.get ()); 196 1.1 christos if (key_repr_string == nullptr) 197 1.1 christos gdbpy_handle_exception (); 198 1.1 christos 199 1.1 christos gdbpy_error (_("non-string object used as key: %s"), 200 1.1 christos key_repr_string.get ()); 201 1.1 christos } 202 1.1 christos 203 1.1 christos gdb::unique_xmalloc_ptr<char> key_string 204 1.1 christos = python_string_to_target_string (key_obj); 205 1.1 christos if (key_string == nullptr) 206 1.1 christos gdbpy_handle_exception (); 207 1.1 christos 208 1.1 christos /* Predicate function, returns true if NAME is a valid field name for use 209 1.1 christos in MI result output, otherwise, returns false. */ 210 1.1 christos auto is_valid_key_name = [] (const char *name) -> bool 211 1.1 christos { 212 1.1 christos gdb_assert (name != nullptr); 213 1.1 christos 214 1.1 christos if (*name == '\0' || !isalpha (*name)) 215 1.1 christos return false; 216 1.1 christos 217 1.1 christos for (; *name != '\0'; ++name) 218 1.1 christos if (!isalnum (*name) && *name != '_' && *name != '-') 219 1.1 christos return false; 220 1.1 christos 221 1.1 christos return true; 222 1.1 christos }; 223 1.1 christos 224 1.1 christos if (!is_valid_key_name (key_string.get ())) 225 1.1 christos { 226 1.1 christos if (*key_string.get () == '\0') 227 1.1 christos gdbpy_error (_("Invalid empty key in MI result")); 228 1.1 christos else 229 1.1 christos gdbpy_error (_("Invalid key in MI result: %s"), key_string.get ()); 230 1.1 christos } 231 1.1 christos 232 1.1 christos return key_string; 233 1.1 christos } 234 1.1 christos 235 1.1 christos /* Serialize RESULT and print it in MI format to the current_uiout. 236 1.1 christos FIELD_NAME is used as the name of this result field. 237 1.1 christos 238 1.1 christos RESULT can be a dictionary, a sequence, an iterator, or an object that 239 1.1 christos can be converted to a string, these are converted to the matching MI 240 1.1 christos output format (dictionaries as tuples, sequences and iterators as lists, 241 1.1 christos and strings as named fields). 242 1.1 christos 243 1.1 christos If anything goes wrong while formatting the output then an error is 244 1.1 christos thrown. 245 1.1 christos 246 1.1 christos This function is the recursive inner core of serialize_mi_result, and 247 1.1 christos should only be called from that function. */ 248 1.1 christos 249 1.1 christos static void 250 1.1 christos serialize_mi_result_1 (PyObject *result, const char *field_name) 251 1.1 christos { 252 1.1 christos struct ui_out *uiout = current_uiout; 253 1.1 christos 254 1.1 christos if (PyDict_Check (result)) 255 1.1 christos { 256 1.1 christos PyObject *key, *value; 257 1.1 christos Py_ssize_t pos = 0; 258 1.1 christos ui_out_emit_tuple tuple_emitter (uiout, field_name); 259 1.1 christos while (PyDict_Next (result, &pos, &key, &value)) 260 1.1 christos { 261 1.1 christos gdb::unique_xmalloc_ptr<char> key_string 262 1.1 christos (py_object_to_mi_key (key)); 263 1.1 christos serialize_mi_result_1 (value, key_string.get ()); 264 1.1 christos } 265 1.1 christos } 266 1.1 christos else if (PySequence_Check (result) && !PyUnicode_Check (result)) 267 1.1 christos { 268 1.1 christos ui_out_emit_list list_emitter (uiout, field_name); 269 1.1 christos Py_ssize_t len = PySequence_Size (result); 270 1.1 christos if (len == -1) 271 1.1 christos gdbpy_handle_exception (); 272 1.1 christos for (Py_ssize_t i = 0; i < len; ++i) 273 1.1 christos { 274 1.1 christos gdbpy_ref<> item (PySequence_ITEM (result, i)); 275 1.1 christos if (item == nullptr) 276 1.1 christos gdbpy_handle_exception (); 277 1.1 christos serialize_mi_result_1 (item.get (), nullptr); 278 1.1 christos } 279 1.1 christos } 280 1.1 christos else if (PyIter_Check (result)) 281 1.1 christos { 282 1.1 christos gdbpy_ref<> item; 283 1.1 christos ui_out_emit_list list_emitter (uiout, field_name); 284 1.1 christos while (true) 285 1.1 christos { 286 1.1 christos item.reset (PyIter_Next (result)); 287 1.1 christos if (item == nullptr) 288 1.1 christos { 289 1.1 christos if (PyErr_Occurred () != nullptr) 290 1.1 christos gdbpy_handle_exception (); 291 1.1 christos break; 292 1.1 christos } 293 1.1 christos serialize_mi_result_1 (item.get (), nullptr); 294 1.1 christos } 295 1.1 christos } 296 1.1 christos else 297 1.1 christos { 298 1.1 christos if (PyLong_Check (result)) 299 1.1 christos { 300 1.1 christos int overflow = 0; 301 1.1 christos gdb_py_longest val = gdb_py_long_as_long_and_overflow (result, 302 1.1 christos &overflow); 303 1.1 christos if (PyErr_Occurred () != nullptr) 304 1.1 christos gdbpy_handle_exception (); 305 1.1 christos if (overflow == 0) 306 1.1 christos { 307 1.1 christos uiout->field_signed (field_name, val); 308 1.1 christos return; 309 1.1 christos } 310 1.1 christos /* Fall through to the string case on overflow. */ 311 1.1 christos } 312 1.1 christos 313 1.1 christos gdb::unique_xmalloc_ptr<char> string (gdbpy_obj_to_string (result)); 314 1.1 christos if (string == nullptr) 315 1.1 christos gdbpy_handle_exception (); 316 1.1 christos uiout->field_string (field_name, string.get ()); 317 1.1 christos } 318 1.1 christos } 319 1.1 christos 320 1.1 christos /* See python-internal.h. */ 321 1.1 christos 322 1.1 christos void 323 1.1 christos serialize_mi_results (PyObject *results) 324 1.1 christos { 325 1.1 christos gdb_assert (PyDict_Check (results)); 326 1.1 christos 327 1.1 christos PyObject *key, *value; 328 1.1 christos Py_ssize_t pos = 0; 329 1.1 christos while (PyDict_Next (results, &pos, &key, &value)) 330 1.1 christos { 331 1.1 christos gdb::unique_xmalloc_ptr<char> key_string 332 1.1 christos (py_object_to_mi_key (key)); 333 1.1 christos serialize_mi_result_1 (value, key_string.get ()); 334 1.1 christos } 335 1.1 christos } 336 1.1 christos 337 1.1 christos /* See python-internal.h. */ 338 1.1 christos 339 1.1 christos PyObject * 340 1.1 christos gdbpy_notify_mi (PyObject *self, PyObject *args, PyObject *kwargs) 341 1.1 christos { 342 1.1 christos static const char *keywords[] = { "name", "data", nullptr }; 343 1.1 christos char *name = nullptr; 344 1.1 christos PyObject *data = Py_None; 345 1.1 christos 346 1.1 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "s|O", keywords, 347 1.1 christos &name, &data)) 348 1.1 christos return nullptr; 349 1.1 christos 350 1.1 christos /* Validate notification name. */ 351 1.1 christos const int name_len = strlen (name); 352 1.1 christos if (name_len == 0) 353 1.1 christos { 354 1.1 christos PyErr_SetString (PyExc_ValueError, _("MI notification name is empty.")); 355 1.1 christos return nullptr; 356 1.1 christos } 357 1.1 christos for (int i = 0; i < name_len; i++) 358 1.1 christos { 359 1.1 christos if (!isalnum (name[i]) && name[i] != '-') 360 1.1 christos { 361 1.1 christos PyErr_Format 362 1.1 christos (PyExc_ValueError, 363 1.1 christos _("MI notification name contains invalid character: %c."), 364 1.1 christos name[i]); 365 1.1 christos return nullptr; 366 1.1 christos } 367 1.1 christos } 368 1.1 christos 369 1.1 christos /* Validate additional data. */ 370 1.1 christos if (!(data == Py_None || PyDict_Check (data))) 371 1.1 christos { 372 1.1 christos PyErr_Format 373 1.1 christos (PyExc_ValueError, 374 1.1 christos _("MI notification data must be either None or a dictionary, not %s"), 375 1.1 christos Py_TYPE (data)->tp_name); 376 1.1 christos return nullptr; 377 1.1 christos } 378 1.1 christos 379 1.1 christos SWITCH_THRU_ALL_UIS () 380 1.1 christos { 381 1.1 christos struct mi_interp *mi = as_mi_interp (top_level_interpreter ()); 382 1.1 christos 383 1.1 christos if (mi == nullptr) 384 1.1 christos continue; 385 1.1 christos 386 1.1 christos target_terminal::scoped_restore_terminal_state term_state; 387 1.1 christos target_terminal::ours_for_output (); 388 1.1 christos 389 1.1 christos gdb_printf (mi->event_channel, "%s", name); 390 1.1 christos if (data != Py_None) 391 1.1 christos { 392 1.1 christos ui_out *mi_uiout = mi->interp_ui_out (); 393 1.1 christos ui_out_redirect_pop redir (mi_uiout, mi->event_channel); 394 1.1 christos scoped_restore restore_uiout 395 1.1 christos = make_scoped_restore (¤t_uiout, mi_uiout); 396 1.1 christos 397 1.1 christos serialize_mi_results (data); 398 1.1 christos } 399 1.1 christos gdb_flush (mi->event_channel); 400 1.1 christos } 401 1.1 christos 402 1.1 christos Py_RETURN_NONE; 403 1.1 christos } 404