1 /* Python interface to inferiors.
3 Copyright (C) 2009-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 #include "python-internal.h"
21 #include "process-stratum-target.h"
23 #include "observable.h"
24 #include "target-connection.h"
25 #include "py-events.h"
27 #include "arch-utils.h"
33 /* The Python object that represents a connection. */
35 struct connection_object
39 /* The process target that represents this connection. When a
40 connection_object is created this field will always point at a valid
41 target. Later, if GDB stops using this target (the target is popped
42 from all target stacks) then this field is set to nullptr, which
43 indicates that this Python object is now in the invalid state (see
44 the is_valid() method below). */
45 struct process_stratum_target
*target
;
48 extern PyTypeObject connection_object_type
49 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("connection_object");
51 extern PyTypeObject remote_connection_object_type
52 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("remote_connection_object");
54 /* Require that CONNECTION be valid. */
55 #define CONNPY_REQUIRE_VALID(connection) \
57 if (connection->target == nullptr) \
59 PyErr_SetString (PyExc_RuntimeError, \
60 _("Connection no longer exists.")); \
65 /* A map between process_stratum targets and the Python object representing
66 them. We actually hold a gdbpy_ref around the Python object so that
67 reference counts are handled correctly when entries are deleted. */
68 static std::map
<process_stratum_target
*,
69 gdbpy_ref
<connection_object
>> all_connection_objects
;
71 /* Return a reference to a gdb.TargetConnection object for TARGET. If
72 TARGET is nullptr then a reference to None is returned.
74 Previously created gdb.TargetConnection objects are cached, and
75 additional references to the same connection object can be returned with
76 later calls to this function. */
79 target_to_connection_object (process_stratum_target
*target
)
81 if (target
== nullptr)
82 return gdbpy_ref
<>::new_reference (Py_None
);
84 gdbpy_ref
<connection_object
> conn_obj
;
85 auto conn_obj_iter
= all_connection_objects
.find (target
);
86 if (conn_obj_iter
== all_connection_objects
.end ())
90 if (is_remote_target (target
))
91 type
= &remote_connection_object_type
;
93 type
= &connection_object_type
;
95 conn_obj
.reset (PyObject_New (connection_object
, type
));
96 if (conn_obj
== nullptr)
98 conn_obj
->target
= target
;
99 all_connection_objects
.emplace (target
, conn_obj
);
102 conn_obj
= conn_obj_iter
->second
;
104 gdb_assert (conn_obj
!= nullptr);
106 /* Repackage the result as a PyObject reference. */
107 return gdbpy_ref
<> ((PyObject
*) conn_obj
.release ());
110 /* Return a list of gdb.TargetConnection objects, one for each currently
111 active connection. The returned list is in no particular order. */
114 gdbpy_connections (PyObject
*self
, PyObject
*args
)
116 gdbpy_ref
<> list (PyList_New (0));
120 for (process_stratum_target
*target
: all_non_exited_process_targets ())
122 gdb_assert (target
!= nullptr);
124 gdbpy_ref
<> conn
= target_to_connection_object (target
);
127 gdb_assert (conn
.get () != Py_None
);
129 if (PyList_Append (list
.get (), conn
.get ()) < 0)
133 return list
.release ();
136 /* Emit a connection event for TARGET to REGISTRY. Return 0 on success, or
137 a negative value on error. */
140 emit_connection_event (process_stratum_target
*target
,
141 eventregistry_object
*registry
)
143 gdbpy_ref
<> event_obj
144 = create_event_object (&connection_event_object_type
);
145 if (event_obj
== nullptr)
148 gdbpy_ref
<> conn
= target_to_connection_object (target
);
149 if (evpy_add_attribute (event_obj
.get (), "connection", conn
.get ()) < 0)
152 return evpy_emit_event (event_obj
.get (), registry
);
155 /* Callback for the connection_removed observer. */
158 connpy_connection_removed (process_stratum_target
*target
)
160 if (!gdb_python_initialized
)
163 gdbpy_enter enter_py
;
165 if (!evregpy_no_listeners_p (gdb_py_events
.connection_removed
))
166 if (emit_connection_event (target
, gdb_py_events
.connection_removed
) < 0)
167 gdbpy_print_stack ();
169 auto conn_obj_iter
= all_connection_objects
.find (target
);
170 if (conn_obj_iter
!= all_connection_objects
.end ())
172 gdbpy_ref
<connection_object
> conn_obj
= conn_obj_iter
->second
;
173 conn_obj
->target
= nullptr;
174 all_connection_objects
.erase (target
);
178 /* Called when a gdb.TargetConnection object is deallocated. */
181 connpy_connection_dealloc (PyObject
*obj
)
183 connection_object
*conn_obj
= (connection_object
*) obj
;
185 /* As the all_connection_objects map holds a reference to each connection
186 object we can only enter the dealloc function when the reference in
187 all_connection_objects has been erased.
189 As we always set the target pointer back to nullptr before we erase
190 items from all_connection_objects then, when we get here, the target
191 pointer must be nullptr. */
192 gdb_assert (conn_obj
->target
== nullptr);
194 Py_TYPE (obj
)->tp_free (obj
);
197 /* Implement repr() for gdb.TargetConnection. */
200 connpy_repr (PyObject
*obj
)
202 connection_object
*self
= (connection_object
*) obj
;
203 process_stratum_target
*target
= self
->target
;
205 if (target
== nullptr)
206 return gdb_py_invalid_object_repr (obj
);
208 return PyUnicode_FromFormat ("<%s num=%d, what=\"%s\">",
209 Py_TYPE (obj
)->tp_name
,
210 target
->connection_number
,
211 make_target_connection_string (target
).c_str ());
214 /* Implementation of gdb.TargetConnection.is_valid() -> Boolean. Returns
215 True if this connection object is still associated with a
216 process_stratum_target, otherwise, returns False. */
219 connpy_is_valid (PyObject
*self
, PyObject
*args
)
221 connection_object
*conn
= (connection_object
*) self
;
223 if (conn
->target
== nullptr)
229 /* Return the id number of this connection. */
232 connpy_get_connection_num (PyObject
*self
, void *closure
)
234 connection_object
*conn
= (connection_object
*) self
;
236 CONNPY_REQUIRE_VALID (conn
);
238 auto num
= conn
->target
->connection_number
;
239 return gdb_py_object_from_longest (num
).release ();
242 /* Return a string that gives the short name for this connection type. */
245 connpy_get_connection_type (PyObject
*self
, void *closure
)
247 connection_object
*conn
= (connection_object
*) self
;
249 CONNPY_REQUIRE_VALID (conn
);
251 const char *shortname
= conn
->target
->shortname ();
252 return host_string_to_python_string (shortname
).release ();
255 /* Return a string that gives a longer description of this connection type. */
258 connpy_get_description (PyObject
*self
, void *closure
)
260 connection_object
*conn
= (connection_object
*) self
;
262 CONNPY_REQUIRE_VALID (conn
);
264 const char *longname
= conn
->target
->longname ();
265 return host_string_to_python_string (longname
).release ();
268 /* Return a string that gives additional details about this connection, or
269 None, if there are no additional details for this connection type. */
272 connpy_get_connection_details (PyObject
*self
, void *closure
)
274 connection_object
*conn
= (connection_object
*) self
;
276 CONNPY_REQUIRE_VALID (conn
);
278 const char *details
= conn
->target
->connection_string ();
279 if (details
!= nullptr)
280 return host_string_to_python_string (details
).release ();
285 /* Python specific initialization for this file. */
287 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
288 gdbpy_initialize_connection (void)
290 if (gdbpy_type_ready (&connection_object_type
) < 0)
293 if (gdbpy_type_ready (&remote_connection_object_type
) < 0)
299 /* Set of callbacks used to implement gdb.send_packet. */
301 struct py_send_packet_callbacks
: public send_remote_packet_callbacks
303 /* Constructor, initialise the result to nullptr. It is invalid to try
304 and read the result before sending a packet and processing the
307 py_send_packet_callbacks ()
311 /* There's nothing to do when the packet is sent. */
313 void sending (gdb::array_view
<const char> &buf
) override
316 /* When the result is returned create a Python object and assign this
317 into M_RESULT. If for any reason we can't create a Python object to
318 represent the result then M_RESULT is set to nullptr, and Python's
319 internal error flags will be set. If the result we got back from the
320 remote is empty then set the result to None. */
322 void received (gdb::array_view
<const char> &buf
) override
324 if (buf
.size () > 0 && buf
.data ()[0] != '\0')
325 m_result
.reset (PyBytes_FromStringAndSize (buf
.data (), buf
.size ()));
328 /* We didn't get back any result data; set the result to None. */
330 m_result
.reset (Py_None
);
334 /* Get a reference to the result as a Python object. It is invalid to
335 call this before sending a packet to the remote and processing the
338 The result value is setup in the RECEIVED call above. If the RECEIVED
339 call causes an error then the result value will be set to nullptr,
340 and the error reason is left stored in Python's global error state.
342 It is important that the result is inspected immediately after sending
343 a packet to the remote, and any error fetched, calling any other
344 Python functions that might clear the error state, or rely on an error
345 not being set will cause undefined behaviour. */
347 gdbpy_ref
<> result () const
354 /* A reference to the result value. */
356 gdbpy_ref
<> m_result
;
359 /* Implement RemoteTargetConnection.send_packet function. Send a packet to
360 the target identified by SELF. The connection must still be valid, and
361 the packet to be sent must be non-empty, otherwise an exception will be
365 connpy_send_packet (PyObject
*self
, PyObject
*args
, PyObject
*kw
)
367 connection_object
*conn
= (connection_object
*) self
;
369 CONNPY_REQUIRE_VALID (conn
);
371 static const char *keywords
[] = {"packet", nullptr};
372 PyObject
*packet_obj
;
374 if (!gdb_PyArg_ParseTupleAndKeywords (args
, kw
, "O", keywords
,
378 /* If the packet is a unicode string then convert it to a bytes object. */
379 if (PyUnicode_Check (packet_obj
))
381 /* We encode the string to bytes using the ascii codec, if this fails
382 then a suitable error will have been set. */
383 packet_obj
= PyUnicode_AsASCIIString (packet_obj
);
384 if (packet_obj
== nullptr)
388 /* Check the packet is now a bytes object. */
389 if (!PyBytes_Check (packet_obj
))
391 PyErr_SetString (PyExc_TypeError
, _("Packet is not a bytes object"));
395 Py_ssize_t packet_len
= 0;
396 char *packet_str_nonconst
= nullptr;
397 if (PyBytes_AsStringAndSize (packet_obj
, &packet_str_nonconst
,
400 const char *packet_str
= packet_str_nonconst
;
401 gdb_assert (packet_str
!= nullptr);
405 PyErr_SetString (PyExc_ValueError
, _("Packet must not be empty"));
411 scoped_restore_current_thread restore_thread
;
412 switch_to_target_no_thread (conn
->target
);
414 gdb::array_view
<const char> view (packet_str
, packet_len
);
415 py_send_packet_callbacks callbacks
;
416 send_remote_packet (view
, &callbacks
);
417 PyObject
*result
= callbacks
.result ().release ();
418 /* If we encountered an error converting the reply to a Python
419 object, then the result here can be nullptr. In that case, Python
420 should be aware that an error occurred. */
421 gdb_assert ((result
== nullptr) == (PyErr_Occurred () != nullptr));
424 catch (const gdb_exception
&except
)
426 return gdbpy_handle_gdb_exception (nullptr, except
);
430 /* Global initialization for this file. */
432 void _initialize_py_connection ();
434 _initialize_py_connection ()
436 gdb::observers::connection_removed
.attach (connpy_connection_removed
,
440 GDBPY_INITIALIZE_FILE (gdbpy_initialize_connection
);
442 /* Methods for the gdb.TargetConnection object type. */
444 static PyMethodDef connection_object_methods
[] =
446 { "is_valid", connpy_is_valid
, METH_NOARGS
,
447 "is_valid () -> Boolean.\n\
448 Return true if this TargetConnection is valid, false if not." },
452 /* Methods for the gdb.RemoteTargetConnection object type. */
454 static PyMethodDef remote_connection_object_methods
[] =
456 { "send_packet", (PyCFunction
) connpy_send_packet
,
457 METH_VARARGS
| METH_KEYWORDS
,
458 "send_packet (PACKET) -> Bytes\n\
459 Send PACKET to a remote target, return the reply as a bytes array." },
463 /* Attributes for the gdb.TargetConnection object type. */
465 static gdb_PyGetSetDef connection_object_getset
[] =
467 { "num", connpy_get_connection_num
, NULL
,
468 "ID number of this connection, as assigned by GDB.", NULL
},
469 { "type", connpy_get_connection_type
, NULL
,
470 "A short string that is the name for this connection type.", NULL
},
471 { "description", connpy_get_description
, NULL
,
472 "A longer string describing this connection type.", NULL
},
473 { "details", connpy_get_connection_details
, NULL
,
474 "A string containing additional connection details.", NULL
},
478 /* Define the gdb.TargetConnection object type. */
480 PyTypeObject connection_object_type
=
482 PyVarObject_HEAD_INIT (NULL
, 0)
483 "gdb.TargetConnection", /* tp_name */
484 sizeof (connection_object
), /* tp_basicsize */
486 connpy_connection_dealloc
, /* tp_dealloc */
491 connpy_repr
, /* tp_repr */
492 0, /* tp_as_number */
493 0, /* tp_as_sequence */
494 0, /* tp_as_mapping */
500 0, /* tp_as_buffer */
501 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /* tp_flags */
502 "GDB target connection object", /* tp_doc */
505 0, /* tp_richcompare */
506 0, /* tp_weaklistoffset */
509 connection_object_methods
, /* tp_methods */
511 connection_object_getset
, /* tp_getset */
514 0, /* tp_descr_get */
515 0, /* tp_descr_set */
516 0, /* tp_dictoffset */
521 /* Define the gdb.RemoteTargetConnection object type. */
523 PyTypeObject remote_connection_object_type
=
525 PyVarObject_HEAD_INIT (NULL
, 0)
526 "gdb.RemoteTargetConnection", /* tp_name */
527 sizeof (connection_object
), /* tp_basicsize */
529 connpy_connection_dealloc
, /* tp_dealloc */
534 connpy_repr
, /* tp_repr */
535 0, /* tp_as_number */
536 0, /* tp_as_sequence */
537 0, /* tp_as_mapping */
543 0, /* tp_as_buffer */
544 Py_TPFLAGS_DEFAULT
, /* tp_flags */
545 "GDB remote target connection object", /* tp_doc */
548 0, /* tp_richcompare */
549 0, /* tp_weaklistoffset */
552 remote_connection_object_methods
, /* tp_methods */
555 &connection_object_type
, /* tp_base */
557 0, /* tp_descr_get */
558 0, /* tp_descr_set */
559 0, /* tp_dictoffset */