1 /* Python interface to inferiors. 2 3 Copyright (C) 2009-2023 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 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. 11 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. 16 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/>. */ 19 20 #include "defs.h" 21 #include "python-internal.h" 22 #include "process-stratum-target.h" 23 #include "inferior.h" 24 #include "observable.h" 25 #include "target-connection.h" 26 #include "py-events.h" 27 #include "py-event.h" 28 #include "arch-utils.h" 29 #include "remote.h" 30 #include "charset.h" 31 32 #include <map> 33 34 /* The Python object that represents a connection. */ 35 36 struct connection_object 37 { 38 PyObject_HEAD 39 40 /* The process target that represents this connection. When a 41 connection_object is created this field will always point at a valid 42 target. Later, if GDB stops using this target (the target is popped 43 from all target stacks) then this field is set to nullptr, which 44 indicates that this Python object is now in the invalid state (see 45 the is_valid() method below). */ 46 struct process_stratum_target *target; 47 }; 48 49 extern PyTypeObject connection_object_type 50 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("connection_object"); 51 52 extern PyTypeObject remote_connection_object_type 53 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("remote_connection_object"); 54 55 /* Require that CONNECTION be valid. */ 56 #define CONNPY_REQUIRE_VALID(connection) \ 57 do { \ 58 if (connection->target == nullptr) \ 59 { \ 60 PyErr_SetString (PyExc_RuntimeError, \ 61 _("Connection no longer exists.")); \ 62 return nullptr; \ 63 } \ 64 } while (0) 65 66 /* A map between process_stratum targets and the Python object representing 67 them. We actually hold a gdbpy_ref around the Python object so that 68 reference counts are handled correctly when entries are deleted. */ 69 static std::map<process_stratum_target *, 70 gdbpy_ref<connection_object>> all_connection_objects; 71 72 /* Return a reference to a gdb.TargetConnection object for TARGET. If 73 TARGET is nullptr then a reference to None is returned. 74 75 Previously created gdb.TargetConnection objects are cached, and 76 additional references to the same connection object can be returned with 77 later calls to this function. */ 78 79 gdbpy_ref<> 80 target_to_connection_object (process_stratum_target *target) 81 { 82 if (target == nullptr) 83 return gdbpy_ref<>::new_reference (Py_None); 84 85 gdbpy_ref <connection_object> conn_obj; 86 auto conn_obj_iter = all_connection_objects.find (target); 87 if (conn_obj_iter == all_connection_objects.end ()) 88 { 89 PyTypeObject *type; 90 91 if (is_remote_target (target)) 92 type = &remote_connection_object_type; 93 else 94 type = &connection_object_type; 95 96 conn_obj.reset (PyObject_New (connection_object, type)); 97 if (conn_obj == nullptr) 98 return nullptr; 99 conn_obj->target = target; 100 all_connection_objects.emplace (target, conn_obj); 101 } 102 else 103 conn_obj = conn_obj_iter->second; 104 105 gdb_assert (conn_obj != nullptr); 106 107 /* Repackage the result as a PyObject reference. */ 108 return gdbpy_ref<> ((PyObject *) conn_obj.release ()); 109 } 110 111 /* Return a list of gdb.TargetConnection objects, one for each currently 112 active connection. The returned list is in no particular order. */ 113 114 PyObject * 115 gdbpy_connections (PyObject *self, PyObject *args) 116 { 117 gdbpy_ref<> list (PyList_New (0)); 118 if (list == nullptr) 119 return nullptr; 120 121 for (process_stratum_target *target : all_non_exited_process_targets ()) 122 { 123 gdb_assert (target != nullptr); 124 125 gdbpy_ref<> conn = target_to_connection_object (target); 126 if (conn == nullptr) 127 return nullptr; 128 gdb_assert (conn.get () != Py_None); 129 130 if (PyList_Append (list.get (), conn.get ()) < 0) 131 return nullptr; 132 } 133 134 return list.release (); 135 } 136 137 /* Emit a connection event for TARGET to REGISTRY. Return 0 on success, or 138 a negative value on error. */ 139 140 static int 141 emit_connection_event (process_stratum_target *target, 142 eventregistry_object *registry) 143 { 144 gdbpy_ref<> event_obj 145 = create_event_object (&connection_event_object_type); 146 if (event_obj == nullptr) 147 return -1; 148 149 gdbpy_ref<> conn = target_to_connection_object (target); 150 if (evpy_add_attribute (event_obj.get (), "connection", conn.get ()) < 0) 151 return -1; 152 153 return evpy_emit_event (event_obj.get (), registry); 154 } 155 156 /* Callback for the connection_removed observer. */ 157 158 static void 159 connpy_connection_removed (process_stratum_target *target) 160 { 161 if (!gdb_python_initialized) 162 return; 163 164 gdbpy_enter enter_py; 165 166 if (!evregpy_no_listeners_p (gdb_py_events.connection_removed)) 167 if (emit_connection_event (target, gdb_py_events.connection_removed) < 0) 168 gdbpy_print_stack (); 169 170 auto conn_obj_iter = all_connection_objects.find (target); 171 if (conn_obj_iter != all_connection_objects.end ()) 172 { 173 gdbpy_ref <connection_object> conn_obj = conn_obj_iter->second; 174 conn_obj->target = nullptr; 175 all_connection_objects.erase (target); 176 } 177 } 178 179 /* Called when a gdb.TargetConnection object is deallocated. */ 180 181 static void 182 connpy_connection_dealloc (PyObject *obj) 183 { 184 connection_object *conn_obj = (connection_object *) obj; 185 186 /* As the all_connection_objects map holds a reference to each connection 187 object we can only enter the dealloc function when the reference in 188 all_connection_objects has been erased. 189 190 As we always set the target pointer back to nullptr before we erase 191 items from all_connection_objects then, when we get here, the target 192 pointer must be nullptr. */ 193 gdb_assert (conn_obj->target == nullptr); 194 195 Py_TYPE (obj)->tp_free (obj); 196 } 197 198 /* Implement repr() for gdb.TargetConnection. */ 199 200 static PyObject * 201 connpy_repr (PyObject *obj) 202 { 203 connection_object *self = (connection_object *) obj; 204 process_stratum_target *target = self->target; 205 206 if (target == nullptr) 207 return PyUnicode_FromFormat ("<%s (invalid)>", Py_TYPE (obj)->tp_name); 208 209 return PyUnicode_FromFormat ("<%s num=%d, what=\"%s\">", 210 Py_TYPE (obj)->tp_name, 211 target->connection_number, 212 make_target_connection_string (target).c_str ()); 213 } 214 215 /* Implementation of gdb.TargetConnection.is_valid() -> Boolean. Returns 216 True if this connection object is still associated with a 217 process_stratum_target, otherwise, returns False. */ 218 219 static PyObject * 220 connpy_is_valid (PyObject *self, PyObject *args) 221 { 222 connection_object *conn = (connection_object *) self; 223 224 if (conn->target == nullptr) 225 Py_RETURN_FALSE; 226 227 Py_RETURN_TRUE; 228 } 229 230 /* Return the id number of this connection. */ 231 232 static PyObject * 233 connpy_get_connection_num (PyObject *self, void *closure) 234 { 235 connection_object *conn = (connection_object *) self; 236 237 CONNPY_REQUIRE_VALID (conn); 238 239 auto num = conn->target->connection_number; 240 return gdb_py_object_from_longest (num).release (); 241 } 242 243 /* Return a string that gives the short name for this connection type. */ 244 245 static PyObject * 246 connpy_get_connection_type (PyObject *self, void *closure) 247 { 248 connection_object *conn = (connection_object *) self; 249 250 CONNPY_REQUIRE_VALID (conn); 251 252 const char *shortname = conn->target->shortname (); 253 return host_string_to_python_string (shortname).release (); 254 } 255 256 /* Return a string that gives a longer description of this connection type. */ 257 258 static PyObject * 259 connpy_get_description (PyObject *self, void *closure) 260 { 261 connection_object *conn = (connection_object *) self; 262 263 CONNPY_REQUIRE_VALID (conn); 264 265 const char *longname = conn->target->longname (); 266 return host_string_to_python_string (longname).release (); 267 } 268 269 /* Return a string that gives additional details about this connection, or 270 None, if there are no additional details for this connection type. */ 271 272 static PyObject * 273 connpy_get_connection_details (PyObject *self, void *closure) 274 { 275 connection_object *conn = (connection_object *) self; 276 277 CONNPY_REQUIRE_VALID (conn); 278 279 const char *details = conn->target->connection_string (); 280 if (details != nullptr) 281 return host_string_to_python_string (details).release (); 282 else 283 Py_RETURN_NONE; 284 } 285 286 /* Python specific initialization for this file. */ 287 288 int 289 gdbpy_initialize_connection (void) 290 { 291 if (PyType_Ready (&connection_object_type) < 0) 292 return -1; 293 294 if (gdb_pymodule_addobject (gdb_module, "TargetConnection", 295 (PyObject *) &connection_object_type) < 0) 296 return -1; 297 298 if (PyType_Ready (&remote_connection_object_type) < 0) 299 return -1; 300 301 if (gdb_pymodule_addobject (gdb_module, "RemoteTargetConnection", 302 (PyObject *) &remote_connection_object_type) < 0) 303 return -1; 304 305 return 0; 306 } 307 308 /* Set of callbacks used to implement gdb.send_packet. */ 309 310 struct py_send_packet_callbacks : public send_remote_packet_callbacks 311 { 312 /* Constructor, initialise the result to nullptr. It is invalid to try 313 and read the result before sending a packet and processing the 314 reply. */ 315 316 py_send_packet_callbacks () 317 : m_result (nullptr) 318 { /* Nothing. */ } 319 320 /* There's nothing to do when the packet is sent. */ 321 322 void sending (gdb::array_view<const char> &buf) override 323 { /* Nothing. */ } 324 325 /* When the result is returned create a Python object and assign this 326 into M_RESULT. If for any reason we can't create a Python object to 327 represent the result then M_RESULT is set to nullptr, and Python's 328 internal error flags will be set. If the result we got back from the 329 remote is empty then set the result to None. */ 330 331 void received (gdb::array_view<const char> &buf) override 332 { 333 if (buf.size () > 0 && buf.data ()[0] != '\0') 334 m_result.reset (PyBytes_FromStringAndSize (buf.data (), buf.size ())); 335 else 336 { 337 /* We didn't get back any result data; set the result to None. */ 338 Py_INCREF (Py_None); 339 m_result.reset (Py_None); 340 } 341 } 342 343 /* Get a reference to the result as a Python object. It is invalid to 344 call this before sending a packet to the remote and processing the 345 reply. 346 347 The result value is setup in the RECEIVED call above. If the RECEIVED 348 call causes an error then the result value will be set to nullptr, 349 and the error reason is left stored in Python's global error state. 350 351 It is important that the result is inspected immediately after sending 352 a packet to the remote, and any error fetched, calling any other 353 Python functions that might clear the error state, or rely on an error 354 not being set will cause undefined behaviour. */ 355 356 gdbpy_ref<> result () const 357 { 358 return m_result; 359 } 360 361 private: 362 363 /* A reference to the result value. */ 364 365 gdbpy_ref<> m_result; 366 }; 367 368 /* Implement RemoteTargetConnection.send_packet function. Send a packet to 369 the target identified by SELF. The connection must still be valid, and 370 the packet to be sent must be non-empty, otherwise an exception will be 371 thrown. */ 372 373 static PyObject * 374 connpy_send_packet (PyObject *self, PyObject *args, PyObject *kw) 375 { 376 connection_object *conn = (connection_object *) self; 377 378 CONNPY_REQUIRE_VALID (conn); 379 380 static const char *keywords[] = {"packet", nullptr}; 381 PyObject *packet_obj; 382 383 if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, 384 &packet_obj)) 385 return nullptr; 386 387 /* If the packet is a unicode string then convert it to a bytes object. */ 388 if (PyUnicode_Check (packet_obj)) 389 { 390 /* We encode the string to bytes using the ascii codec, if this fails 391 then a suitable error will have been set. */ 392 packet_obj = PyUnicode_AsASCIIString (packet_obj); 393 if (packet_obj == nullptr) 394 return nullptr; 395 } 396 397 /* Check the packet is now a bytes object. */ 398 if (!PyBytes_Check (packet_obj)) 399 { 400 PyErr_SetString (PyExc_TypeError, _("Packet is not a bytes object")); 401 return nullptr; 402 } 403 404 Py_ssize_t packet_len = 0; 405 char *packet_str_nonconst = nullptr; 406 if (PyBytes_AsStringAndSize (packet_obj, &packet_str_nonconst, 407 &packet_len) < 0) 408 return nullptr; 409 const char *packet_str = packet_str_nonconst; 410 gdb_assert (packet_str != nullptr); 411 412 if (packet_len == 0) 413 { 414 PyErr_SetString (PyExc_ValueError, _("Packet must not be empty")); 415 return nullptr; 416 } 417 418 try 419 { 420 scoped_restore_current_thread restore_thread; 421 switch_to_target_no_thread (conn->target); 422 423 gdb::array_view<const char> view (packet_str, packet_len); 424 py_send_packet_callbacks callbacks; 425 send_remote_packet (view, &callbacks); 426 PyObject *result = callbacks.result ().release (); 427 /* If we encountered an error converting the reply to a Python 428 object, then the result here can be nullptr. In that case, Python 429 should be aware that an error occurred. */ 430 gdb_assert ((result == nullptr) == (PyErr_Occurred () != nullptr)); 431 return result; 432 } 433 catch (const gdb_exception &except) 434 { 435 gdbpy_convert_exception (except); 436 return nullptr; 437 } 438 } 439 440 /* Global initialization for this file. */ 441 442 void _initialize_py_connection (); 443 void 444 _initialize_py_connection () 445 { 446 gdb::observers::connection_removed.attach (connpy_connection_removed, 447 "py-connection"); 448 } 449 450 /* Methods for the gdb.TargetConnection object type. */ 451 452 static PyMethodDef connection_object_methods[] = 453 { 454 { "is_valid", connpy_is_valid, METH_NOARGS, 455 "is_valid () -> Boolean.\n\ 456 Return true if this TargetConnection is valid, false if not." }, 457 { NULL } 458 }; 459 460 /* Methods for the gdb.RemoteTargetConnection object type. */ 461 462 static PyMethodDef remote_connection_object_methods[] = 463 { 464 { "send_packet", (PyCFunction) connpy_send_packet, 465 METH_VARARGS | METH_KEYWORDS, 466 "send_packet (PACKET) -> Bytes\n\ 467 Send PACKET to a remote target, return the reply as a bytes array." }, 468 { NULL } 469 }; 470 471 /* Attributes for the gdb.TargetConnection object type. */ 472 473 static gdb_PyGetSetDef connection_object_getset[] = 474 { 475 { "num", connpy_get_connection_num, NULL, 476 "ID number of this connection, as assigned by GDB.", NULL }, 477 { "type", connpy_get_connection_type, NULL, 478 "A short string that is the name for this connection type.", NULL }, 479 { "description", connpy_get_description, NULL, 480 "A longer string describing this connection type.", NULL }, 481 { "details", connpy_get_connection_details, NULL, 482 "A string containing additional connection details.", NULL }, 483 { NULL } 484 }; 485 486 /* Define the gdb.TargetConnection object type. */ 487 488 PyTypeObject connection_object_type = 489 { 490 PyVarObject_HEAD_INIT (NULL, 0) 491 "gdb.TargetConnection", /* tp_name */ 492 sizeof (connection_object), /* tp_basicsize */ 493 0, /* tp_itemsize */ 494 connpy_connection_dealloc, /* tp_dealloc */ 495 0, /* tp_print */ 496 0, /* tp_getattr */ 497 0, /* tp_setattr */ 498 0, /* tp_compare */ 499 connpy_repr, /* tp_repr */ 500 0, /* tp_as_number */ 501 0, /* tp_as_sequence */ 502 0, /* tp_as_mapping */ 503 0, /* tp_hash */ 504 0, /* tp_call */ 505 0, /* tp_str */ 506 0, /* tp_getattro */ 507 0, /* tp_setattro */ 508 0, /* tp_as_buffer */ 509 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ 510 "GDB target connection object", /* tp_doc */ 511 0, /* tp_traverse */ 512 0, /* tp_clear */ 513 0, /* tp_richcompare */ 514 0, /* tp_weaklistoffset */ 515 0, /* tp_iter */ 516 0, /* tp_iternext */ 517 connection_object_methods, /* tp_methods */ 518 0, /* tp_members */ 519 connection_object_getset, /* tp_getset */ 520 0, /* tp_base */ 521 0, /* tp_dict */ 522 0, /* tp_descr_get */ 523 0, /* tp_descr_set */ 524 0, /* tp_dictoffset */ 525 0, /* tp_init */ 526 0 /* tp_alloc */ 527 }; 528 529 /* Define the gdb.RemoteTargetConnection object type. */ 530 531 PyTypeObject remote_connection_object_type = 532 { 533 PyVarObject_HEAD_INIT (NULL, 0) 534 "gdb.RemoteTargetConnection", /* tp_name */ 535 sizeof (connection_object), /* tp_basicsize */ 536 0, /* tp_itemsize */ 537 connpy_connection_dealloc, /* tp_dealloc */ 538 0, /* tp_print */ 539 0, /* tp_getattr */ 540 0, /* tp_setattr */ 541 0, /* tp_compare */ 542 connpy_repr, /* tp_repr */ 543 0, /* tp_as_number */ 544 0, /* tp_as_sequence */ 545 0, /* tp_as_mapping */ 546 0, /* tp_hash */ 547 0, /* tp_call */ 548 0, /* tp_str */ 549 0, /* tp_getattro */ 550 0, /* tp_setattro */ 551 0, /* tp_as_buffer */ 552 Py_TPFLAGS_DEFAULT, /* tp_flags */ 553 "GDB remote target connection object", /* tp_doc */ 554 0, /* tp_traverse */ 555 0, /* tp_clear */ 556 0, /* tp_richcompare */ 557 0, /* tp_weaklistoffset */ 558 0, /* tp_iter */ 559 0, /* tp_iternext */ 560 remote_connection_object_methods, /* tp_methods */ 561 0, /* tp_members */ 562 0, /* tp_getset */ 563 &connection_object_type, /* tp_base */ 564 0, /* tp_dict */ 565 0, /* tp_descr_get */ 566 0, /* tp_descr_set */ 567 0, /* tp_dictoffset */ 568 0, /* tp_init */ 569 0 /* tp_alloc */ 570 }; 571