System notice: In light of the Debian OpenSSL security issue we've regenerated the server keys. See this thread for instructions and the new key fingerprints.

Commit 025c132276e9f066906c4c59a81291d300e9e847

Expose breakpoints to Python.

Commit diff

gdb/Makefile.in

 
262262#
263263SUBDIR_PYTHON_OBS = \
264264 python.o \
265 python-breakpoint.o \
265266 python-hooks.o \
266267 python-value.o
267268SUBDIR_PYTHON_SRCS = \
268269 python/python.c \
270 python/breakpoint.c \
269271 python/hooks.c \
270272 python/value.c
271273SUBDIR_PYTHON_DEPS =
34173417 $(command_h) $(libiberty_h) $(cli_decode_h) $(charset_h) $(top_h) \
34183418 $(exceptions_h) $(python_internal_h) $(version_h)
34193419 $(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) $(srcdir)/python/python.c
3420python-breakpoint.o: $(srcdir)/python/breakpoint.c $(defs_h) $(python_h) \
3421 $(value_h) $(exceptions_h) $(python_internal_h) $(charset_h) \
3422 $(breakpoint_h) $(gdbcmd_h)
3423 $(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) \
3424 $(srcdir)/python/breakpoint.c -o python-breakpoint.o
34203425python-hooks.o: $(srcdir)/python/hooks.c $(defs_h) $(cli_decode_h) \
34213426 $(charset_h) $(gdb_events_h) $(python_h) $(python_internal_h)
34223427 $(CC) -c $(INTERNAL_CFLAGS) $(PYTHON_CFLAGS) \
toggle raw diff

