GDB (xrefs)
Loading...
Searching...
No Matches
py-progspace.c
Go to the documentation of this file.
1/* Python interface to program spaces.
2
3 Copyright (C) 2010-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 "charset.h"
23#include "progspace.h"
24#include "objfiles.h"
25#include "language.h"
26#include "arch-utils.h"
27#include "solib.h"
28#include "block.h"
29
31{
32 PyObject_HEAD
33
34 /* The corresponding pspace. */
36
37 /* Dictionary holding user-added attributes.
38 This is the __dict__ attribute of the object. */
39 PyObject *dict;
40
41 /* The pretty-printer list of functions. */
42 PyObject *printers;
43
44 /* The frame filter list of functions. */
45 PyObject *frame_filters;
46
47 /* The frame unwinder list. */
48 PyObject *frame_unwinders;
49
50 /* The type-printer list. */
51 PyObject *type_printers;
52
53 /* The debug method list. */
54 PyObject *xmethods;
55};
56
57extern PyTypeObject pspace_object_type
59
60/* Clear the PSPACE pointer in a Pspace object and remove the reference. */
62{
64 {
65 /* This is a fiction, but we're in a nasty spot: The pspace is in the
66 process of being deleted, we can't rely on anything in it. Plus
67 this is one time when the current program space and current inferior
68 are not in sync: All inferiors that use PSPACE may no longer exist.
69 We don't need to do much here, and since "there is always an inferior"
70 using target_gdbarch suffices.
71 Note: We cannot call get_current_arch because it may try to access
72 the target, which may involve accessing data in the pspace currently
73 being deleted. */
74 struct gdbarch *arch = target_gdbarch ();
75
76 gdbpy_enter enter_py (arch);
77 gdbpy_ref<pspace_object> object (obj);
78 object->pspace = NULL;
79 }
80};
81
84
85/* Require that PSPACE_OBJ be a valid program space ID. */
86#define PSPY_REQUIRE_VALID(pspace_obj) \
87 do { \
88 if (pspace_obj->pspace == nullptr) \
89 { \
90 PyErr_SetString (PyExc_RuntimeError, \
91 _("Program space no longer exists.")); \
92 return NULL; \
93 } \
94 } while (0)
95
96/* An Objfile method which returns the objfile's file name, or None. */
97
98static PyObject *
99pspy_get_filename (PyObject *self, void *closure)
100{
101 pspace_object *obj = (pspace_object *) self;
102
103 if (obj->pspace)
104 {
106
107 if (objfile)
109 .release ());
110 }
111 Py_RETURN_NONE;
112}
113
114static void
115pspy_dealloc (PyObject *self)
116{
117 pspace_object *ps_self = (pspace_object *) self;
118
119 Py_XDECREF (ps_self->dict);
120 Py_XDECREF (ps_self->printers);
121 Py_XDECREF (ps_self->frame_filters);
122 Py_XDECREF (ps_self->frame_unwinders);
123 Py_XDECREF (ps_self->type_printers);
124 Py_XDECREF (ps_self->xmethods);
125 Py_TYPE (self)->tp_free (self);
126}
127
128/* Initialize a pspace_object.
129 The result is a boolean indicating success. */
130
131static int
133{
134 self->pspace = NULL;
135
136 self->dict = PyDict_New ();
137 if (self->dict == NULL)
138 return 0;
139
140 self->printers = PyList_New (0);
141 if (self->printers == NULL)
142 return 0;
143
144 self->frame_filters = PyDict_New ();
145 if (self->frame_filters == NULL)
146 return 0;
147
148 self->frame_unwinders = PyList_New (0);
149 if (self->frame_unwinders == NULL)
150 return 0;
151
152 self->type_printers = PyList_New (0);
153 if (self->type_printers == NULL)
154 return 0;
155
156 self->xmethods = PyList_New (0);
157 if (self->xmethods == NULL)
158 return 0;
159
160 return 1;
161}
162
163static PyObject *
164pspy_new (PyTypeObject *type, PyObject *args, PyObject *keywords)
165{
166 gdbpy_ref<pspace_object> self ((pspace_object *) type->tp_alloc (type, 0));
167
168 if (self != NULL)
169 {
170 if (!pspy_initialize (self.get ()))
171 return NULL;
172 }
173
174 return (PyObject *) self.release ();
175}
176
177PyObject *
178pspy_get_printers (PyObject *o, void *ignore)
179{
180 pspace_object *self = (pspace_object *) o;
181
182 Py_INCREF (self->printers);
183 return self->printers;
184}
185
186static int
187pspy_set_printers (PyObject *o, PyObject *value, void *ignore)
188{
189 pspace_object *self = (pspace_object *) o;
190
191 if (! value)
192 {
193 PyErr_SetString (PyExc_TypeError,
194 "cannot delete the pretty_printers attribute");
195 return -1;
196 }
197
198 if (! PyList_Check (value))
199 {
200 PyErr_SetString (PyExc_TypeError,
201 "the pretty_printers attribute must be a list");
202 return -1;
203 }
204
205 /* Take care in case the LHS and RHS are related somehow. */
206 gdbpy_ref<> tmp (self->printers);
207 Py_INCREF (value);
208 self->printers = value;
209
210 return 0;
211}
212
213/* Return the Python dictionary attribute containing frame filters for
214 this program space. */
215PyObject *
216pspy_get_frame_filters (PyObject *o, void *ignore)
217{
218 pspace_object *self = (pspace_object *) o;
219
220 Py_INCREF (self->frame_filters);
221 return self->frame_filters;
222}
223
224/* Set this object file's frame filters dictionary to FILTERS. */
225static int
226pspy_set_frame_filters (PyObject *o, PyObject *frame, void *ignore)
227{
228 pspace_object *self = (pspace_object *) o;
229
230 if (! frame)
231 {
232 PyErr_SetString (PyExc_TypeError,
233 "cannot delete the frame filter attribute");
234 return -1;
235 }
236
237 if (! PyDict_Check (frame))
238 {
239 PyErr_SetString (PyExc_TypeError,
240 "the frame filter attribute must be a dictionary");
241 return -1;
242 }
243
244 /* Take care in case the LHS and RHS are related somehow. */
245 gdbpy_ref<> tmp (self->frame_filters);
246 Py_INCREF (frame);
247 self->frame_filters = frame;
248
249 return 0;
250}
251
252/* Return the list of the frame unwinders for this program space. */
253
254PyObject *
255pspy_get_frame_unwinders (PyObject *o, void *ignore)
256{
257 pspace_object *self = (pspace_object *) o;
258
259 Py_INCREF (self->frame_unwinders);
260 return self->frame_unwinders;
261}
262
263/* Set this program space's list of the unwinders to UNWINDERS. */
264
265static int
266pspy_set_frame_unwinders (PyObject *o, PyObject *unwinders, void *ignore)
267{
268 pspace_object *self = (pspace_object *) o;
269
270 if (!unwinders)
271 {
272 PyErr_SetString (PyExc_TypeError,
273 "cannot delete the frame unwinders list");
274 return -1;
275 }
276
277 if (!PyList_Check (unwinders))
278 {
279 PyErr_SetString (PyExc_TypeError,
280 "the frame unwinders attribute must be a list");
281 return -1;
282 }
283
284 /* Take care in case the LHS and RHS are related somehow. */
285 gdbpy_ref<> tmp (self->frame_unwinders);
286 Py_INCREF (unwinders);
287 self->frame_unwinders = unwinders;
288
289 return 0;
290}
291
292/* Get the 'type_printers' attribute. */
293
294static PyObject *
295pspy_get_type_printers (PyObject *o, void *ignore)
296{
297 pspace_object *self = (pspace_object *) o;
298
299 Py_INCREF (self->type_printers);
300 return self->type_printers;
301}
302
303/* Get the 'xmethods' attribute. */
304
305PyObject *
306pspy_get_xmethods (PyObject *o, void *ignore)
307{
308 pspace_object *self = (pspace_object *) o;
309
310 Py_INCREF (self->xmethods);
311 return self->xmethods;
312}
313
314/* Set the 'type_printers' attribute. */
315
316static int
317pspy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
318{
319 pspace_object *self = (pspace_object *) o;
320
321 if (! value)
322 {
323 PyErr_SetString (PyExc_TypeError,
324 "cannot delete the type_printers attribute");
325 return -1;
326 }
327
328 if (! PyList_Check (value))
329 {
330 PyErr_SetString (PyExc_TypeError,
331 "the type_printers attribute must be a list");
332 return -1;
333 }
334
335 /* Take care in case the LHS and RHS are related somehow. */
336 gdbpy_ref<> tmp (self->type_printers);
337 Py_INCREF (value);
338 self->type_printers = value;
339
340 return 0;
341}
342
343/* Implement the objfiles method. */
344
345static PyObject *
346pspy_get_objfiles (PyObject *self_, PyObject *args)
347{
348 pspace_object *self = (pspace_object *) self_;
349
350 PSPY_REQUIRE_VALID (self);
351
352 gdbpy_ref<> list (PyList_New (0));
353 if (list == NULL)
354 return NULL;
355
356 if (self->pspace != NULL)
357 {
358 for (objfile *objf : self->pspace->objfiles ())
359 {
361
362 if (item == nullptr
363 || PyList_Append (list.get (), item.get ()) == -1)
364 return NULL;
365 }
366 }
367
368 return list.release ();
369}
370
371/* Implementation of solib_name (Long) -> String.
372 Returns the name of the shared library holding a given address, or None. */
373
374static PyObject *
375pspy_solib_name (PyObject *o, PyObject *args)
376{
377 CORE_ADDR pc;
378 PyObject *pc_obj;
379
380 pspace_object *self = (pspace_object *) o;
381
382 PSPY_REQUIRE_VALID (self);
383
384 if (!PyArg_ParseTuple (args, "O", &pc_obj))
385 return NULL;
386 if (get_addr_from_python (pc_obj, &pc) < 0)
387 return nullptr;
388
389 const char *soname = solib_name_from_address (self->pspace, pc);
390 if (soname == nullptr)
391 Py_RETURN_NONE;
392 return host_string_to_python_string (soname).release ();
393}
394
395/* Return the innermost lexical block containing the specified pc value,
396 or 0 if there is none. */
397static PyObject *
398pspy_block_for_pc (PyObject *o, PyObject *args)
399{
400 pspace_object *self = (pspace_object *) o;
401 CORE_ADDR pc;
402 PyObject *pc_obj;
403 const struct block *block = NULL;
404 struct compunit_symtab *cust = NULL;
405
406 PSPY_REQUIRE_VALID (self);
407
408 if (!PyArg_ParseTuple (args, "O", &pc_obj))
409 return NULL;
410 if (get_addr_from_python (pc_obj, &pc) < 0)
411 return nullptr;
412
413 try
414 {
416
418 cust = find_pc_compunit_symtab (pc);
419
420 if (cust != NULL && cust->objfile () != NULL)
421 block = block_for_pc (pc);
422 }
423 catch (const gdb_exception &except)
424 {
426 }
427
428 if (cust == NULL || cust->objfile () == NULL)
429 Py_RETURN_NONE;
430
431 if (block)
432 return block_to_block_object (block, cust->objfile ());
433
434 Py_RETURN_NONE;
435}
436
437/* Implementation of the find_pc_line function.
438 Returns the gdb.Symtab_and_line object corresponding to a PC value. */
439
440static PyObject *
441pspy_find_pc_line (PyObject *o, PyObject *args)
442{
443 CORE_ADDR pc;
444 PyObject *result = NULL; /* init for gcc -Wall */
445 PyObject *pc_obj;
446 pspace_object *self = (pspace_object *) o;
447
448 PSPY_REQUIRE_VALID (self);
449
450 if (!PyArg_ParseTuple (args, "O", &pc_obj))
451 return NULL;
452 if (get_addr_from_python (pc_obj, &pc) < 0)
453 return nullptr;
454
455 try
456 {
457 struct symtab_and_line sal;
459
461
462 sal = find_pc_line (pc, 0);
463 result = symtab_and_line_to_sal_object (sal);
464 }
465 catch (const gdb_exception &except)
466 {
468 }
469
470 return result;
471}
472
473/* Implementation of is_valid (self) -> Boolean.
474 Returns True if this program space still exists in GDB. */
475
476static PyObject *
477pspy_is_valid (PyObject *o, PyObject *args)
478{
479 pspace_object *self = (pspace_object *) o;
480
481 if (self->pspace == NULL)
482 Py_RETURN_FALSE;
483
484 Py_RETURN_TRUE;
485}
486
487
488
489/* Return a new reference to the Python object of type Pspace
490 representing PSPACE. If the object has already been created,
491 return it. Otherwise, create it. Return NULL and set the Python
492 error on failure. */
493
496{
497 PyObject *result = (PyObject *) pspy_pspace_data_key.get (pspace);
498 if (result == NULL)
499 {
501 ((pspace_object *) PyObject_New (pspace_object, &pspace_object_type));
502 if (object == NULL)
503 return NULL;
504 if (!pspy_initialize (object.get ()))
505 return NULL;
506
507 object->pspace = pspace;
508 pspy_pspace_data_key.set (pspace, object.get ());
509 result = (PyObject *) object.release ();
510 }
511
512 return gdbpy_ref<>::new_reference (result);
513}
514
515/* See python-internal.h. */
516
517struct program_space *
519{
520 gdb_assert (gdbpy_is_progspace (obj));
521 return ((pspace_object *) obj)->pspace;
522}
523
524/* See python-internal.h. */
525
526bool
527gdbpy_is_progspace (PyObject *obj)
528{
529 return PyObject_TypeCheck (obj, &pspace_object_type);
530}
531
532int
534{
535 if (PyType_Ready (&pspace_object_type) < 0)
536 return -1;
537
538 return gdb_pymodule_addobject (gdb_module, "Progspace",
539 (PyObject *) &pspace_object_type);
540}
541
542
543
545{
546 { "__dict__", gdb_py_generic_dict, NULL,
547 "The __dict__ for this progspace.", &pspace_object_type },
548 { "filename", pspy_get_filename, NULL,
549 "The progspace's main filename, or None.", NULL },
550 { "pretty_printers", pspy_get_printers, pspy_set_printers,
551 "Pretty printers.", NULL },
553 "Frame filters.", NULL },
555 "Frame unwinders.", NULL },
557 "Type printers.", NULL },
558 { "xmethods", pspy_get_xmethods, NULL,
559 "Debug methods.", NULL },
560 { NULL }
561};
562
563static PyMethodDef progspace_object_methods[] =
564{
565 { "objfiles", pspy_get_objfiles, METH_NOARGS,
566 "Return a sequence of objfiles associated to this program space." },
567 { "solib_name", pspy_solib_name, METH_VARARGS,
568 "solib_name (Long) -> String.\n\
569Return the name of the shared library holding a given address, or None." },
570 { "block_for_pc", pspy_block_for_pc, METH_VARARGS,
571 "Return the block containing the given pc value, or None." },
572 { "find_pc_line", pspy_find_pc_line, METH_VARARGS,
573 "find_pc_line (pc) -> Symtab_and_line.\n\
574Return the gdb.Symtab_and_line object corresponding to the pc value." },
575 { "is_valid", pspy_is_valid, METH_NOARGS,
576 "is_valid () -> Boolean.\n\
577Return true if this program space is valid, false if not." },
578 { NULL }
579};
580
581PyTypeObject pspace_object_type =
582{
583 PyVarObject_HEAD_INIT (NULL, 0)
584 "gdb.Progspace", /*tp_name*/
585 sizeof (pspace_object), /*tp_basicsize*/
586 0, /*tp_itemsize*/
587 pspy_dealloc, /*tp_dealloc*/
588 0, /*tp_print*/
589 0, /*tp_getattr*/
590 0, /*tp_setattr*/
591 0, /*tp_compare*/
592 0, /*tp_repr*/
593 0, /*tp_as_number*/
594 0, /*tp_as_sequence*/
595 0, /*tp_as_mapping*/
596 0, /*tp_hash */
597 0, /*tp_call*/
598 0, /*tp_str*/
599 0, /*tp_getattro*/
600 0, /*tp_setattro*/
601 0, /*tp_as_buffer*/
602 Py_TPFLAGS_DEFAULT, /*tp_flags*/
603 "GDB progspace object", /* tp_doc */
604 0, /* tp_traverse */
605 0, /* tp_clear */
606 0, /* tp_richcompare */
607 0, /* tp_weaklistoffset */
608 0, /* tp_iter */
609 0, /* tp_iternext */
610 progspace_object_methods, /* tp_methods */
611 0, /* tp_members */
612 pspace_getset, /* tp_getset */
613 0, /* tp_base */
614 0, /* tp_dict */
615 0, /* tp_descr_get */
616 0, /* tp_descr_set */
617 offsetof (pspace_object, dict), /* tp_dictoffset */
618 0, /* tp_init */
619 0, /* tp_alloc */
620 pspy_new, /* tp_new */
621};
constexpr string_view get()
Definition: 70483.cc:49
struct gdbarch * target_gdbarch(void)
Definition: arch-utils.c:1453
const struct block * block_for_pc(CORE_ADDR pc)
Definition: block.c:283
void set(unsigned key, void *datum)
Definition: registry.h:204
void * get(unsigned key)
Definition: registry.h:211
const char * objfile_name(const struct objfile *objfile)
Definition: objfiles.c:1308
void set_current_program_space(struct program_space *pspace)
Definition: progspace.c:224
PyObject * block_to_block_object(const struct block *block, struct objfile *objfile)
Definition: py-block.c:329
gdbpy_ref objfile_to_objfile_object(struct objfile *objfile)
Definition: py-objfile.c:686
PyTypeObject pspace_object_type
Definition: py-progspace.c:581
bool gdbpy_is_progspace(PyObject *obj)
Definition: py-progspace.c:527
static const registry< program_space >::key< pspace_object, pspace_deleter > pspy_pspace_data_key
Definition: py-progspace.c:83
static PyObject * pspy_is_valid(PyObject *o, PyObject *args)
Definition: py-progspace.c:477
static int pspy_set_frame_filters(PyObject *o, PyObject *frame, void *ignore)
Definition: py-progspace.c:226
static PyObject * pspy_get_objfiles(PyObject *self_, PyObject *args)
Definition: py-progspace.c:346
static PyObject * pspy_get_filename(PyObject *self, void *closure)
Definition: py-progspace.c:99
static int pspy_set_type_printers(PyObject *o, PyObject *value, void *ignore)
Definition: py-progspace.c:317
static PyObject * pspy_new(PyTypeObject *type, PyObject *args, PyObject *keywords)
Definition: py-progspace.c:164
static PyObject * pspy_find_pc_line(PyObject *o, PyObject *args)
Definition: py-progspace.c:441
static PyObject * pspy_solib_name(PyObject *o, PyObject *args)
Definition: py-progspace.c:375
static gdb_PyGetSetDef pspace_getset[]
Definition: py-progspace.c:544
PyObject * pspy_get_xmethods(PyObject *o, void *ignore)
Definition: py-progspace.c:306
static PyObject * pspy_block_for_pc(PyObject *o, PyObject *args)
Definition: py-progspace.c:398
static int pspy_set_frame_unwinders(PyObject *o, PyObject *unwinders, void *ignore)
Definition: py-progspace.c:266
static PyObject * pspy_get_type_printers(PyObject *o, void *ignore)
Definition: py-progspace.c:295
#define PSPY_REQUIRE_VALID(pspace_obj)
Definition: py-progspace.c:86
gdbpy_ref pspace_to_pspace_object(struct program_space *pspace)
Definition: py-progspace.c:495
static void pspy_dealloc(PyObject *self)
Definition: py-progspace.c:115
struct program_space * progspace_object_to_program_space(PyObject *obj)
Definition: py-progspace.c:518
static int pspy_set_printers(PyObject *o, PyObject *value, void *ignore)
Definition: py-progspace.c:187
int gdbpy_initialize_pspace(void)
Definition: py-progspace.c:533
static int pspy_initialize(pspace_object *self)
Definition: py-progspace.c:132
PyObject * pspy_get_printers(PyObject *o, void *ignore)
Definition: py-progspace.c:178
PyObject * pspy_get_frame_filters(PyObject *o, void *ignore)
Definition: py-progspace.c:216
static PyMethodDef progspace_object_methods[]
Definition: py-progspace.c:563
PyObject * pspy_get_frame_unwinders(PyObject *o, void *ignore)
Definition: py-progspace.c:255
gdb::ref_ptr< T, gdbpy_ref_policy< T > > gdbpy_ref
Definition: py-ref.h:43
PyObject * symtab_and_line_to_sal_object(struct symtab_and_line sal)
Definition: py-symtab.c:481
gdbpy_ref host_string_to_python_string(const char *str)
Definition: py-utils.c:153
int get_addr_from_python(PyObject *obj, CORE_ADDR *addr)
Definition: py-utils.c:236
int gdb_pymodule_addobject(PyObject *module, const char *name, PyObject *object)
Definition: py-utils.c:331
PyObject * gdb_py_generic_dict(PyObject *self, void *closure)
Definition: py-utils.c:314
PyObject * gdb_module
Definition: python.c:84
#define CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF(ARG)
#define GDB_PY_HANDLE_EXCEPTION(Exception)
const char * solib_name_from_address(struct program_space *pspace, CORE_ADDR address)
Definition: solib.c:1193
Definition: block.h:109
struct objfile * objfile() const
Definition: symtab.h:1714
objfiles_range objfiles()
Definition: progspace.h:209
struct objfile * symfile_object_file
Definition: progspace.h:353
void operator()(pspace_object *obj)
Definition: py-progspace.c:63
PyObject * frame_unwinders
Definition: py-progspace.c:48
PyObject * type_printers
Definition: py-progspace.c:51
PyObject * xmethods
Definition: py-progspace.c:54
PyObject_HEAD struct program_space * pspace
Definition: py-progspace.c:35
PyObject * dict
Definition: py-progspace.c:39
PyObject * printers
Definition: py-progspace.c:42
PyObject * frame_filters
Definition: py-progspace.c:45
CORE_ADDR pc
Definition: symtab.h:2272
struct program_space * pspace
Definition: symtab.h:2261
Definition: gdbtypes.h:922
Definition: value.c:181
struct compunit_symtab * find_pc_compunit_symtab(CORE_ADDR pc)
Definition: symtab.c:2954
struct symtab_and_line find_pc_line(CORE_ADDR pc, int notcurrent)
Definition: symtab.c:3297