py-inferior.c revision 1.11 1 1.1 christos /* Python interface to inferiors.
2 1.1 christos
3 1.11 christos Copyright (C) 2009-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.10 christos #include "auto-load.h"
21 1.1 christos #include "gdbcore.h"
22 1.1 christos #include "gdbthread.h"
23 1.1 christos #include "inferior.h"
24 1.1 christos #include "objfiles.h"
25 1.8 christos #include "observable.h"
26 1.1 christos #include "python-internal.h"
27 1.1 christos #include "arch-utils.h"
28 1.1 christos #include "language.h"
29 1.9 christos #include "gdbsupport/gdb_signals.h"
30 1.1 christos #include "py-event.h"
31 1.1 christos #include "py-stopevent.h"
32 1.11 christos #include "progspace-and-thread.h"
33 1.10 christos #include <unordered_map>
34 1.1 christos
35 1.10 christos using thread_map_t
36 1.10 christos = std::unordered_map<thread_info *, gdbpy_ref<thread_object>>;
37 1.1 christos
38 1.8 christos struct inferior_object
39 1.1 christos {
40 1.1 christos PyObject_HEAD
41 1.1 christos
42 1.1 christos /* The inferior we represent. */
43 1.1 christos struct inferior *inferior;
44 1.1 christos
45 1.10 christos /* thread_object instances under this inferior. This owns a
46 1.1 christos reference to each object it contains. */
47 1.10 christos thread_map_t *threads;
48 1.11 christos
49 1.11 christos /* Dictionary holding user-added attributes.
50 1.11 christos This is the __dict__ attribute of the object. */
51 1.11 christos PyObject *dict;
52 1.8 christos };
53 1.1 christos
54 1.5 christos extern PyTypeObject inferior_object_type
55 1.1 christos CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
56 1.1 christos
57 1.10 christos /* Deleter to clean up when an inferior is removed. */
58 1.10 christos struct infpy_deleter
59 1.10 christos {
60 1.10 christos void operator() (inferior_object *obj)
61 1.10 christos {
62 1.10 christos if (!gdb_python_initialized)
63 1.10 christos return;
64 1.1 christos
65 1.10 christos gdbpy_enter enter_py;
66 1.10 christos gdbpy_ref<inferior_object> inf_obj (obj);
67 1.10 christos
68 1.10 christos inf_obj->inferior = NULL;
69 1.1 christos
70 1.10 christos delete inf_obj->threads;
71 1.10 christos }
72 1.10 christos };
73 1.1 christos
74 1.10 christos static const registry<inferior>::key<inferior_object, infpy_deleter>
75 1.10 christos infpy_inf_data_key;
76 1.1 christos
77 1.1 christos /* Require that INFERIOR be a valid inferior ID. */
78 1.1 christos #define INFPY_REQUIRE_VALID(Inferior) \
79 1.1 christos do { \
80 1.1 christos if (!Inferior->inferior) \
81 1.1 christos { \
82 1.1 christos PyErr_SetString (PyExc_RuntimeError, \
83 1.1 christos _("Inferior no longer exists.")); \
84 1.1 christos return NULL; \
85 1.1 christos } \
86 1.1 christos } while (0)
87 1.1 christos
88 1.1 christos static void
89 1.10 christos python_on_normal_stop (struct bpstat *bs, int print_frame)
90 1.1 christos {
91 1.1 christos enum gdb_signal stop_signal;
92 1.1 christos
93 1.1 christos if (!gdb_python_initialized)
94 1.1 christos return;
95 1.1 christos
96 1.8 christos if (inferior_ptid == null_ptid)
97 1.8 christos return;
98 1.1 christos
99 1.10 christos stop_signal = inferior_thread ()->stop_signal ();
100 1.1 christos
101 1.10 christos gdbpy_enter enter_py;
102 1.1 christos
103 1.1 christos if (emit_stop_event (bs, stop_signal) < 0)
104 1.1 christos gdbpy_print_stack ();
105 1.1 christos }
106 1.1 christos
107 1.1 christos static void
108 1.1 christos python_on_resume (ptid_t ptid)
109 1.1 christos {
110 1.1 christos if (!gdb_python_initialized)
111 1.1 christos return;
112 1.1 christos
113 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ());
114 1.1 christos
115 1.1 christos if (emit_continue_event (ptid) < 0)
116 1.1 christos gdbpy_print_stack ();
117 1.1 christos }
118 1.1 christos
119 1.3 christos /* Callback, registered as an observer, that notifies Python listeners
120 1.3 christos when an inferior function call is about to be made. */
121 1.3 christos
122 1.3 christos static void
123 1.3 christos python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
124 1.3 christos {
125 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ());
126 1.3 christos
127 1.3 christos if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0)
128 1.3 christos gdbpy_print_stack ();
129 1.3 christos }
130 1.3 christos
131 1.3 christos /* Callback, registered as an observer, that notifies Python listeners
132 1.3 christos when an inferior function call has completed. */
133 1.3 christos
134 1.3 christos static void
135 1.3 christos python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
136 1.3 christos {
137 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ());
138 1.3 christos
139 1.3 christos if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0)
140 1.3 christos gdbpy_print_stack ();
141 1.3 christos }
142 1.3 christos
143 1.3 christos /* Callback, registered as an observer, that notifies Python listeners
144 1.3 christos when a part of memory has been modified by user action (eg via a
145 1.3 christos 'set' command). */
146 1.3 christos
147 1.3 christos static void
148 1.3 christos python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
149 1.3 christos {
150 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ());
151 1.3 christos
152 1.3 christos if (emit_memory_changed_event (addr, len) < 0)
153 1.3 christos gdbpy_print_stack ();
154 1.3 christos }
155 1.3 christos
156 1.3 christos /* Callback, registered as an observer, that notifies Python listeners
157 1.3 christos when a register has been modified by user action (eg via a 'set'
158 1.3 christos command). */
159 1.3 christos
160 1.3 christos static void
161 1.11 christos python_on_register_change (const frame_info_ptr &frame, int regnum)
162 1.3 christos {
163 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ());
164 1.3 christos
165 1.3 christos if (emit_register_changed_event (frame, regnum) < 0)
166 1.3 christos gdbpy_print_stack ();
167 1.3 christos }
168 1.3 christos
169 1.1 christos static void
170 1.1 christos python_inferior_exit (struct inferior *inf)
171 1.1 christos {
172 1.1 christos const LONGEST *exit_code = NULL;
173 1.1 christos
174 1.1 christos if (!gdb_python_initialized)
175 1.1 christos return;
176 1.1 christos
177 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ());
178 1.1 christos
179 1.1 christos if (inf->has_exit_code)
180 1.1 christos exit_code = &inf->exit_code;
181 1.1 christos
182 1.1 christos if (emit_exited_event (exit_code, inf) < 0)
183 1.1 christos gdbpy_print_stack ();
184 1.1 christos }
185 1.1 christos
186 1.1 christos /* Callback used to notify Python listeners about new objfiles loaded in the
187 1.3 christos inferior. OBJFILE may be NULL which means that the objfile list has been
188 1.3 christos cleared (emptied). */
189 1.1 christos
190 1.1 christos static void
191 1.1 christos python_new_objfile (struct objfile *objfile)
192 1.1 christos {
193 1.1 christos if (!gdb_python_initialized)
194 1.1 christos return;
195 1.1 christos
196 1.11 christos gdbpy_enter enter_py (objfile->arch ());
197 1.11 christos
198 1.11 christos if (emit_new_objfile_event (objfile) < 0)
199 1.11 christos gdbpy_print_stack ();
200 1.11 christos }
201 1.1 christos
202 1.11 christos static void
203 1.11 christos python_all_objfiles_removed (program_space *pspace)
204 1.11 christos {
205 1.11 christos if (!gdb_python_initialized)
206 1.11 christos return;
207 1.11 christos
208 1.11 christos gdbpy_enter enter_py (current_inferior ()->arch ());
209 1.11 christos
210 1.11 christos if (emit_clear_objfiles_event (pspace) < 0)
211 1.11 christos gdbpy_print_stack ();
212 1.1 christos }
213 1.1 christos
214 1.10 christos /* Emit a Python event when an objfile is about to be removed. */
215 1.10 christos
216 1.10 christos static void
217 1.10 christos python_free_objfile (struct objfile *objfile)
218 1.10 christos {
219 1.10 christos if (!gdb_python_initialized)
220 1.10 christos return;
221 1.10 christos
222 1.10 christos gdbpy_enter enter_py (objfile->arch ());
223 1.10 christos
224 1.10 christos if (emit_free_objfile_event (objfile) < 0)
225 1.10 christos gdbpy_print_stack ();
226 1.10 christos }
227 1.10 christos
228 1.1 christos /* Return a reference to the Python object of type Inferior
229 1.1 christos representing INFERIOR. If the object has already been created,
230 1.1 christos return it and increment the reference count, otherwise, create it.
231 1.1 christos Return NULL on failure. */
232 1.8 christos
233 1.8 christos gdbpy_ref<inferior_object>
234 1.1 christos inferior_to_inferior_object (struct inferior *inferior)
235 1.1 christos {
236 1.1 christos inferior_object *inf_obj;
237 1.1 christos
238 1.10 christos inf_obj = infpy_inf_data_key.get (inferior);
239 1.1 christos if (!inf_obj)
240 1.1 christos {
241 1.1 christos inf_obj = PyObject_New (inferior_object, &inferior_object_type);
242 1.1 christos if (!inf_obj)
243 1.8 christos return NULL;
244 1.1 christos
245 1.1 christos inf_obj->inferior = inferior;
246 1.10 christos inf_obj->threads = new thread_map_t ();
247 1.11 christos inf_obj->dict = PyDict_New ();
248 1.11 christos if (inf_obj->dict == nullptr)
249 1.11 christos return nullptr;
250 1.1 christos
251 1.7 christos /* PyObject_New initializes the new object with a refcount of 1. This
252 1.7 christos counts for the reference we are keeping in the inferior data. */
253 1.10 christos infpy_inf_data_key.set (inferior, inf_obj);
254 1.1 christos }
255 1.7 christos
256 1.7 christos /* We are returning a new reference. */
257 1.8 christos gdb_assert (inf_obj != nullptr);
258 1.8 christos return gdbpy_ref<inferior_object>::new_reference (inf_obj);
259 1.8 christos }
260 1.1 christos
261 1.8 christos /* Called when a new inferior is created. Notifies any Python event
262 1.8 christos listeners. */
263 1.8 christos static void
264 1.8 christos python_new_inferior (struct inferior *inf)
265 1.8 christos {
266 1.8 christos if (!gdb_python_initialized)
267 1.8 christos return;
268 1.1 christos
269 1.10 christos gdbpy_enter enter_py;
270 1.1 christos
271 1.8 christos if (evregpy_no_listeners_p (gdb_py_events.new_inferior))
272 1.8 christos return;
273 1.1 christos
274 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
275 1.8 christos if (inf_obj == NULL)
276 1.8 christos {
277 1.8 christos gdbpy_print_stack ();
278 1.8 christos return;
279 1.8 christos }
280 1.1 christos
281 1.8 christos gdbpy_ref<> event = create_event_object (&new_inferior_event_object_type);
282 1.8 christos if (event == NULL
283 1.8 christos || evpy_add_attribute (event.get (), "inferior",
284 1.8 christos (PyObject *) inf_obj.get ()) < 0
285 1.8 christos || evpy_emit_event (event.get (), gdb_py_events.new_inferior) < 0)
286 1.8 christos gdbpy_print_stack ();
287 1.1 christos }
288 1.1 christos
289 1.8 christos /* Called when an inferior is removed. Notifies any Python event
290 1.8 christos listeners. */
291 1.8 christos static void
292 1.8 christos python_inferior_deleted (struct inferior *inf)
293 1.1 christos {
294 1.8 christos if (!gdb_python_initialized)
295 1.8 christos return;
296 1.1 christos
297 1.10 christos gdbpy_enter enter_py;
298 1.8 christos
299 1.8 christos if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted))
300 1.8 christos return;
301 1.8 christos
302 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
303 1.8 christos if (inf_obj == NULL)
304 1.8 christos {
305 1.8 christos gdbpy_print_stack ();
306 1.8 christos return;
307 1.8 christos }
308 1.8 christos
309 1.8 christos gdbpy_ref<> event = create_event_object (&inferior_deleted_event_object_type);
310 1.8 christos if (event == NULL
311 1.8 christos || evpy_add_attribute (event.get (), "inferior",
312 1.8 christos (PyObject *) inf_obj.get ()) < 0
313 1.8 christos || evpy_emit_event (event.get (), gdb_py_events.inferior_deleted) < 0)
314 1.8 christos gdbpy_print_stack ();
315 1.8 christos }
316 1.1 christos
317 1.8 christos gdbpy_ref<>
318 1.8 christos thread_to_thread_object (thread_info *thr)
319 1.8 christos {
320 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (thr->inf);
321 1.7 christos if (inf_obj == NULL)
322 1.1 christos return NULL;
323 1.1 christos
324 1.10 christos auto thread_it = inf_obj->threads->find (thr);
325 1.10 christos if (thread_it != inf_obj->threads->end ())
326 1.10 christos return gdbpy_ref<>::new_reference
327 1.10 christos ((PyObject *) (thread_it->second.get ()));
328 1.1 christos
329 1.8 christos PyErr_SetString (PyExc_SystemError,
330 1.8 christos _("could not find gdb thread object"));
331 1.1 christos return NULL;
332 1.1 christos }
333 1.1 christos
334 1.1 christos static void
335 1.1 christos add_thread_object (struct thread_info *tp)
336 1.1 christos {
337 1.1 christos inferior_object *inf_obj;
338 1.1 christos
339 1.1 christos if (!gdb_python_initialized)
340 1.1 christos return;
341 1.1 christos
342 1.10 christos gdbpy_enter enter_py;
343 1.1 christos
344 1.9 christos gdbpy_ref<thread_object> thread_obj = create_thread_object (tp);
345 1.9 christos if (thread_obj == NULL)
346 1.1 christos {
347 1.1 christos gdbpy_print_stack ();
348 1.1 christos return;
349 1.1 christos }
350 1.1 christos
351 1.1 christos inf_obj = (inferior_object *) thread_obj->inf_obj;
352 1.1 christos
353 1.10 christos auto ins_result = inf_obj->threads->emplace
354 1.10 christos (thread_map_t::value_type (tp, std::move (thread_obj)));
355 1.1 christos
356 1.10 christos if (!ins_result.second)
357 1.10 christos return;
358 1.8 christos
359 1.8 christos if (evregpy_no_listeners_p (gdb_py_events.new_thread))
360 1.8 christos return;
361 1.8 christos
362 1.10 christos gdbpy_ref<> event = create_thread_event_object
363 1.10 christos (&new_thread_event_object_type,
364 1.10 christos (PyObject *) ins_result.first->second.get ());
365 1.10 christos
366 1.8 christos if (event == NULL
367 1.8 christos || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0)
368 1.8 christos gdbpy_print_stack ();
369 1.1 christos }
370 1.1 christos
371 1.1 christos static void
372 1.11 christos delete_thread_object (thread_info *tp,
373 1.11 christos std::optional<ULONGEST> /* exit_code */,
374 1.11 christos bool /* silent */)
375 1.1 christos {
376 1.1 christos if (!gdb_python_initialized)
377 1.1 christos return;
378 1.1 christos
379 1.10 christos gdbpy_enter enter_py;
380 1.1 christos
381 1.8 christos gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf);
382 1.7 christos if (inf_obj == NULL)
383 1.7 christos return;
384 1.1 christos
385 1.11 christos if (emit_thread_exit_event (tp) < 0)
386 1.11 christos gdbpy_print_stack ();
387 1.11 christos
388 1.10 christos auto it = inf_obj->threads->find (tp);
389 1.10 christos if (it != inf_obj->threads->end ())
390 1.10 christos {
391 1.10 christos /* Some python code can still hold a reference to the thread_object
392 1.10 christos instance. Make sure to remove the link to the associated
393 1.10 christos thread_info object as it will be freed soon. This makes the python
394 1.10 christos object invalid (i.e. gdb.InfThread.is_valid returns False). */
395 1.10 christos it->second->thread = nullptr;
396 1.10 christos inf_obj->threads->erase (it);
397 1.10 christos }
398 1.1 christos }
399 1.1 christos
400 1.1 christos static PyObject *
401 1.1 christos infpy_threads (PyObject *self, PyObject *args)
402 1.1 christos {
403 1.10 christos int i = 0;
404 1.1 christos inferior_object *inf_obj = (inferior_object *) self;
405 1.1 christos PyObject *tuple;
406 1.1 christos
407 1.1 christos INFPY_REQUIRE_VALID (inf_obj);
408 1.1 christos
409 1.9 christos try
410 1.5 christos {
411 1.5 christos update_thread_list ();
412 1.5 christos }
413 1.9 christos catch (const gdb_exception &except)
414 1.5 christos {
415 1.5 christos GDB_PY_HANDLE_EXCEPTION (except);
416 1.5 christos }
417 1.1 christos
418 1.10 christos tuple = PyTuple_New (inf_obj->threads->size ());
419 1.1 christos if (!tuple)
420 1.1 christos return NULL;
421 1.1 christos
422 1.10 christos for (const thread_map_t::value_type &entry : *inf_obj->threads)
423 1.1 christos {
424 1.10 christos PyObject *thr = (PyObject *) entry.second.get ();
425 1.9 christos Py_INCREF (thr);
426 1.9 christos PyTuple_SET_ITEM (tuple, i, thr);
427 1.10 christos i = i + 1;
428 1.1 christos }
429 1.1 christos
430 1.1 christos return tuple;
431 1.1 christos }
432 1.1 christos
433 1.1 christos static PyObject *
434 1.1 christos infpy_get_num (PyObject *self, void *closure)
435 1.1 christos {
436 1.1 christos inferior_object *inf = (inferior_object *) self;
437 1.1 christos
438 1.1 christos INFPY_REQUIRE_VALID (inf);
439 1.1 christos
440 1.10 christos return gdb_py_object_from_longest (inf->inferior->num).release ();
441 1.10 christos }
442 1.10 christos
443 1.10 christos /* Return the gdb.TargetConnection object for this inferior, or None if a
444 1.10 christos connection does not exist. */
445 1.10 christos
446 1.10 christos static PyObject *
447 1.10 christos infpy_get_connection (PyObject *self, void *closure)
448 1.10 christos {
449 1.10 christos inferior_object *inf = (inferior_object *) self;
450 1.10 christos
451 1.10 christos INFPY_REQUIRE_VALID (inf);
452 1.10 christos
453 1.10 christos process_stratum_target *target = inf->inferior->process_target ();
454 1.10 christos return target_to_connection_object (target).release ();
455 1.10 christos }
456 1.10 christos
457 1.10 christos /* Return the connection number of the given inferior, or None if a
458 1.10 christos connection does not exist. */
459 1.10 christos
460 1.10 christos static PyObject *
461 1.10 christos infpy_get_connection_num (PyObject *self, void *closure)
462 1.10 christos {
463 1.10 christos inferior_object *inf = (inferior_object *) self;
464 1.10 christos
465 1.10 christos INFPY_REQUIRE_VALID (inf);
466 1.10 christos
467 1.10 christos process_stratum_target *target = inf->inferior->process_target ();
468 1.10 christos if (target == nullptr)
469 1.10 christos Py_RETURN_NONE;
470 1.10 christos
471 1.10 christos return gdb_py_object_from_longest (target->connection_number).release ();
472 1.1 christos }
473 1.1 christos
474 1.1 christos static PyObject *
475 1.1 christos infpy_get_pid (PyObject *self, void *closure)
476 1.1 christos {
477 1.1 christos inferior_object *inf = (inferior_object *) self;
478 1.1 christos
479 1.1 christos INFPY_REQUIRE_VALID (inf);
480 1.1 christos
481 1.10 christos return gdb_py_object_from_longest (inf->inferior->pid).release ();
482 1.1 christos }
483 1.1 christos
484 1.1 christos static PyObject *
485 1.1 christos infpy_get_was_attached (PyObject *self, void *closure)
486 1.1 christos {
487 1.1 christos inferior_object *inf = (inferior_object *) self;
488 1.1 christos
489 1.1 christos INFPY_REQUIRE_VALID (inf);
490 1.1 christos if (inf->inferior->attach_flag)
491 1.1 christos Py_RETURN_TRUE;
492 1.1 christos Py_RETURN_FALSE;
493 1.1 christos }
494 1.1 christos
495 1.8 christos /* Getter of gdb.Inferior.progspace. */
496 1.8 christos
497 1.8 christos static PyObject *
498 1.8 christos infpy_get_progspace (PyObject *self, void *closure)
499 1.8 christos {
500 1.8 christos inferior_object *inf = (inferior_object *) self;
501 1.8 christos
502 1.8 christos INFPY_REQUIRE_VALID (inf);
503 1.8 christos
504 1.8 christos program_space *pspace = inf->inferior->pspace;
505 1.8 christos gdb_assert (pspace != nullptr);
506 1.8 christos
507 1.8 christos return pspace_to_pspace_object (pspace).release ();
508 1.8 christos }
509 1.8 christos
510 1.1 christos /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...).
511 1.1 christos Returns a tuple of all inferiors. */
512 1.1 christos PyObject *
513 1.1 christos gdbpy_inferiors (PyObject *unused, PyObject *unused2)
514 1.1 christos {
515 1.7 christos gdbpy_ref<> list (PyList_New (0));
516 1.7 christos if (list == NULL)
517 1.7 christos return NULL;
518 1.1 christos
519 1.9 christos for (inferior *inf : all_inferiors ())
520 1.9 christos {
521 1.9 christos gdbpy_ref<inferior_object> inferior = inferior_to_inferior_object (inf);
522 1.9 christos
523 1.9 christos if (inferior == NULL)
524 1.9 christos continue;
525 1.9 christos
526 1.9 christos if (PyList_Append (list.get (), (PyObject *) inferior.get ()) != 0)
527 1.9 christos return NULL;
528 1.9 christos }
529 1.1 christos
530 1.7 christos return PyList_AsTuple (list.get ());
531 1.1 christos }
532 1.1 christos
533 1.1 christos /* Membuf and memory manipulation. */
534 1.1 christos
535 1.1 christos /* Implementation of Inferior.read_memory (address, length).
536 1.1 christos Returns a Python buffer object with LENGTH bytes of the inferior's
537 1.1 christos memory at ADDRESS. Both arguments are integers. Returns NULL on error,
538 1.1 christos with a python exception set. */
539 1.1 christos static PyObject *
540 1.1 christos infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
541 1.1 christos {
542 1.11 christos inferior_object *inf = (inferior_object *) self;
543 1.1 christos CORE_ADDR addr, length;
544 1.8 christos gdb::unique_xmalloc_ptr<gdb_byte> buffer;
545 1.10 christos PyObject *addr_obj, *length_obj;
546 1.7 christos static const char *keywords[] = { "address", "length", NULL };
547 1.1 christos
548 1.11 christos INFPY_REQUIRE_VALID (inf);
549 1.11 christos
550 1.7 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
551 1.7 christos &addr_obj, &length_obj))
552 1.1 christos return NULL;
553 1.1 christos
554 1.1 christos if (get_addr_from_python (addr_obj, &addr) < 0
555 1.1 christos || get_addr_from_python (length_obj, &length) < 0)
556 1.1 christos return NULL;
557 1.1 christos
558 1.11 christos if (length == 0)
559 1.11 christos {
560 1.11 christos PyErr_SetString (PyExc_ValueError,
561 1.11 christos _("Argument 'count' should be greater than zero"));
562 1.11 christos return NULL;
563 1.11 christos }
564 1.11 christos
565 1.11 christos void *p = malloc (length);
566 1.11 christos if (p == nullptr)
567 1.11 christos return PyErr_NoMemory ();
568 1.11 christos buffer.reset ((gdb_byte *) p);
569 1.11 christos
570 1.9 christos try
571 1.1 christos {
572 1.11 christos /* Use this scoped-restore because we want to be able to read
573 1.11 christos memory from an unwinder. */
574 1.11 christos scoped_restore_current_inferior_for_memory restore_inferior
575 1.11 christos (inf->inferior);
576 1.1 christos
577 1.8 christos read_memory (addr, buffer.get (), length);
578 1.1 christos }
579 1.9 christos catch (const gdb_exception &except)
580 1.1 christos {
581 1.1 christos GDB_PY_HANDLE_EXCEPTION (except);
582 1.1 christos }
583 1.1 christos
584 1.1 christos
585 1.10 christos return gdbpy_buffer_to_membuf (std::move (buffer), addr, length);
586 1.1 christos }
587 1.1 christos
588 1.1 christos /* Implementation of Inferior.write_memory (address, buffer [, length]).
589 1.1 christos Writes the contents of BUFFER (a Python object supporting the read
590 1.1 christos buffer protocol) at ADDRESS in the inferior's memory. Write LENGTH
591 1.1 christos bytes from BUFFER, or its entire contents if the argument is not
592 1.1 christos provided. The function returns nothing. Returns NULL on error, with
593 1.1 christos a python exception set. */
594 1.1 christos static PyObject *
595 1.1 christos infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
596 1.1 christos {
597 1.11 christos inferior_object *inf = (inferior_object *) self;
598 1.1 christos Py_ssize_t buf_len;
599 1.6 christos const gdb_byte *buffer;
600 1.1 christos CORE_ADDR addr, length;
601 1.1 christos PyObject *addr_obj, *length_obj = NULL;
602 1.7 christos static const char *keywords[] = { "address", "buffer", "length", NULL };
603 1.1 christos Py_buffer pybuf;
604 1.1 christos
605 1.11 christos INFPY_REQUIRE_VALID (inf);
606 1.11 christos
607 1.7 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
608 1.7 christos &addr_obj, &pybuf, &length_obj))
609 1.1 christos return NULL;
610 1.1 christos
611 1.9 christos Py_buffer_up buffer_up (&pybuf);
612 1.6 christos buffer = (const gdb_byte *) pybuf.buf;
613 1.1 christos buf_len = pybuf.len;
614 1.1 christos
615 1.1 christos if (get_addr_from_python (addr_obj, &addr) < 0)
616 1.9 christos return nullptr;
617 1.1 christos
618 1.1 christos if (!length_obj)
619 1.1 christos length = buf_len;
620 1.1 christos else if (get_addr_from_python (length_obj, &length) < 0)
621 1.9 christos return nullptr;
622 1.1 christos
623 1.9 christos try
624 1.1 christos {
625 1.11 christos /* It's probably not too important to avoid invalidating the
626 1.11 christos frame cache when writing memory, but this scoped-restore is
627 1.11 christos still used here, just to keep the code similar to other code
628 1.11 christos in this file. */
629 1.11 christos scoped_restore_current_inferior_for_memory restore_inferior
630 1.11 christos (inf->inferior);
631 1.11 christos
632 1.6 christos write_memory_with_notification (addr, buffer, length);
633 1.1 christos }
634 1.9 christos catch (gdb_exception &ex)
635 1.5 christos {
636 1.11 christos GDB_PY_HANDLE_EXCEPTION (ex);
637 1.5 christos }
638 1.5 christos
639 1.1 christos Py_RETURN_NONE;
640 1.1 christos }
641 1.1 christos
642 1.1 christos /* Implementation of
643 1.11 christos Inferior.search_memory (address, length, pattern). ADDRESS is the
644 1.1 christos address to start the search. LENGTH specifies the scope of the
645 1.1 christos search from ADDRESS. PATTERN is the pattern to search for (and
646 1.1 christos must be a Python object supporting the buffer protocol).
647 1.1 christos Returns a Python Long object holding the address where the pattern
648 1.1 christos was located, or if the pattern was not found, returns None. Returns NULL
649 1.1 christos on error, with a python exception set. */
650 1.1 christos static PyObject *
651 1.1 christos infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
652 1.1 christos {
653 1.11 christos inferior_object *inf = (inferior_object *) self;
654 1.1 christos CORE_ADDR start_addr, length;
655 1.7 christos static const char *keywords[] = { "address", "length", "pattern", NULL };
656 1.1 christos PyObject *start_addr_obj, *length_obj;
657 1.1 christos Py_ssize_t pattern_size;
658 1.6 christos const gdb_byte *buffer;
659 1.1 christos CORE_ADDR found_addr;
660 1.1 christos int found = 0;
661 1.1 christos Py_buffer pybuf;
662 1.1 christos
663 1.11 christos INFPY_REQUIRE_VALID (inf);
664 1.11 christos
665 1.7 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
666 1.7 christos &start_addr_obj, &length_obj,
667 1.7 christos &pybuf))
668 1.1 christos return NULL;
669 1.1 christos
670 1.9 christos Py_buffer_up buffer_up (&pybuf);
671 1.6 christos buffer = (const gdb_byte *) pybuf.buf;
672 1.1 christos pattern_size = pybuf.len;
673 1.1 christos
674 1.1 christos if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
675 1.9 christos return nullptr;
676 1.1 christos
677 1.1 christos if (get_addr_from_python (length_obj, &length) < 0)
678 1.9 christos return nullptr;
679 1.1 christos
680 1.1 christos if (!length)
681 1.1 christos {
682 1.1 christos PyErr_SetString (PyExc_ValueError,
683 1.1 christos _("Search range is empty."));
684 1.9 christos return nullptr;
685 1.1 christos }
686 1.1 christos /* Watch for overflows. */
687 1.1 christos else if (length > CORE_ADDR_MAX
688 1.1 christos || (start_addr + length - 1) < start_addr)
689 1.1 christos {
690 1.1 christos PyErr_SetString (PyExc_ValueError,
691 1.1 christos _("The search range is too large."));
692 1.9 christos return nullptr;
693 1.1 christos }
694 1.1 christos
695 1.9 christos try
696 1.1 christos {
697 1.11 christos /* It's probably not too important to avoid invalidating the
698 1.11 christos frame cache when searching memory, but this scoped-restore is
699 1.11 christos still used here, just to keep the code similar to other code
700 1.11 christos in this file. */
701 1.11 christos scoped_restore_current_inferior_for_memory restore_inferior
702 1.11 christos (inf->inferior);
703 1.11 christos
704 1.1 christos found = target_search_memory (start_addr, length,
705 1.1 christos buffer, pattern_size,
706 1.1 christos &found_addr);
707 1.1 christos }
708 1.9 christos catch (gdb_exception &ex)
709 1.5 christos {
710 1.11 christos GDB_PY_HANDLE_EXCEPTION (ex);
711 1.5 christos }
712 1.5 christos
713 1.1 christos if (found)
714 1.9 christos return gdb_py_object_from_ulongest (found_addr).release ();
715 1.1 christos else
716 1.1 christos Py_RETURN_NONE;
717 1.1 christos }
718 1.1 christos
719 1.1 christos /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
720 1.1 christos Returns True if this inferior object still exists in GDB. */
721 1.1 christos
722 1.1 christos static PyObject *
723 1.1 christos infpy_is_valid (PyObject *self, PyObject *args)
724 1.1 christos {
725 1.1 christos inferior_object *inf = (inferior_object *) self;
726 1.1 christos
727 1.1 christos if (! inf->inferior)
728 1.1 christos Py_RETURN_FALSE;
729 1.1 christos
730 1.1 christos Py_RETURN_TRUE;
731 1.1 christos }
732 1.1 christos
733 1.9 christos /* Implementation of gdb.Inferior.thread_from_handle (self, handle)
734 1.10 christos -> gdb.InferiorThread. */
735 1.8 christos
736 1.8 christos static PyObject *
737 1.8 christos infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw)
738 1.8 christos {
739 1.8 christos PyObject *handle_obj;
740 1.8 christos inferior_object *inf_obj = (inferior_object *) self;
741 1.9 christos static const char *keywords[] = { "handle", NULL };
742 1.8 christos
743 1.8 christos INFPY_REQUIRE_VALID (inf_obj);
744 1.8 christos
745 1.8 christos if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj))
746 1.8 christos return NULL;
747 1.8 christos
748 1.9 christos const gdb_byte *bytes;
749 1.9 christos size_t bytes_len;
750 1.9 christos Py_buffer_up buffer_up;
751 1.9 christos Py_buffer py_buf;
752 1.9 christos
753 1.9 christos if (PyObject_CheckBuffer (handle_obj)
754 1.9 christos && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0)
755 1.9 christos {
756 1.9 christos buffer_up.reset (&py_buf);
757 1.9 christos bytes = (const gdb_byte *) py_buf.buf;
758 1.9 christos bytes_len = py_buf.len;
759 1.9 christos }
760 1.9 christos else if (gdbpy_is_value_object (handle_obj))
761 1.9 christos {
762 1.9 christos struct value *val = value_object_to_value (handle_obj);
763 1.11 christos bytes = val->contents_all ().data ();
764 1.11 christos bytes_len = val->type ()->length ();
765 1.9 christos }
766 1.9 christos else
767 1.8 christos {
768 1.8 christos PyErr_SetString (PyExc_TypeError,
769 1.9 christos _("Argument 'handle' must be a thread handle object."));
770 1.8 christos
771 1.8 christos return NULL;
772 1.8 christos }
773 1.8 christos
774 1.9 christos try
775 1.8 christos {
776 1.8 christos struct thread_info *thread_info;
777 1.8 christos
778 1.9 christos thread_info = find_thread_by_handle
779 1.10 christos (gdb::array_view<const gdb_byte> (bytes, bytes_len),
780 1.9 christos inf_obj->inferior);
781 1.8 christos if (thread_info != NULL)
782 1.8 christos return thread_to_thread_object (thread_info).release ();
783 1.8 christos }
784 1.9 christos catch (const gdb_exception &except)
785 1.8 christos {
786 1.8 christos GDB_PY_HANDLE_EXCEPTION (except);
787 1.8 christos }
788 1.8 christos
789 1.8 christos Py_RETURN_NONE;
790 1.8 christos }
791 1.8 christos
792 1.8 christos /* Implementation of gdb.Inferior.architecture. */
793 1.8 christos
794 1.8 christos static PyObject *
795 1.8 christos infpy_architecture (PyObject *self, PyObject *args)
796 1.8 christos {
797 1.8 christos inferior_object *inf = (inferior_object *) self;
798 1.8 christos
799 1.8 christos INFPY_REQUIRE_VALID (inf);
800 1.8 christos
801 1.11 christos return gdbarch_to_arch_object (inf->inferior->arch ());
802 1.8 christos }
803 1.8 christos
804 1.8 christos /* Implement repr() for gdb.Inferior. */
805 1.8 christos
806 1.8 christos static PyObject *
807 1.8 christos infpy_repr (PyObject *obj)
808 1.8 christos {
809 1.8 christos inferior_object *self = (inferior_object *) obj;
810 1.8 christos inferior *inf = self->inferior;
811 1.8 christos
812 1.8 christos if (inf == nullptr)
813 1.11 christos return gdb_py_invalid_object_repr (obj);
814 1.8 christos
815 1.10 christos return PyUnicode_FromFormat ("<gdb.Inferior num=%d, pid=%d>",
816 1.10 christos inf->num, inf->pid);
817 1.8 christos }
818 1.8 christos
819 1.11 christos /* Implement clear_env. */
820 1.11 christos
821 1.11 christos static PyObject *
822 1.11 christos infpy_clear_env (PyObject *obj)
823 1.11 christos {
824 1.11 christos inferior_object *self = (inferior_object *) obj;
825 1.11 christos
826 1.11 christos INFPY_REQUIRE_VALID (self);
827 1.11 christos
828 1.11 christos self->inferior->environment.clear ();
829 1.11 christos Py_RETURN_NONE;
830 1.11 christos }
831 1.11 christos
832 1.11 christos /* Implement set_env. */
833 1.11 christos
834 1.11 christos static PyObject *
835 1.11 christos infpy_set_env (PyObject *obj, PyObject *args, PyObject *kw)
836 1.11 christos {
837 1.11 christos inferior_object *self = (inferior_object *) obj;
838 1.11 christos INFPY_REQUIRE_VALID (self);
839 1.11 christos
840 1.11 christos const char *name, *val;
841 1.11 christos static const char *keywords[] = { "name", "value", nullptr };
842 1.11 christos
843 1.11 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "ss", keywords,
844 1.11 christos &name, &val))
845 1.11 christos return nullptr;
846 1.11 christos
847 1.11 christos self->inferior->environment.set (name, val);
848 1.11 christos Py_RETURN_NONE;
849 1.11 christos }
850 1.11 christos
851 1.11 christos /* Implement unset_env. */
852 1.11 christos
853 1.11 christos static PyObject *
854 1.11 christos infpy_unset_env (PyObject *obj, PyObject *args, PyObject *kw)
855 1.11 christos {
856 1.11 christos inferior_object *self = (inferior_object *) obj;
857 1.11 christos INFPY_REQUIRE_VALID (self);
858 1.11 christos
859 1.11 christos const char *name;
860 1.11 christos static const char *keywords[] = { "name", nullptr };
861 1.11 christos if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s", keywords, &name))
862 1.11 christos return nullptr;
863 1.11 christos
864 1.11 christos self->inferior->environment.unset (name);
865 1.11 christos Py_RETURN_NONE;
866 1.11 christos }
867 1.11 christos
868 1.11 christos /* Getter for "arguments". */
869 1.11 christos
870 1.11 christos static PyObject *
871 1.11 christos infpy_get_args (PyObject *self, void *closure)
872 1.11 christos {
873 1.11 christos inferior_object *inf = (inferior_object *) self;
874 1.11 christos
875 1.11 christos INFPY_REQUIRE_VALID (inf);
876 1.11 christos
877 1.11 christos const std::string &args = inf->inferior->args ();
878 1.11 christos if (args.empty ())
879 1.11 christos Py_RETURN_NONE;
880 1.11 christos
881 1.11 christos return host_string_to_python_string (args.c_str ()).release ();
882 1.11 christos }
883 1.11 christos
884 1.11 christos /* Setter for "arguments". */
885 1.11 christos
886 1.11 christos static int
887 1.11 christos infpy_set_args (PyObject *self, PyObject *value, void *closure)
888 1.11 christos {
889 1.11 christos inferior_object *inf = (inferior_object *) self;
890 1.11 christos
891 1.11 christos if (!inf->inferior)
892 1.11 christos {
893 1.11 christos PyErr_SetString (PyExc_RuntimeError, _("Inferior no longer exists."));
894 1.11 christos return -1;
895 1.11 christos }
896 1.11 christos
897 1.11 christos if (value == nullptr)
898 1.11 christos {
899 1.11 christos PyErr_SetString (PyExc_TypeError,
900 1.11 christos _("Cannot delete 'arguments' attribute."));
901 1.11 christos return -1;
902 1.11 christos }
903 1.11 christos
904 1.11 christos if (gdbpy_is_string (value))
905 1.11 christos {
906 1.11 christos gdb::unique_xmalloc_ptr<char> str = python_string_to_host_string (value);
907 1.11 christos if (str == nullptr)
908 1.11 christos return -1;
909 1.11 christos inf->inferior->set_args (std::string (str.get ()));
910 1.11 christos }
911 1.11 christos else if (PySequence_Check (value))
912 1.11 christos {
913 1.11 christos std::vector<gdb::unique_xmalloc_ptr<char>> args;
914 1.11 christos Py_ssize_t len = PySequence_Size (value);
915 1.11 christos if (len == -1)
916 1.11 christos return -1;
917 1.11 christos for (Py_ssize_t i = 0; i < len; ++i)
918 1.11 christos {
919 1.11 christos gdbpy_ref<> item (PySequence_ITEM (value, i));
920 1.11 christos if (item == nullptr)
921 1.11 christos return -1;
922 1.11 christos gdb::unique_xmalloc_ptr<char> str
923 1.11 christos = python_string_to_host_string (item.get ());
924 1.11 christos if (str == nullptr)
925 1.11 christos return -1;
926 1.11 christos args.push_back (std::move (str));
927 1.11 christos }
928 1.11 christos std::vector<char *> argvec;
929 1.11 christos for (const auto &arg : args)
930 1.11 christos argvec.push_back (arg.get ());
931 1.11 christos gdb::array_view<char * const> view (argvec.data (), argvec.size ());
932 1.11 christos inf->inferior->set_args (view);
933 1.11 christos }
934 1.11 christos else
935 1.11 christos {
936 1.11 christos PyErr_SetString (PyExc_TypeError,
937 1.11 christos _("string or sequence required for 'arguments'"));
938 1.11 christos return -1;
939 1.11 christos }
940 1.11 christos return 0;
941 1.11 christos }
942 1.11 christos
943 1.11 christos /* Getter for "main_name". */
944 1.11 christos
945 1.11 christos static PyObject *
946 1.11 christos infpy_get_main_name (PyObject *self, void *closure)
947 1.11 christos {
948 1.11 christos inferior_object *inf = (inferior_object *) self;
949 1.11 christos
950 1.11 christos INFPY_REQUIRE_VALID (inf);
951 1.11 christos
952 1.11 christos const char *name = nullptr;
953 1.11 christos try
954 1.11 christos {
955 1.11 christos /* This is unfortunate but the implementation of main_name can
956 1.11 christos reach into memory. It's probably not too important to avoid
957 1.11 christos invalidating the frame cache here, but this scoped-restore is
958 1.11 christos still used, just to keep the code similar to other code in
959 1.11 christos this file. */
960 1.11 christos scoped_restore_current_inferior_for_memory restore_inferior
961 1.11 christos (inf->inferior);
962 1.11 christos
963 1.11 christos name = main_name ();
964 1.11 christos }
965 1.11 christos catch (const gdb_exception &except)
966 1.11 christos {
967 1.11 christos /* We can just ignore this. */
968 1.11 christos }
969 1.11 christos
970 1.11 christos if (name == nullptr)
971 1.11 christos Py_RETURN_NONE;
972 1.11 christos
973 1.11 christos return host_string_to_python_string (name).release ();
974 1.11 christos }
975 1.8 christos
976 1.1 christos static void
977 1.1 christos infpy_dealloc (PyObject *obj)
978 1.1 christos {
979 1.1 christos inferior_object *inf_obj = (inferior_object *) obj;
980 1.1 christos
981 1.10 christos /* The inferior itself holds a reference to this Python object, which
982 1.10 christos will keep the reference count of this object above zero until GDB
983 1.10 christos deletes the inferior and py_free_inferior is called.
984 1.10 christos
985 1.10 christos Once py_free_inferior has been called then the link between this
986 1.10 christos Python object and the inferior is set to nullptr, and then the
987 1.10 christos reference count on this Python object is decremented.
988 1.10 christos
989 1.10 christos The result of all this is that the link between this Python object and
990 1.10 christos the inferior should always have been set to nullptr before this
991 1.10 christos function is called. */
992 1.10 christos gdb_assert (inf_obj->inferior == nullptr);
993 1.1 christos
994 1.11 christos Py_XDECREF (inf_obj->dict);
995 1.11 christos
996 1.9 christos Py_TYPE (obj)->tp_free (obj);
997 1.1 christos }
998 1.1 christos
999 1.1 christos /* Implementation of gdb.selected_inferior() -> gdb.Inferior.
1000 1.1 christos Returns the current inferior object. */
1001 1.1 christos
1002 1.1 christos PyObject *
1003 1.1 christos gdbpy_selected_inferior (PyObject *self, PyObject *args)
1004 1.1 christos {
1005 1.8 christos return ((PyObject *)
1006 1.8 christos inferior_to_inferior_object (current_inferior ()).release ());
1007 1.1 christos }
1008 1.1 christos
1009 1.11 christos static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
1010 1.1 christos gdbpy_initialize_inferior (void)
1011 1.1 christos {
1012 1.1 christos if (PyType_Ready (&inferior_object_type) < 0)
1013 1.1 christos return -1;
1014 1.1 christos
1015 1.1 christos if (gdb_pymodule_addobject (gdb_module, "Inferior",
1016 1.1 christos (PyObject *) &inferior_object_type) < 0)
1017 1.1 christos return -1;
1018 1.1 christos
1019 1.10 christos gdb::observers::new_thread.attach (add_thread_object, "py-inferior");
1020 1.10 christos gdb::observers::thread_exit.attach (delete_thread_object, "py-inferior");
1021 1.10 christos gdb::observers::normal_stop.attach (python_on_normal_stop, "py-inferior");
1022 1.10 christos gdb::observers::target_resumed.attach (python_on_resume, "py-inferior");
1023 1.10 christos gdb::observers::inferior_call_pre.attach (python_on_inferior_call_pre,
1024 1.10 christos "py-inferior");
1025 1.10 christos gdb::observers::inferior_call_post.attach (python_on_inferior_call_post,
1026 1.10 christos "py-inferior");
1027 1.10 christos gdb::observers::memory_changed.attach (python_on_memory_change,
1028 1.10 christos "py-inferior");
1029 1.10 christos gdb::observers::register_changed.attach (python_on_register_change,
1030 1.10 christos "py-inferior");
1031 1.10 christos gdb::observers::inferior_exit.attach (python_inferior_exit, "py-inferior");
1032 1.10 christos /* Need to run after auto-load's new_objfile observer, so that
1033 1.10 christos auto-loaded pretty-printers are available. */
1034 1.10 christos gdb::observers::new_objfile.attach
1035 1.10 christos (python_new_objfile, "py-inferior",
1036 1.10 christos { &auto_load_new_objfile_observer_token });
1037 1.11 christos gdb::observers::all_objfiles_removed.attach (python_all_objfiles_removed,
1038 1.11 christos "py-inferior");
1039 1.10 christos gdb::observers::free_objfile.attach (python_free_objfile, "py-inferior");
1040 1.10 christos gdb::observers::inferior_added.attach (python_new_inferior, "py-inferior");
1041 1.10 christos gdb::observers::inferior_removed.attach (python_inferior_deleted,
1042 1.10 christos "py-inferior");
1043 1.1 christos
1044 1.10 christos return 0;
1045 1.1 christos }
1046 1.1 christos
1047 1.11 christos GDBPY_INITIALIZE_FILE (gdbpy_initialize_inferior);
1048 1.11 christos
1049 1.11 christos
1050 1.11 christos
1052 1.1 christos static gdb_PyGetSetDef inferior_object_getset[] =
1053 1.11 christos {
1054 1.11 christos { "__dict__", gdb_py_generic_dict, nullptr,
1055 1.11 christos "The __dict__ for this inferior.", &inferior_object_type },
1056 1.11 christos { "arguments", infpy_get_args, infpy_set_args,
1057 1.1 christos "Arguments to this program.", nullptr },
1058 1.10 christos { "num", infpy_get_num, NULL, "ID of inferior, as assigned by GDB.", NULL },
1059 1.10 christos { "connection", infpy_get_connection, NULL,
1060 1.10 christos "The gdb.TargetConnection for this inferior.", NULL },
1061 1.10 christos { "connection_num", infpy_get_connection_num, NULL,
1062 1.1 christos "ID of inferior's connection, as assigned by GDB.", NULL },
1063 1.1 christos { "pid", infpy_get_pid, NULL, "PID of inferior, as assigned by the OS.",
1064 1.1 christos NULL },
1065 1.1 christos { "was_attached", infpy_get_was_attached, NULL,
1066 1.8 christos "True if the inferior was created using 'attach'.", NULL },
1067 1.11 christos { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" },
1068 1.11 christos { "main_name", infpy_get_main_name, nullptr,
1069 1.1 christos "Name of 'main' function, if known.", nullptr },
1070 1.1 christos { NULL }
1071 1.1 christos };
1072 1.1 christos
1073 1.1 christos static PyMethodDef inferior_object_methods[] =
1074 1.1 christos {
1075 1.1 christos { "is_valid", infpy_is_valid, METH_NOARGS,
1076 1.1 christos "is_valid () -> Boolean.\n\
1077 1.1 christos Return true if this inferior is valid, false if not." },
1078 1.1 christos { "threads", infpy_threads, METH_NOARGS,
1079 1.1 christos "Return all the threads of this inferior." },
1080 1.1 christos { "read_memory", (PyCFunction) infpy_read_memory,
1081 1.1 christos METH_VARARGS | METH_KEYWORDS,
1082 1.1 christos "read_memory (address, length) -> buffer\n\
1083 1.1 christos Return a buffer object for reading from the inferior's memory." },
1084 1.1 christos { "write_memory", (PyCFunction) infpy_write_memory,
1085 1.1 christos METH_VARARGS | METH_KEYWORDS,
1086 1.1 christos "write_memory (address, buffer [, length])\n\
1087 1.1 christos Write the given buffer object to the inferior's memory." },
1088 1.1 christos { "search_memory", (PyCFunction) infpy_search_memory,
1089 1.1 christos METH_VARARGS | METH_KEYWORDS,
1090 1.1 christos "search_memory (address, length, pattern) -> long\n\
1091 1.9 christos Return a long with the address of a match, or None." },
1092 1.8 christos /* thread_from_thread_handle is deprecated. */
1093 1.8 christos { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle,
1094 1.8 christos METH_VARARGS | METH_KEYWORDS,
1095 1.9 christos "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\
1096 1.9 christos Return thread object corresponding to thread handle.\n\
1097 1.9 christos This method is deprecated - use thread_from_handle instead." },
1098 1.9 christos { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle,
1099 1.9 christos METH_VARARGS | METH_KEYWORDS,
1100 1.8 christos "thread_from_handle (handle) -> gdb.InferiorThread.\n\
1101 1.8 christos Return thread object corresponding to thread handle." },
1102 1.8 christos { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS,
1103 1.8 christos "architecture () -> gdb.Architecture\n\
1104 1.11 christos Return architecture of this inferior." },
1105 1.11 christos { "clear_env", (PyCFunction) infpy_clear_env, METH_NOARGS,
1106 1.11 christos "clear_env () -> None\n\
1107 1.11 christos Clear environment of this inferior." },
1108 1.11 christos { "set_env", (PyCFunction) infpy_set_env, METH_VARARGS | METH_KEYWORDS,
1109 1.11 christos "set_env (name, value) -> None\n\
1110 1.11 christos Set an environment variable of this inferior." },
1111 1.11 christos { "unset_env", (PyCFunction) infpy_unset_env, METH_VARARGS | METH_KEYWORDS,
1112 1.11 christos "unset_env (name) -> None\n\
1113 1.1 christos Unset an environment of this inferior." },
1114 1.1 christos { NULL }
1115 1.1 christos };
1116 1.5 christos
1117 1.1 christos PyTypeObject inferior_object_type =
1118 1.1 christos {
1119 1.1 christos PyVarObject_HEAD_INIT (NULL, 0)
1120 1.1 christos "gdb.Inferior", /* tp_name */
1121 1.1 christos sizeof (inferior_object), /* tp_basicsize */
1122 1.1 christos 0, /* tp_itemsize */
1123 1.1 christos infpy_dealloc, /* tp_dealloc */
1124 1.1 christos 0, /* tp_print */
1125 1.1 christos 0, /* tp_getattr */
1126 1.1 christos 0, /* tp_setattr */
1127 1.8 christos 0, /* tp_compare */
1128 1.1 christos infpy_repr, /* tp_repr */
1129 1.1 christos 0, /* tp_as_number */
1130 1.1 christos 0, /* tp_as_sequence */
1131 1.1 christos 0, /* tp_as_mapping */
1132 1.1 christos 0, /* tp_hash */
1133 1.1 christos 0, /* tp_call */
1134 1.1 christos 0, /* tp_str */
1135 1.1 christos 0, /* tp_getattro */
1136 1.1 christos 0, /* tp_setattro */
1137 1.10 christos 0, /* tp_as_buffer */
1138 1.1 christos Py_TPFLAGS_DEFAULT, /* tp_flags */
1139 1.1 christos "GDB inferior object", /* tp_doc */
1140 1.1 christos 0, /* tp_traverse */
1141 1.1 christos 0, /* tp_clear */
1142 1.1 christos 0, /* tp_richcompare */
1143 1.1 christos 0, /* tp_weaklistoffset */
1144 1.1 christos 0, /* tp_iter */
1145 1.1 christos 0, /* tp_iternext */
1146 1.1 christos inferior_object_methods, /* tp_methods */
1147 1.1 christos 0, /* tp_members */
1148 1.1 christos inferior_object_getset, /* tp_getset */
1149 1.1 christos 0, /* tp_base */
1150 1.1 christos 0, /* tp_dict */
1151 1.1 christos 0, /* tp_descr_get */
1152 1.11 christos 0, /* tp_descr_set */
1153 1.1 christos offsetof (inferior_object, dict), /* tp_dictoffset */
1154 1.1 christos 0, /* tp_init */
1155 1.1 christos 0 /* tp_alloc */
1156 };
1157