gdb/python/breakpoint.c

 
1/* Python interface to breakpoints
2
3 Copyright (C) 2008 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 "value.h"
22#include "exceptions.h"
23#include "python-internal.h"
24#include "charset.h"
25#include "breakpoint.h"
26#include "gdbcmd.h"
27
28
29/* From breakpoint.c. */
30extern struct breakpoint *breakpoint_chain;
31
32
33typedef struct breakpoint_object breakpoint_object;
34
35static PyObject *bppy_is_valid (PyObject *, PyObject *);
36static PyObject *bppy_is_enabled (PyObject *, PyObject *);
37static PyObject *bppy_is_silent (PyObject *, PyObject *);
38static PyObject *bppy_set_enabled (PyObject *, PyObject *);
39static PyObject *bppy_set_silent (PyObject *, PyObject *);
40static PyObject *bppy_get_location (PyObject *, PyObject *);
41static PyObject *bppy_get_condition (PyObject *, PyObject *);
42static PyObject *bppy_get_commands (PyObject *, PyObject *);
43
44
45/* A dynamically allocated vector of breakpoint objects. Each
46 breakpoint has a number. A breakpoint is valid if its slot in this
47 vector is non-null. When a breakpoint is deleted, we drop our
48 reference to it and zero its slot; this is how we let the Python
49 object have a lifetime which is independent from that of the gdb
50 breakpoint. */
51static breakpoint_object **bppy_breakpoints;
52
53/* Number of slots in bppy_breakpoints. */
54static int bppy_slots;
55
56/* Number of live breakpoints. */
57static int bppy_live;
58
59/* Variables used to pass information between the Breakpoint
60 constructor and the breakpoint-created hook function. */
61static breakpoint_object *bppy_pending_object;
62
63struct breakpoint_object
64{
65 PyObject_HEAD
66
67 /* The breakpoint number according to gdb. */
68 int number;
69
70 /* The gdb breakpoint object, or NULL if the breakpoint has been
71 deleted. */
72 struct breakpoint *bp;
73};
74
75#define BPPY_VALID_P(Num) \
76 ((Num) >= 0 \
77 && (Num) < bppy_slots \
78 && bppy_breakpoints[Num] != NULL)
79
80#define BPPY_REQUIRE_VALID(Breakpoint) \
81 do { \
82 if (! BPPY_VALID_P ((Breakpoint)->number)) \
83 return PyErr_Format (PyExc_RuntimeError, "breakpoint %d is invalid", \
84 (Breakpoint)->number); \
85 } while (0)
86
87static PyMethodDef breakpoint_object_methods[] =
88{
89 { "is_valid", bppy_is_valid, METH_NOARGS,
90 "Return true if this breakpoint is valid, false if not." },
91 { "is_enabled", bppy_is_enabled, METH_NOARGS,
92 "Return true if this breakpoint is enabled, false if disabled." },
93 { "is_silent", bppy_is_silent, METH_NOARGS,
94 "Return true if this breakpoint is silent, false if verbose." },
95
96 { "set_enabled", bppy_set_enabled, METH_O,
97 "Enable or disable this breakpoint" },
98 { "set_silent", bppy_set_silent, METH_O,
99 "Make this breakpoint quiet or verbose" },
100
101 { "get_location", bppy_get_location, METH_NOARGS,
102 "Return the location of this breakpoint, as specified by the user"},
103 { "get_condition", bppy_get_condition, METH_NOARGS,
104 "Return the condition of this breakpoint, as specified by the user.\n\
105Returns None if no condition set."},
106 { "get_commands", bppy_get_commands, METH_NOARGS,
107 "Return the commands of this breakpoint, as specified by the user"},
108
109 { 0 }
110};
111
112static PyTypeObject breakpoint_object_type =
113{
114 PyObject_HEAD_INIT (NULL)
115 0, /*ob_size*/
116 "gdb.Breakpoint", /*tp_name*/
117 sizeof (breakpoint_object), /*tp_basicsize*/
118 0, /*tp_itemsize*/
119 0, /*tp_dealloc*/
120 0, /*tp_print*/
121 0, /*tp_getattr*/
122 0, /*tp_setattr*/
123 0, /*tp_compare*/
124 0, /*tp_repr*/
125 0, /*tp_as_number*/
126 0, /*tp_as_sequence*/
127 0, /*tp_as_mapping*/
128 0, /*tp_hash */
129 0, /*tp_call*/
130 0, /*tp_str*/
131 0, /*tp_getattro*/
132 0, /*tp_setattro*/
133 0, /*tp_as_buffer*/
134 Py_TPFLAGS_DEFAULT, /*tp_flags*/
135 "GDB breakpoint object", /* tp_doc */
136 0, /* tp_traverse */
137 0, /* tp_clear */
138 0, /* tp_richcompare */
139 0, /* tp_weaklistoffset */
140 0, /* tp_iter */
141 0, /* tp_iternext */
142 breakpoint_object_methods /* tp_methods */
143};
144
145static PyObject *
146bppy_is_valid (PyObject *self, PyObject *args)
147{
148 if (((breakpoint_object *) self)->bp)
149 Py_RETURN_TRUE;
150 Py_RETURN_FALSE;
151}
152
153static PyObject *
154bppy_is_enabled (PyObject *self, PyObject *args)
155{
156 if (! ((breakpoint_object *) self)->bp)
157 Py_RETURN_FALSE;
158 /* Not clear what we really want here. */
159 if (((breakpoint_object *) self)->bp->enable_state == bp_enabled)
160 Py_RETURN_TRUE;
161 Py_RETURN_FALSE;
162}
163
164static PyObject *
165bppy_is_silent (PyObject *self, PyObject *args)
166{
167 BPPY_REQUIRE_VALID ((breakpoint_object *) self);
168 if (((breakpoint_object *) self)->bp->silent)
169 Py_RETURN_TRUE;
170 Py_RETURN_FALSE;
171}
172
173static PyObject *
174bppy_set_enabled (PyObject *self, PyObject *newvalue)
175{
176 breakpoint_object *self_bp = (breakpoint_object *) self;
177
178 BPPY_REQUIRE_VALID (self_bp);
179 if (! PyBool_Check (newvalue))
180 return PyErr_Format (PyExc_RuntimeError, "argument must be boolean");
181
182 if (newvalue == Py_True)
183 enable_breakpoint (self_bp->bp);
184 else
185 disable_breakpoint (self_bp->bp);
186
187 Py_RETURN_NONE;
188}
189
190static PyObject *
191bppy_set_silent (PyObject *self, PyObject *newvalue)
192{
193 breakpoint_object *self_bp = (breakpoint_object *) self;
194
195 BPPY_REQUIRE_VALID (self_bp);
196 if (! PyBool_Check (newvalue))
197 return PyErr_Format (PyExc_RuntimeError, "argument must be boolean");
198
199 self_bp->bp->silent = (newvalue == Py_True);
200
201 Py_RETURN_NONE;
202}
203
204static PyObject *
205bppy_get_location (PyObject *self, PyObject *args)
206{
207 char *str;
208
209 BPPY_REQUIRE_VALID ((breakpoint_object *) self);
210 str = ((breakpoint_object *) self)->bp->addr_string;
211 /* FIXME: watchpoints? tracepoints? */
212 if (! str)
213 str = "";
214 return PyString_Decode (str, strlen (str), host_charset (),
215 NULL /* FIXME */);
216}
217
218static PyObject *
219bppy_get_condition (PyObject *self, PyObject *args)
220{
221 char *str;
222 BPPY_REQUIRE_VALID ((breakpoint_object *) self);
223
224 str = ((breakpoint_object *) self)->bp->cond_string;
225 if (! str)
226 Py_RETURN_NONE;
227 return PyString_Decode (str, strlen (str), host_charset (),
228 NULL /* FIXME */);
229}
230
231static PyObject *
232bppy_get_commands (PyObject *self, PyObject *args)
233{
234 breakpoint_object *self_bp = (breakpoint_object *) self;
235 long length;
236 volatile struct gdb_exception except;
237 struct ui_file *string_file;
238 struct cleanup *chain;
239 PyObject *result;
240 char *cmdstr;
241
242 BPPY_REQUIRE_VALID (self_bp);
243
244 if (! self_bp->bp->commands)
245 Py_RETURN_NONE;
246
247 string_file = mem_fileopen ();
248 chain = make_cleanup_ui_file_delete (string_file);
249
250 TRY_CATCH (except, RETURN_MASK_ALL)
251 {
252 /* FIXME: this can fail. Maybe we need to be making a new
253 ui_out object here? */
254 ui_out_redirect (uiout, string_file);
255 print_command_lines (uiout, self_bp->bp->commands, 0);
256 ui_out_redirect (uiout, NULL);
257 }
258 cmdstr = ui_file_xstrdup (string_file, &length);
259 GDB_PY_HANDLE_EXCEPTION (except);
260
261 result = PyString_Decode (cmdstr, strlen (cmdstr), host_charset (),
262 NULL /* FIXME */);
263 do_cleanups (chain);
264 xfree (cmdstr);
265 return result;
266}
267
268static PyObject *
269bppy_new (PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
270{
271 PyObject *result;
272 char *spec;
273 volatile struct gdb_exception except;
274
275 /* FIXME: allow condition, thread, temporary, ... ? */
276 if (! PyArg_ParseTuple (args, "s", &spec))
277 return NULL;
278 result = subtype->tp_alloc (subtype, 0);
279 if (! result)
280 return NULL;
281 bppy_pending_object = (breakpoint_object *) result;
282 bppy_pending_object->number = -1;
283 bppy_pending_object->bp = NULL;
284
285 TRY_CATCH (except, RETURN_MASK_ALL)
286 {
287 set_breakpoint (spec, NULL, 0, 0, -1, 0, AUTO_BOOLEAN_TRUE);
288 }
289 GDB_PY_HANDLE_EXCEPTION (except);
290
291 BPPY_REQUIRE_VALID ((breakpoint_object *) result);
292 return result;
293}
294
295
296
297/* Static function to return a tuple holding all breakpoints. */
298
299PyObject *
300gdbpy_get_breakpoints (PyObject *self, PyObject *args)
301{
302 PyObject *result;
303
304 if (bppy_live == 0)
305 Py_RETURN_NONE;
306
307 result = PyTuple_New (bppy_live);
308 if (result)
309 {
310 int i, out = 0;
311 for (i = 0; out < bppy_live; ++i)
312 {
313 if (! bppy_breakpoints[i])
314 continue;
315 Py_INCREF (bppy_breakpoints[i]);
316 PyTuple_SetItem (result, out, (PyObject *) bppy_breakpoints[i]);
317 ++out;
318 }
319 }
320 return result;
321}
322
323
324
325/* Event callback functions. */
326
327void
328gdbpy_breakpoint_created (int num)
329{
330 breakpoint_object *newbp;
331 struct breakpoint *bp;
332
333 if (num < 0)
334 return;
335
336 for (bp = breakpoint_chain; bp; bp = bp->next)
337 if (bp->number == num)
338 break;
339 if (! bp)
340 return;
341
342 if (num >= bppy_slots)
343 {
344 int old = bppy_slots;
345 bppy_slots = bppy_slots * 2 + 10;
346 bppy_breakpoints
347 = (breakpoint_object **) xrealloc (bppy_breakpoints,
348 (bppy_slots
349 * sizeof (breakpoint_object *)));
350 memset (&bppy_breakpoints[old], 0,
351 (bppy_slots - old) * sizeof (PyObject *));
352 }
353
354 ++bppy_live;
355
356 if (bppy_pending_object)
357 {
358 newbp = bppy_pending_object;
359 bppy_pending_object = NULL;
360 }
361 else
362 newbp = PyObject_New (breakpoint_object, &breakpoint_object_type);
363 if (newbp)
364 {
365 PyObject *hookfn;
366
367 newbp->number = num;
368 newbp->bp = bp;
369 bppy_breakpoints[num] = newbp;
370
371 hookfn = gdbpy_get_hook_function ("new_breakpoint");
372 if (hookfn)
373 {
374 /* FIXME: refc? */
375 PyObject_CallFunctionObjArgs (hookfn, newbp, NULL);
376 }
377 }
378
379 if (PyErr_Occurred ())
380 {
381 /* FIXME -- what to do? */
382 PyErr_Print ();
383 }
384}
385
386void
387gdbpy_breakpoint_deleted (int num)
388{
389 if (BPPY_VALID_P (num))
390 {
391 bppy_breakpoints[num]->bp = NULL;
392 Py_DECREF (bppy_breakpoints[num]);
393 bppy_breakpoints[num] = NULL;
394 --bppy_live;
395 }
396}
397
398void
399gdbpy_initialize_breakpoints (void)
400{
401 breakpoint_object_type.tp_new = bppy_new;
402 if (PyType_Ready (&breakpoint_object_type) < 0)
403 return;
404
405 Py_INCREF (&breakpoint_object_type);
406 PyModule_AddObject (gdb_module, "Breakpoint",
407 (PyObject *) &breakpoint_object_type);
408}
toggle raw diff

gdb/python/hooks.c

 
112112gdbpy_initialize_hooks (void)
113113{
114114 handlers.architecture_changed = gdbpy_architecture_changed;
115 handlers.breakpoint_create = gdbpy_breakpoint_created;
116 handlers.breakpoint_delete = gdbpy_breakpoint_deleted;
115117 deprecated_set_gdb_event_hooks (&handlers);
116118
117119 deprecated_set_hook = gdbpy_set_hook;
toggle raw diff

gdb/python/python-internal.h

 
3131
3232PyObject *gdbpy_make_value_from_int (PyObject *self, PyObject *args);
3333PyObject *gdbpy_get_value_from_history (PyObject *self, PyObject *args);
34PyObject *gdbpy_get_breakpoints (PyObject *, PyObject *);
3435
3536PyObject *variable_to_python (struct cmd_list_element *);
3637PyObject *value_to_value_object (struct value *v);
4343
4444void gdbpy_initialize_values (void);
4545void gdbpy_initialize_hooks (void);
46void gdbpy_initialize_breakpoints (void);
4647
4748/* Use this after a TRY_EXCEPT to throw the appropriate Python
4849 exception. FIXME: throw different errors depending on
5656 "%s", Exception.message); \
5757 } while (0)
5858
59/* Breakpoint hook functions. */
60void gdbpy_breakpoint_created (int);
61void gdbpy_breakpoint_deleted (int);
62
5963#endif /* GDB_PYTHON_INTERNAL_H */
toggle raw diff

gdb/python/python.c

 
5353 { "show", get_show_variable, METH_VARARGS,
5454 "Return a gdb setting's value" },
5555
56 { "get_breakpoints", gdbpy_get_breakpoints, METH_NOARGS,
57 "Return a tuple of all breakpoint objects" },
58
5659 {NULL, NULL, 0, NULL}
5760 };
5861
6969
7070 gdbpy_initialize_hooks ();
7171 gdbpy_initialize_values ();
72 gdbpy_initialize_breakpoints ();
7273
7374 PyRun_SimpleString ("import gdb");
7475
toggle raw diff