py-breakpoint.c revision 1.1.1.9 1 /* Python interface to breakpoints
2
3 Copyright (C) 2008-2024 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 "value.h"
21 #include "python-internal.h"
22 #include "python.h"
23 #include "charset.h"
24 #include "breakpoint.h"
25 #include "cli/cli-cmds.h"
26 #include "gdbthread.h"
27 #include "observable.h"
28 #include "cli/cli-script.h"
29 #include "ada-lang.h"
30 #include "arch-utils.h"
31 #include "language.h"
32 #include "location.h"
33 #include "py-event.h"
34 #include "linespec.h"
35 #include "gdbsupport/common-utils.h"
36
37 extern PyTypeObject breakpoint_location_object_type
38 CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("breakpoint_location_object");
39
40 struct gdbpy_breakpoint_location_object
41 {
42 PyObject_HEAD
43
44 /* An owning reference to the gdb breakpoint location object. */
45 bp_location *bp_loc;
46
47 /* An owning reference to the location's breakpoint owner. */
48 gdbpy_breakpoint_object *owner;
49 };
50
51 /* Require that BREAKPOINT and LOCATION->OWNER are the same; throw a Python
52 exception if they are not. */
53 #define BPLOCPY_REQUIRE_VALID(Breakpoint, Location) \
54 do { \
55 if ((Breakpoint)->bp != (Location)->bp_loc->owner) \
56 return PyErr_Format (PyExc_RuntimeError, \
57 _("Breakpoint location is invalid.")); \
58 } while (0)
59
60 /* Require that BREAKPOINT and LOCATION->OWNER are the same; throw a Python
61 exception if they are not. This macro is for use in setter functions. */
62 #define BPLOCPY_SET_REQUIRE_VALID(Breakpoint, Location) \
63 do { \
64 if ((Breakpoint)->bp != (Location)->bp_loc->owner) \
65 { \
66 PyErr_Format (PyExc_RuntimeError, \
67 _("Breakpoint location is invalid.")); \
68 return -1; \
69 } \
70 } while (0)
71
72 /* Debugging of Python breakpoints. */
73
74 static bool pybp_debug;
75
76 /* Implementation of "show debug py-breakpoint". */
77
78 static void
79 show_pybp_debug (struct ui_file *file, int from_tty,
80 struct cmd_list_element *c, const char *value)
81 {
82 gdb_printf (file, _("Python breakpoint debugging is %s.\n"), value);
83 }
84
85 /* Print a "py-breakpoint" debug statement. */
86
87 #define pybp_debug_printf(fmt, ...) \
88 debug_prefixed_printf_cond (pybp_debug, "py-breakpoint", fmt, ##__VA_ARGS__)
89
90 /* Print a "py-breakpoint" enter/exit debug statements. */
91
92 #define PYBP_SCOPED_DEBUG_ENTER_EXIT \
93 scoped_debug_enter_exit (pybp_debug, "py-breakpoint")
94
95 /* Number of live breakpoints. */
96 static int bppy_live;
97
98 /* Variables used to pass information between the Breakpoint
99 constructor and the breakpoint-created hook function. */
100 gdbpy_breakpoint_object *bppy_pending_object;
101
102 /* Function that is called when a Python condition is evaluated. */
103 static const char stop_func[] = "stop";
104
105 /* This is used to initialize various gdb.bp_* constants. */
106 struct pybp_code
107 {
108 /* The name. */
109 const char *name;
110 /* The code. */
111 int code;
112 };
113
114 /* Entries related to the type of user set breakpoints. */
115 static struct pybp_code pybp_codes[] =
116 {
117 { "BP_NONE", bp_none},
118 { "BP_BREAKPOINT", bp_breakpoint},
119 { "BP_HARDWARE_BREAKPOINT", bp_hardware_breakpoint},
120 { "BP_WATCHPOINT", bp_watchpoint},
121 { "BP_HARDWARE_WATCHPOINT", bp_hardware_watchpoint},
122 { "BP_READ_WATCHPOINT", bp_read_watchpoint},
123 { "BP_ACCESS_WATCHPOINT", bp_access_watchpoint},
124 { "BP_CATCHPOINT", bp_catchpoint},
125 {NULL} /* Sentinel. */
126 };
127
128 /* Entries related to the type of watchpoint. */
129 static struct pybp_code pybp_watch_types[] =
130 {
131 { "WP_READ", hw_read},
132 { "WP_WRITE", hw_write},
133 { "WP_ACCESS", hw_access},
134 {NULL} /* Sentinel. */
135 };
136
137 /* Python function which checks the validity of a breakpoint object. */
138 static PyObject *
139 bppy_is_valid (PyObject *self, PyObject *args)
140 {
141 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
142
143 if (self_bp->bp)
144 Py_RETURN_TRUE;
145 Py_RETURN_FALSE;
146 }
147
148 /* Python function to test whether or not the breakpoint is enabled. */
149 static PyObject *
150 bppy_get_enabled (PyObject *self, void *closure)
151 {
152 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
153
154 BPPY_REQUIRE_VALID (self_bp);
155 if (! self_bp->bp)
156 Py_RETURN_FALSE;
157 if (self_bp->bp->enable_state == bp_enabled)
158 Py_RETURN_TRUE;
159 Py_RETURN_FALSE;
160 }
161
162 /* Python function to test whether or not the breakpoint is silent. */
163 static PyObject *
164 bppy_get_silent (PyObject *self, void *closure)
165 {
166 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
167
168 BPPY_REQUIRE_VALID (self_bp);
169 if (self_bp->bp->silent)
170 Py_RETURN_TRUE;
171 Py_RETURN_FALSE;
172 }
173
174 /* Python function to set the enabled state of a breakpoint. */
175 static int
176 bppy_set_enabled (PyObject *self, PyObject *newvalue, void *closure)
177 {
178 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
179 int cmp;
180
181 BPPY_SET_REQUIRE_VALID (self_bp);
182
183 if (newvalue == NULL)
184 {
185 PyErr_SetString (PyExc_TypeError,
186 _("Cannot delete `enabled' attribute."));
187
188 return -1;
189 }
190 else if (! PyBool_Check (newvalue))
191 {
192 PyErr_SetString (PyExc_TypeError,
193 _("The value of `enabled' must be a boolean."));
194 return -1;
195 }
196
197 cmp = PyObject_IsTrue (newvalue);
198 if (cmp < 0)
199 return -1;
200
201 try
202 {
203 if (cmp == 1)
204 enable_breakpoint (self_bp->bp);
205 else
206 disable_breakpoint (self_bp->bp);
207 }
208 catch (const gdb_exception &except)
209 {
210 GDB_PY_SET_HANDLE_EXCEPTION (except);
211 }
212
213 return 0;
214 }
215
216 /* Python function to set the 'silent' state of a breakpoint. */
217 static int
218 bppy_set_silent (PyObject *self, PyObject *newvalue, void *closure)
219 {
220 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
221 int cmp;
222
223 BPPY_SET_REQUIRE_VALID (self_bp);
224
225 if (newvalue == NULL)
226 {
227 PyErr_SetString (PyExc_TypeError,
228 _("Cannot delete `silent' attribute."));
229 return -1;
230 }
231 else if (! PyBool_Check (newvalue))
232 {
233 PyErr_SetString (PyExc_TypeError,
234 _("The value of `silent' must be a boolean."));
235 return -1;
236 }
237
238 cmp = PyObject_IsTrue (newvalue);
239 if (cmp < 0)
240 return -1;
241 else
242 breakpoint_set_silent (self_bp->bp, cmp);
243
244 return 0;
245 }
246
247 /* Python function to set the thread of a breakpoint. */
248 static int
249 bppy_set_thread (PyObject *self, PyObject *newvalue, void *closure)
250 {
251 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
252 long id;
253
254 BPPY_SET_REQUIRE_VALID (self_bp);
255
256 if (newvalue == NULL)
257 {
258 PyErr_SetString (PyExc_TypeError,
259 _("Cannot delete `thread' attribute."));
260 return -1;
261 }
262 else if (PyLong_Check (newvalue))
263 {
264 if (! gdb_py_int_as_long (newvalue, &id))
265 return -1;
266
267 if (!valid_global_thread_id (id))
268 {
269 PyErr_SetString (PyExc_RuntimeError,
270 _("Invalid thread ID."));
271 return -1;
272 }
273
274 if (self_bp->bp->task != -1)
275 {
276 PyErr_SetString (PyExc_RuntimeError,
277 _("Cannot set both task and thread attributes."));
278 return -1;
279 }
280 }
281 else if (newvalue == Py_None)
282 id = -1;
283 else
284 {
285 PyErr_SetString (PyExc_TypeError,
286 _("The value of `thread' must be an integer or None."));
287 return -1;
288 }
289
290 if (self_bp->bp->inferior != -1 && id != -1)
291 {
292 PyErr_SetString (PyExc_RuntimeError,
293 _("Cannot have both 'thread' and 'inferior' "
294 "conditions on a breakpoint"));
295 return -1;
296 }
297
298 breakpoint_set_thread (self_bp->bp, id);
299
300 return 0;
301 }
302
303 /* Python function to set the inferior of a breakpoint. */
304
305 static int
306 bppy_set_inferior (PyObject *self, PyObject *newvalue, void *closure)
307 {
308 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
309 long id;
310
311 BPPY_SET_REQUIRE_VALID (self_bp);
312
313 if (newvalue == NULL)
314 {
315 PyErr_SetString (PyExc_TypeError,
316 _("Cannot delete 'inferior' attribute."));
317 return -1;
318 }
319 else if (PyLong_Check (newvalue))
320 {
321 if (!gdb_py_int_as_long (newvalue, &id))
322 return -1;
323
324 if (!valid_global_inferior_id (id))
325 {
326 PyErr_SetString (PyExc_RuntimeError,
327 _("Invalid inferior ID."));
328 return -1;
329 }
330 }
331 else if (newvalue == Py_None)
332 id = -1;
333 else
334 {
335 PyErr_SetString (PyExc_TypeError,
336 _("The value of 'inferior' must be an integer or None."));
337 return -1;
338 }
339
340 if (self_bp->bp->type != bp_breakpoint
341 && self_bp->bp->type != bp_hardware_breakpoint)
342 {
343 PyErr_SetString (PyExc_RuntimeError,
344 _("Cannot set 'inferior' attribute on a gdb.Breakpoint "
345 "of this type"));
346 return -1;
347 }
348
349 if (self_bp->bp->thread != -1 && id != -1)
350 {
351 PyErr_SetString (PyExc_RuntimeError,
352 _("Cannot have both 'thread' and 'inferior' conditions "
353 "on a breakpoint"));
354 return -1;
355 }
356
357 if (self_bp->bp->task != -1 && id != -1)
358 {
359 PyErr_SetString (PyExc_RuntimeError,
360 _("Cannot have both 'task' and 'inferior' conditions "
361 "on a breakpoint"));
362 return -1;
363 }
364
365 breakpoint_set_inferior (self_bp->bp, id);
366
367 return 0;
368 }
369
370 /* Python function to set the (Ada) task of a breakpoint. */
371 static int
372 bppy_set_task (PyObject *self, PyObject *newvalue, void *closure)
373 {
374 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
375 long id;
376 int valid_id = 0;
377
378 BPPY_SET_REQUIRE_VALID (self_bp);
379
380 if (newvalue == NULL)
381 {
382 PyErr_SetString (PyExc_TypeError,
383 _("Cannot delete `task' attribute."));
384 return -1;
385 }
386 else if (PyLong_Check (newvalue))
387 {
388 if (! gdb_py_int_as_long (newvalue, &id))
389 return -1;
390
391 try
392 {
393 valid_id = valid_task_id (id);
394 }
395 catch (const gdb_exception &except)
396 {
397 GDB_PY_SET_HANDLE_EXCEPTION (except);
398 }
399
400 if (! valid_id)
401 {
402 PyErr_SetString (PyExc_RuntimeError,
403 _("Invalid task ID."));
404 return -1;
405 }
406
407 if (self_bp->bp->thread != -1)
408 {
409 PyErr_SetString (PyExc_RuntimeError,
410 _("Cannot set both task and thread attributes."));
411 return -1;
412 }
413 }
414 else if (newvalue == Py_None)
415 id = -1;
416 else
417 {
418 PyErr_SetString (PyExc_TypeError,
419 _("The value of `task' must be an integer or None."));
420 return -1;
421 }
422
423 breakpoint_set_task (self_bp->bp, id);
424
425 return 0;
426 }
427
428 /* Python function which deletes the underlying GDB breakpoint. This
429 triggers the breakpoint_deleted observer which will call
430 gdbpy_breakpoint_deleted; that function cleans up the Python
431 sections. */
432
433 static PyObject *
434 bppy_delete_breakpoint (PyObject *self, PyObject *args)
435 {
436 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
437
438 BPPY_REQUIRE_VALID (self_bp);
439
440 try
441 {
442 delete_breakpoint (self_bp->bp);
443 }
444 catch (const gdb_exception &except)
445 {
446 GDB_PY_HANDLE_EXCEPTION (except);
447 }
448
449 Py_RETURN_NONE;
450 }
451
452
453 /* Python function to set the ignore count of a breakpoint. */
454 static int
455 bppy_set_ignore_count (PyObject *self, PyObject *newvalue, void *closure)
456 {
457 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
458 long value;
459
460 BPPY_SET_REQUIRE_VALID (self_bp);
461
462 if (newvalue == NULL)
463 {
464 PyErr_SetString (PyExc_TypeError,
465 _("Cannot delete `ignore_count' attribute."));
466 return -1;
467 }
468 else if (!PyLong_Check (newvalue))
469 {
470 PyErr_SetString (PyExc_TypeError,
471 _("The value of `ignore_count' must be an integer."));
472 return -1;
473 }
474
475 if (! gdb_py_int_as_long (newvalue, &value))
476 return -1;
477
478 if (value < 0)
479 value = 0;
480
481 try
482 {
483 set_ignore_count (self_bp->number, (int) value, 0);
484 }
485 catch (const gdb_exception &except)
486 {
487 GDB_PY_SET_HANDLE_EXCEPTION (except);
488 }
489
490 return 0;
491 }
492
493 /* Python function to set the hit count of a breakpoint. */
494 static int
495 bppy_set_hit_count (PyObject *self, PyObject *newvalue, void *closure)
496 {
497 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
498
499 BPPY_SET_REQUIRE_VALID (self_bp);
500
501 if (newvalue == NULL)
502 {
503 PyErr_SetString (PyExc_TypeError,
504 _("Cannot delete `hit_count' attribute."));
505 return -1;
506 }
507 else
508 {
509 long value;
510
511 if (! gdb_py_int_as_long (newvalue, &value))
512 return -1;
513
514 if (value != 0)
515 {
516 PyErr_SetString (PyExc_AttributeError,
517 _("The value of `hit_count' must be zero."));
518 return -1;
519 }
520 }
521
522 self_bp->bp->hit_count = 0;
523
524 return 0;
525 }
526
527 /* Python function to get the location of a breakpoint. */
528 static PyObject *
529 bppy_get_location (PyObject *self, void *closure)
530 {
531 gdbpy_breakpoint_object *obj = (gdbpy_breakpoint_object *) self;
532
533 BPPY_REQUIRE_VALID (obj);
534
535 if (obj->bp->type != bp_breakpoint
536 && obj->bp->type != bp_hardware_breakpoint)
537 Py_RETURN_NONE;
538
539 const char *str = obj->bp->locspec->to_string ();
540 if (str == nullptr)
541 str = "";
542 return host_string_to_python_string (str).release ();
543 }
544
545 /* Python function to get the breakpoint expression. */
546 static PyObject *
547 bppy_get_expression (PyObject *self, void *closure)
548 {
549 const char *str;
550 gdbpy_breakpoint_object *obj = (gdbpy_breakpoint_object *) self;
551
552 BPPY_REQUIRE_VALID (obj);
553
554 if (!is_watchpoint (obj->bp))
555 Py_RETURN_NONE;
556
557 watchpoint *wp = gdb::checked_static_cast<watchpoint *> (obj->bp);
558
559 str = wp->exp_string.get ();
560 if (! str)
561 str = "";
562
563 return host_string_to_python_string (str).release ();
564 }
565
566 /* Python function to get the condition expression of a breakpoint. */
567 static PyObject *
568 bppy_get_condition (PyObject *self, void *closure)
569 {
570 char *str;
571 gdbpy_breakpoint_object *obj = (gdbpy_breakpoint_object *) self;
572
573 BPPY_REQUIRE_VALID (obj);
574
575 str = obj->bp->cond_string.get ();
576 if (! str)
577 Py_RETURN_NONE;
578
579 return host_string_to_python_string (str).release ();
580 }
581
582 /* Returns 0 on success. Returns -1 on error, with a python exception set.
583 */
584
585 static int
586 bppy_set_condition (PyObject *self, PyObject *newvalue, void *closure)
587 {
588 gdb::unique_xmalloc_ptr<char> exp_holder;
589 const char *exp = NULL;
590 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
591
592 BPPY_SET_REQUIRE_VALID (self_bp);
593
594 if (newvalue == NULL)
595 {
596 PyErr_SetString (PyExc_TypeError,
597 _("Cannot delete `condition' attribute."));
598 return -1;
599 }
600 else if (newvalue == Py_None)
601 exp = "";
602 else
603 {
604 exp_holder = python_string_to_host_string (newvalue);
605 if (exp_holder == NULL)
606 return -1;
607 exp = exp_holder.get ();
608 }
609
610 try
611 {
612 set_breakpoint_condition (self_bp->bp, exp, 0, false);
613 }
614 catch (gdb_exception &ex)
615 {
616 GDB_PY_SET_HANDLE_EXCEPTION (ex);
617 }
618
619 return 0;
620 }
621
622 /* Python function to get the commands attached to a breakpoint. */
623 static PyObject *
624 bppy_get_commands (PyObject *self, void *closure)
625 {
626 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
627 struct breakpoint *bp = self_bp->bp;
628
629 BPPY_REQUIRE_VALID (self_bp);
630
631 if (! self_bp->bp->commands)
632 Py_RETURN_NONE;
633
634 string_file stb;
635
636 try
637 {
638 ui_out_redirect_pop redir (current_uiout, &stb);
639 print_command_lines (current_uiout, breakpoint_commands (bp), 0);
640 }
641 catch (const gdb_exception &except)
642 {
643 gdbpy_convert_exception (except);
644 return NULL;
645 }
646
647 return host_string_to_python_string (stb.c_str ()).release ();
648 }
649
650 /* Set the commands attached to a breakpoint. Returns 0 on success.
651 Returns -1 on error, with a python exception set. */
652 static int
653 bppy_set_commands (PyObject *self, PyObject *newvalue, void *closure)
654 {
655 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
656
657 BPPY_SET_REQUIRE_VALID (self_bp);
658
659 gdb::unique_xmalloc_ptr<char> commands
660 (python_string_to_host_string (newvalue));
661 if (commands == nullptr)
662 return -1;
663
664 try
665 {
666 bool first = true;
667 char *save_ptr = nullptr;
668 auto reader
669 = [&] (std::string &buffer)
670 {
671 const char *result = strtok_r (first ? commands.get () : nullptr,
672 "\n", &save_ptr);
673 first = false;
674 return result;
675 };
676
677 counted_command_line lines = read_command_lines_1 (reader, 1, nullptr);
678 breakpoint_set_commands (self_bp->bp, std::move (lines));
679 }
680 catch (gdb_exception &ex)
681 {
682 GDB_PY_SET_HANDLE_EXCEPTION (ex);
683 }
684
685 return 0;
686 }
687
688 /* Python function to get the breakpoint type. */
689 static PyObject *
690 bppy_get_type (PyObject *self, void *closure)
691 {
692 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
693
694 BPPY_REQUIRE_VALID (self_bp);
695
696 return gdb_py_object_from_longest (self_bp->bp->type).release ();
697 }
698
699 /* Python function to get the visibility of the breakpoint. */
700
701 static PyObject *
702 bppy_get_visibility (PyObject *self, void *closure)
703 {
704 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
705
706 BPPY_REQUIRE_VALID (self_bp);
707
708 if (user_breakpoint_p (self_bp->bp))
709 Py_RETURN_TRUE;
710
711 Py_RETURN_FALSE;
712 }
713
714 /* Python function to determine if the breakpoint is a temporary
715 breakpoint. */
716
717 static PyObject *
718 bppy_get_temporary (PyObject *self, void *closure)
719 {
720 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
721
722 BPPY_REQUIRE_VALID (self_bp);
723
724 if (self_bp->bp->disposition == disp_del
725 || self_bp->bp->disposition == disp_del_at_next_stop)
726 Py_RETURN_TRUE;
727
728 Py_RETURN_FALSE;
729 }
730
731 /* Python function to determine if the breakpoint is a pending
732 breakpoint. */
733
734 static PyObject *
735 bppy_get_pending (PyObject *self, void *closure)
736 {
737 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
738
739 BPPY_REQUIRE_VALID (self_bp);
740
741 if (is_watchpoint (self_bp->bp))
742 Py_RETURN_FALSE;
743 if (pending_breakpoint_p (self_bp->bp))
744 Py_RETURN_TRUE;
745
746 Py_RETURN_FALSE;
747 }
748
749 /* Python function to get the breakpoint's number. */
750 static PyObject *
751 bppy_get_number (PyObject *self, void *closure)
752 {
753 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
754
755 BPPY_REQUIRE_VALID (self_bp);
756
757 return gdb_py_object_from_longest (self_bp->number).release ();
758 }
759
760 /* Python function to get the breakpoint's thread ID. */
761 static PyObject *
762 bppy_get_thread (PyObject *self, void *closure)
763 {
764 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
765
766 BPPY_REQUIRE_VALID (self_bp);
767
768 if (self_bp->bp->thread == -1)
769 Py_RETURN_NONE;
770
771 return gdb_py_object_from_longest (self_bp->bp->thread).release ();
772 }
773
774 /* Python function to get the breakpoint's inferior ID. */
775 static PyObject *
776 bppy_get_inferior (PyObject *self, void *closure)
777 {
778 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
779
780 BPPY_REQUIRE_VALID (self_bp);
781
782 if (self_bp->bp->inferior == -1)
783 Py_RETURN_NONE;
784
785 return gdb_py_object_from_longest (self_bp->bp->inferior).release ();
786 }
787
788 /* Python function to get the breakpoint's task ID (in Ada). */
789 static PyObject *
790 bppy_get_task (PyObject *self, void *closure)
791 {
792 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
793
794 BPPY_REQUIRE_VALID (self_bp);
795
796 if (self_bp->bp->task == -1)
797 Py_RETURN_NONE;
798
799 return gdb_py_object_from_longest (self_bp->bp->task).release ();
800 }
801
802 /* Python function to get the breakpoint's hit count. */
803 static PyObject *
804 bppy_get_hit_count (PyObject *self, void *closure)
805 {
806 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
807
808 BPPY_REQUIRE_VALID (self_bp);
809
810 return gdb_py_object_from_longest (self_bp->bp->hit_count).release ();
811 }
812
813 /* Python function to get the breakpoint's ignore count. */
814 static PyObject *
815 bppy_get_ignore_count (PyObject *self, void *closure)
816 {
817 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
818
819 BPPY_REQUIRE_VALID (self_bp);
820
821 return gdb_py_object_from_longest (self_bp->bp->ignore_count).release ();
822 }
823
824 /* Python function to get the breakpoint locations of an owner breakpoint. */
825
826 static PyObject *
827 bppy_get_locations (PyObject *self, void *closure)
828 {
829 using py_bploc_t = gdbpy_breakpoint_location_object;
830 auto *self_bp = (gdbpy_breakpoint_object *) self;
831 BPPY_REQUIRE_VALID (self_bp);
832
833 gdbpy_ref<> list (PyList_New (0));
834 if (list == nullptr)
835 return nullptr;
836
837 for (bp_location &loc : self_bp->bp->locations ())
838 {
839 gdbpy_ref<py_bploc_t> py_bploc
840 (PyObject_New (py_bploc_t, &breakpoint_location_object_type));
841 if (py_bploc == nullptr)
842 return nullptr;
843
844 bp_location_ref_ptr ref = bp_location_ref_ptr::new_reference (&loc);
845 /* The location takes a reference to the owner breakpoint.
846 Decrements when they are de-allocated in bplocpy_dealloc */
847 Py_INCREF (self);
848 py_bploc->owner = self_bp;
849 py_bploc->bp_loc = ref.release ();
850 if (PyList_Append (list.get (), (PyObject *) py_bploc.get ()) != 0)
851 return nullptr;
852 }
853 return list.release ();
854 }
855
856 /* Internal function to validate the Python parameters/keywords
857 provided to bppy_init. */
858
859 static int
860 bppy_init_validate_args (const char *spec, char *source,
861 char *function, char *label,
862 char *line, enum bptype type)
863 {
864 /* If spec is defined, ensure that none of the explicit location
865 keywords are also defined. */
866 if (spec != NULL)
867 {
868 if (source != NULL || function != NULL || label != NULL || line != NULL)
869 {
870 PyErr_SetString (PyExc_RuntimeError,
871 _("Breakpoints specified with spec cannot "
872 "have source, function, label or line defined."));
873 return -1;
874 }
875 }
876 else
877 {
878 /* If spec isn't defined, ensure that the user is not trying to
879 define a watchpoint with an explicit location. */
880 if (type == bp_watchpoint)
881 {
882 PyErr_SetString (PyExc_RuntimeError,
883 _("Watchpoints cannot be set by explicit "
884 "location parameters."));
885 return -1;
886 }
887 else
888 {
889 /* Otherwise, ensure some explicit locations are defined. */
890 if (source == NULL && function == NULL && label == NULL
891 && line == NULL)
892 {
893 PyErr_SetString (PyExc_RuntimeError,
894 _("Neither spec nor explicit location set."));
895 return -1;
896 }
897 /* Finally, if source is specified, ensure that line, label
898 or function are specified too. */
899 if (source != NULL && function == NULL && label == NULL
900 && line == NULL)
901 {
902 PyErr_SetString (PyExc_RuntimeError,
903 _("Specifying a source must also include a "
904 "line, label or function."));
905 return -1;
906 }
907 }
908 }
909 return 1;
910 }
911
912 /* Python function to create a new breakpoint. */
913 static int
914 bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
915 {
916 static const char *keywords[] = { "spec", "type", "wp_class", "internal",
917 "temporary","source", "function",
918 "label", "line", "qualified", NULL };
919 const char *spec = NULL;
920 enum bptype type = bp_breakpoint;
921 int access_type = hw_write;
922 PyObject *internal = NULL;
923 PyObject *temporary = NULL;
924 PyObject *lineobj = NULL;;
925 int internal_bp = 0;
926 int temporary_bp = 0;
927 gdb::unique_xmalloc_ptr<char> line;
928 char *label = NULL;
929 char *source = NULL;
930 char *function = NULL;
931 PyObject * qualified = NULL;
932
933 if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "|siiOOsssOO", keywords,
934 &spec, &type, &access_type,
935 &internal,
936 &temporary, &source,
937 &function, &label, &lineobj,
938 &qualified))
939 return -1;
940
941
942 if (lineobj != NULL)
943 {
944 if (PyLong_Check (lineobj))
945 line = xstrprintf ("%ld", PyLong_AsLong (lineobj));
946 else if (PyUnicode_Check (lineobj))
947 line = python_string_to_host_string (lineobj);
948 else
949 {
950 PyErr_SetString (PyExc_RuntimeError,
951 _("Line keyword should be an integer or a string. "));
952 return -1;
953 }
954 }
955
956 if (internal)
957 {
958 internal_bp = PyObject_IsTrue (internal);
959 if (internal_bp == -1)
960 return -1;
961 }
962
963 if (temporary != NULL)
964 {
965 temporary_bp = PyObject_IsTrue (temporary);
966 if (temporary_bp == -1)
967 return -1;
968 }
969
970 if (bppy_init_validate_args (spec, source, function, label, line.get (),
971 type) == -1)
972 return -1;
973
974 bppy_pending_object = (gdbpy_breakpoint_object *) self;
975 bppy_pending_object->number = -1;
976 bppy_pending_object->bp = NULL;
977
978 try
979 {
980 switch (type)
981 {
982 case bp_breakpoint:
983 case bp_hardware_breakpoint:
984 {
985 location_spec_up locspec;
986 symbol_name_match_type func_name_match_type
987 = (qualified != NULL && PyObject_IsTrue (qualified)
988 ? symbol_name_match_type::FULL
989 : symbol_name_match_type::WILD);
990
991 if (spec != NULL)
992 {
993 gdb::unique_xmalloc_ptr<char>
994 copy_holder (xstrdup (skip_spaces (spec)));
995 const char *copy = copy_holder.get ();
996
997 locspec = string_to_location_spec (©,
998 current_language,
999 func_name_match_type);
1000 }
1001 else
1002 {
1003 std::unique_ptr<explicit_location_spec> explicit_loc
1004 (new explicit_location_spec ());
1005
1006 if (source != nullptr)
1007 explicit_loc->source_filename = make_unique_xstrdup (source);
1008 if (function != nullptr)
1009 explicit_loc->function_name = make_unique_xstrdup (function);
1010 if (label != nullptr)
1011 explicit_loc->label_name = make_unique_xstrdup (label);
1012
1013 if (line != NULL)
1014 explicit_loc->line_offset
1015 = linespec_parse_line_offset (line.get ());
1016
1017 explicit_loc->func_name_match_type = func_name_match_type;
1018
1019 locspec.reset (explicit_loc.release ());
1020 }
1021
1022 const struct breakpoint_ops *ops
1023 = breakpoint_ops_for_location_spec (locspec.get (), false);
1024
1025 create_breakpoint (gdbpy_enter::get_gdbarch (),
1026 locspec.get (), NULL, -1, -1, NULL, false,
1027 0,
1028 temporary_bp, type,
1029 0,
1030 AUTO_BOOLEAN_TRUE,
1031 ops,
1032 0, 1, internal_bp, 0);
1033 break;
1034 }
1035 case bp_watchpoint:
1036 {
1037 spec = skip_spaces (spec);
1038
1039 if (access_type == hw_write)
1040 watch_command_wrapper (spec, 0, internal_bp);
1041 else if (access_type == hw_access)
1042 awatch_command_wrapper (spec, 0, internal_bp);
1043 else if (access_type == hw_read)
1044 rwatch_command_wrapper (spec, 0, internal_bp);
1045 else
1046 error(_("Cannot understand watchpoint access type."));
1047 break;
1048 }
1049 case bp_catchpoint:
1050 error (_("BP_CATCHPOINT not supported"));
1051 default:
1052 error(_("Do not understand breakpoint type to set."));
1053 }
1054 }
1055 catch (const gdb_exception &except)
1056 {
1057 bppy_pending_object = NULL;
1058 gdbpy_convert_exception (except);
1059 return -1;
1060 }
1061
1062 BPPY_SET_REQUIRE_VALID ((gdbpy_breakpoint_object *) self);
1063 return 0;
1064 }
1065
1066 /* __repr__ implementation for gdb.Breakpoint. */
1067
1068 static PyObject *
1069 bppy_repr (PyObject *self)
1070 {
1071 const auto bp = (struct gdbpy_breakpoint_object*) self;
1072 if (bp->bp == nullptr)
1073 return PyUnicode_FromFormat ("<%s (invalid)>", Py_TYPE (self)->tp_name);
1074
1075 std::string str = " ";
1076 if (bp->bp->thread != -1)
1077 str += string_printf ("thread=%d ", bp->bp->thread);
1078 if (bp->bp->task > 0)
1079 str += string_printf ("task=%d ", bp->bp->task);
1080 if (bp->bp->enable_count > 0)
1081 str += string_printf ("enable_count=%d ", bp->bp->enable_count);
1082 str.pop_back ();
1083
1084 return PyUnicode_FromFormat ("<%s%s number=%d hits=%d%s>",
1085 Py_TYPE (self)->tp_name,
1086 (bp->bp->enable_state == bp_enabled
1087 ? "" : " disabled"), bp->bp->number,
1088 bp->bp->hit_count, str.c_str ());
1089 }
1090
1091 /* Append to LIST the breakpoint Python object associated to B.
1092
1093 Return true on success. Return false on failure, with the Python error
1094 indicator set. */
1095
1096 static bool
1097 build_bp_list (struct breakpoint *b, PyObject *list)
1098 {
1099 PyObject *bp = (PyObject *) b->py_bp_object;
1100
1101 /* Not all breakpoints will have a companion Python object.
1102 Only breakpoints that were created via bppy_new, or
1103 breakpoints that were created externally and are tracked by
1104 the Python Scripting API. */
1105 if (bp == nullptr)
1106 return true;
1107
1108 return PyList_Append (list, bp) == 0;
1109 }
1110
1111 /* See python-internal.h. */
1112
1113 bool
1114 gdbpy_breakpoint_init_breakpoint_type ()
1115 {
1116 if (breakpoint_object_type.tp_new == nullptr)
1117 {
1118 breakpoint_object_type.tp_new = PyType_GenericNew;
1119 if (PyType_Ready (&breakpoint_object_type) < 0)
1120 {
1121 /* Reset tp_new back to nullptr so future calls to this function
1122 will try calling PyType_Ready again. */
1123 breakpoint_object_type.tp_new = nullptr;
1124 return false;
1125 }
1126 }
1127
1128 return true;
1129 }
1130
1131 /* Static function to return a tuple holding all breakpoints. */
1132
1133 PyObject *
1134 gdbpy_breakpoints (PyObject *self, PyObject *args)
1135 {
1136 if (bppy_live == 0)
1137 return PyTuple_New (0);
1138
1139 gdbpy_ref<> list (PyList_New (0));
1140 if (list == NULL)
1141 return NULL;
1142
1143 /* If build_bp_list returns false, it signals an error condition. In that
1144 case abandon building the list and return nullptr. */
1145 for (breakpoint &bp : all_breakpoints ())
1146 if (!build_bp_list (&bp, list.get ()))
1147 return nullptr;
1148
1149 return PyList_AsTuple (list.get ());
1150 }
1151
1152 /* Call the "stop" method (if implemented) in the breakpoint
1153 class. If the method returns True, the inferior will be
1154 stopped at the breakpoint. Otherwise the inferior will be
1155 allowed to continue. */
1156
1157 enum ext_lang_bp_stop
1158 gdbpy_breakpoint_cond_says_stop (const struct extension_language_defn *extlang,
1159 struct breakpoint *b)
1160 {
1161 int stop;
1162 struct gdbpy_breakpoint_object *bp_obj = b->py_bp_object;
1163 PyObject *py_bp = (PyObject *) bp_obj;
1164
1165 if (bp_obj == NULL)
1166 return EXT_LANG_BP_STOP_UNSET;
1167
1168 stop = -1;
1169
1170 gdbpy_enter enter_py (b->gdbarch);
1171
1172 if (bp_obj->is_finish_bp)
1173 bpfinishpy_pre_stop_hook (bp_obj);
1174
1175 if (PyObject_HasAttrString (py_bp, stop_func))
1176 {
1177 gdbpy_ref<> result (PyObject_CallMethod (py_bp, stop_func, NULL));
1178
1179 stop = 1;
1180 if (result != NULL)
1181 {
1182 int evaluate = PyObject_IsTrue (result.get ());
1183
1184 if (evaluate == -1)
1185 gdbpy_print_stack ();
1186
1187 /* If the "stop" function returns False that means
1188 the Python breakpoint wants GDB to continue. */
1189 if (! evaluate)
1190 stop = 0;
1191 }
1192 else
1193 gdbpy_print_stack ();
1194 }
1195
1196 if (bp_obj->is_finish_bp)
1197 bpfinishpy_post_stop_hook (bp_obj);
1198
1199 if (stop < 0)
1200 return EXT_LANG_BP_STOP_UNSET;
1201 return stop ? EXT_LANG_BP_STOP_YES : EXT_LANG_BP_STOP_NO;
1202 }
1203
1204 /* Checks if the "stop" method exists in this breakpoint.
1205 Used by condition_command to ensure mutual exclusion of breakpoint
1206 conditions. */
1207
1208 int
1209 gdbpy_breakpoint_has_cond (const struct extension_language_defn *extlang,
1210 struct breakpoint *b)
1211 {
1212 PyObject *py_bp;
1213
1214 if (b->py_bp_object == NULL)
1215 return 0;
1216
1217 py_bp = (PyObject *) b->py_bp_object;
1218
1219 gdbpy_enter enter_py (b->gdbarch);
1220 return PyObject_HasAttrString (py_bp, stop_func);
1221 }
1222
1223
1224
1226 /* Event callback functions. */
1227
1228 /* Callback that is used when a breakpoint is created. This function
1229 will create a new Python breakpoint object. */
1230 static void
1231 gdbpy_breakpoint_created (struct breakpoint *bp)
1232 {
1233 PYBP_SCOPED_DEBUG_ENTER_EXIT;
1234
1235 gdbpy_breakpoint_object *newbp;
1236
1237 if (!user_breakpoint_p (bp) && bppy_pending_object == NULL)
1238 {
1239 pybp_debug_printf ("not attaching python object to this breakpoint");
1240 return;
1241 }
1242
1243 if (bp->type != bp_breakpoint
1244 && bp->type != bp_hardware_breakpoint
1245 && bp->type != bp_watchpoint
1246 && bp->type != bp_hardware_watchpoint
1247 && bp->type != bp_read_watchpoint
1248 && bp->type != bp_access_watchpoint
1249 && bp->type != bp_catchpoint)
1250 {
1251 pybp_debug_printf ("is not a breakpoint or watchpoint");
1252 return;
1253 }
1254
1255 gdbpy_enter enter_py (bp->gdbarch);
1256
1257 if (bppy_pending_object)
1258 {
1259 newbp = bppy_pending_object;
1260 Py_INCREF (newbp);
1261 bppy_pending_object = NULL;
1262 pybp_debug_printf ("attaching existing breakpoint object");
1263 }
1264 else
1265 {
1266 newbp = PyObject_New (gdbpy_breakpoint_object, &breakpoint_object_type);
1267 pybp_debug_printf ("attaching new breakpoint object");
1268 }
1269 if (newbp)
1270 {
1271 newbp->number = bp->number;
1272 newbp->bp = bp;
1273 newbp->bp->py_bp_object = newbp;
1274 newbp->is_finish_bp = 0;
1275 ++bppy_live;
1276 }
1277 else
1278 {
1279 PyErr_SetString (PyExc_RuntimeError,
1280 _("Error while creating breakpoint from GDB."));
1281 gdbpy_print_stack ();
1282 }
1283
1284 if (!evregpy_no_listeners_p (gdb_py_events.breakpoint_created))
1285 {
1286 if (evpy_emit_event ((PyObject *) newbp,
1287 gdb_py_events.breakpoint_created) < 0)
1288 gdbpy_print_stack ();
1289 }
1290 }
1291
1292 /* Callback that is used when a breakpoint is deleted. This will
1293 invalidate the corresponding Python object. */
1294 static void
1295 gdbpy_breakpoint_deleted (struct breakpoint *b)
1296 {
1297 PYBP_SCOPED_DEBUG_ENTER_EXIT;
1298
1299 int num = b->number;
1300 struct breakpoint *bp = NULL;
1301
1302 bp = get_breakpoint (num);
1303 if (bp)
1304 {
1305 gdbpy_enter enter_py (b->gdbarch);
1306
1307 gdbpy_ref<gdbpy_breakpoint_object> bp_obj (bp->py_bp_object);
1308 if (bp_obj != NULL)
1309 {
1310 if (bp_obj->is_finish_bp)
1311 bpfinishpy_pre_delete_hook (bp_obj.get ());
1312
1313 if (!evregpy_no_listeners_p (gdb_py_events.breakpoint_deleted))
1314 {
1315 if (evpy_emit_event ((PyObject *) bp_obj.get (),
1316 gdb_py_events.breakpoint_deleted) < 0)
1317 gdbpy_print_stack ();
1318 }
1319
1320 bp_obj->bp = NULL;
1321 --bppy_live;
1322 }
1323 }
1324 }
1325
1326 /* Callback that is used when a breakpoint is modified. */
1327
1328 static void
1329 gdbpy_breakpoint_modified (struct breakpoint *b)
1330 {
1331 PYBP_SCOPED_DEBUG_ENTER_EXIT;
1332
1333 int num = b->number;
1334 struct breakpoint *bp = NULL;
1335
1336 bp = get_breakpoint (num);
1337 if (bp)
1338 {
1339 gdbpy_enter enter_py (b->gdbarch);
1340
1341 PyObject *bp_obj = (PyObject *) bp->py_bp_object;
1342 if (bp_obj)
1343 {
1344 if (!evregpy_no_listeners_p (gdb_py_events.breakpoint_modified))
1345 {
1346 if (evpy_emit_event (bp_obj,
1347 gdb_py_events.breakpoint_modified) < 0)
1348 gdbpy_print_stack ();
1349 }
1350 }
1351 }
1352 }
1353
1354
1355
1357 /* Initialize the Python breakpoint code. */
1358 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
1359 gdbpy_initialize_breakpoints (void)
1360 {
1361 int i;
1362
1363 if (!gdbpy_breakpoint_init_breakpoint_type ())
1364 return -1;
1365
1366 if (gdb_pymodule_addobject (gdb_module, "Breakpoint",
1367 (PyObject *) &breakpoint_object_type) < 0)
1368 return -1;
1369
1370 gdb::observers::breakpoint_created.attach (gdbpy_breakpoint_created,
1371 "py-breakpoint");
1372 gdb::observers::breakpoint_deleted.attach (gdbpy_breakpoint_deleted,
1373 "py-breakpoint");
1374 gdb::observers::breakpoint_modified.attach (gdbpy_breakpoint_modified,
1375 "py-breakpoint");
1376
1377 /* Add breakpoint types constants. */
1378 for (i = 0; pybp_codes[i].name; ++i)
1379 {
1380 if (PyModule_AddIntConstant (gdb_module, pybp_codes[i].name,
1381 pybp_codes[i].code) < 0)
1382 return -1;
1383 }
1384
1385 /* Add watchpoint types constants. */
1386 for (i = 0; pybp_watch_types[i].name; ++i)
1387 {
1388 if (PyModule_AddIntConstant (gdb_module, pybp_watch_types[i].name,
1389 pybp_watch_types[i].code) < 0)
1390 return -1;
1391 }
1392
1393 return 0;
1394 }
1395
1396 /* Initialize the Python BreakpointLocation code. */
1397
1398 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
1399 gdbpy_initialize_breakpoint_locations ()
1400 {
1401 if (PyType_Ready (&breakpoint_location_object_type) < 0)
1402 return -1;
1403
1404 if (gdb_pymodule_addobject (gdb_module, "BreakpointLocation",
1405 (PyObject *) &breakpoint_location_object_type)
1406 < 0)
1407 return -1;
1408 return 0;
1409 }
1410
1411
1412
1414 /* Helper function that overrides this Python object's
1415 PyObject_GenericSetAttr to allow extra validation of the attribute
1416 being set. */
1417
1418 static int
1419 local_setattro (PyObject *self, PyObject *name, PyObject *v)
1420 {
1421 gdbpy_breakpoint_object *obj = (gdbpy_breakpoint_object *) self;
1422 gdb::unique_xmalloc_ptr<char> attr (python_string_to_host_string (name));
1423
1424 if (attr == NULL)
1425 return -1;
1426
1427 /* If the attribute trying to be set is the "stop" method,
1428 but we already have a condition set in the CLI or other extension
1429 language, disallow this operation. */
1430 if (strcmp (attr.get (), stop_func) == 0)
1431 {
1432 const struct extension_language_defn *extlang = NULL;
1433
1434 if (obj->bp->cond_string != NULL)
1435 extlang = get_ext_lang_defn (EXT_LANG_GDB);
1436 if (extlang == NULL)
1437 extlang = get_breakpoint_cond_ext_lang (obj->bp, EXT_LANG_PYTHON);
1438 if (extlang != NULL)
1439 {
1440 std::string error_text
1441 = string_printf (_("Only one stop condition allowed. There is"
1442 " currently a %s stop condition defined for"
1443 " this breakpoint."),
1444 ext_lang_capitalized_name (extlang));
1445 PyErr_SetString (PyExc_RuntimeError, error_text.c_str ());
1446 return -1;
1447 }
1448 }
1449
1450 return PyObject_GenericSetAttr (self, name, v);
1451 }
1452
1453 static gdb_PyGetSetDef breakpoint_object_getset[] = {
1454 { "enabled", bppy_get_enabled, bppy_set_enabled,
1455 "Boolean telling whether the breakpoint is enabled.", NULL },
1456 { "silent", bppy_get_silent, bppy_set_silent,
1457 "Boolean telling whether the breakpoint is silent.", NULL },
1458 { "thread", bppy_get_thread, bppy_set_thread,
1459 "Thread ID for the breakpoint.\n\
1460 If the value is a thread ID (integer), then this is a thread-specific breakpoint.\n\
1461 If the value is None, then this breakpoint is not thread-specific.\n\
1462 No other type of value can be used.", NULL },
1463 { "inferior", bppy_get_inferior, bppy_set_inferior,
1464 "Inferior ID for the breakpoint.\n\
1465 If the value is an inferior ID (integer), then this is an inferior-specific\n\
1466 breakpoint. If the value is None, then this breakpoint is not\n\
1467 inferior-specific. No other type of value can be used.", NULL },
1468 { "task", bppy_get_task, bppy_set_task,
1469 "Thread ID for the breakpoint.\n\
1470 If the value is a task ID (integer), then this is an Ada task-specific breakpoint.\n\
1471 If the value is None, then this breakpoint is not task-specific.\n\
1472 No other type of value can be used.", NULL },
1473 { "ignore_count", bppy_get_ignore_count, bppy_set_ignore_count,
1474 "Number of times this breakpoint should be automatically continued.",
1475 NULL },
1476 { "number", bppy_get_number, NULL,
1477 "Breakpoint's number assigned by GDB.", NULL },
1478 { "hit_count", bppy_get_hit_count, bppy_set_hit_count,
1479 "Number of times the breakpoint has been hit.\n\
1480 Can be set to zero to clear the count. No other value is valid\n\
1481 when setting this property.", NULL },
1482 { "location", bppy_get_location, NULL,
1483 "Location of the breakpoint, as specified by the user.", NULL},
1484 { "expression", bppy_get_expression, NULL,
1485 "Expression of the breakpoint, as specified by the user.", NULL},
1486 { "condition", bppy_get_condition, bppy_set_condition,
1487 "Condition of the breakpoint, as specified by the user,\
1488 or None if no condition set."},
1489 { "commands", bppy_get_commands, bppy_set_commands,
1490 "Commands of the breakpoint, as specified by the user."},
1491 { "type", bppy_get_type, NULL,
1492 "Type of breakpoint."},
1493 { "visible", bppy_get_visibility, NULL,
1494 "Whether the breakpoint is visible to the user."},
1495 { "temporary", bppy_get_temporary, NULL,
1496 "Whether this breakpoint is a temporary breakpoint."},
1497 { "pending", bppy_get_pending, NULL,
1498 "Whether this breakpoint is a pending breakpoint."},
1499 { "locations", bppy_get_locations, NULL,
1500 "Get locations where this breakpoint was set"},
1501 { NULL } /* Sentinel. */
1502 };
1503
1504 static PyMethodDef breakpoint_object_methods[] =
1505 {
1506 { "is_valid", bppy_is_valid, METH_NOARGS,
1507 "Return true if this breakpoint is valid, false if not." },
1508 { "delete", bppy_delete_breakpoint, METH_NOARGS,
1509 "Delete the underlying GDB breakpoint." },
1510 { NULL } /* Sentinel. */
1511 };
1512
1513 PyTypeObject breakpoint_object_type =
1514 {
1515 PyVarObject_HEAD_INIT (NULL, 0)
1516 "gdb.Breakpoint", /*tp_name*/
1517 sizeof (gdbpy_breakpoint_object), /*tp_basicsize*/
1518 0, /*tp_itemsize*/
1519 0, /*tp_dealloc*/
1520 0, /*tp_print*/
1521 0, /*tp_getattr*/
1522 0, /*tp_setattr*/
1523 0, /*tp_compare*/
1524 bppy_repr, /*tp_repr*/
1525 0, /*tp_as_number*/
1526 0, /*tp_as_sequence*/
1527 0, /*tp_as_mapping*/
1528 0, /*tp_hash */
1529 0, /*tp_call*/
1530 0, /*tp_str*/
1531 0, /*tp_getattro*/
1532 (setattrofunc)local_setattro, /*tp_setattro */
1533 0, /*tp_as_buffer*/
1534 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1535 "GDB breakpoint object", /* tp_doc */
1536 0, /* tp_traverse */
1537 0, /* tp_clear */
1538 0, /* tp_richcompare */
1539 0, /* tp_weaklistoffset */
1540 0, /* tp_iter */
1541 0, /* tp_iternext */
1542 breakpoint_object_methods, /* tp_methods */
1543 0, /* tp_members */
1544 breakpoint_object_getset, /* tp_getset */
1545 0, /* tp_base */
1546 0, /* tp_dict */
1547 0, /* tp_descr_get */
1548 0, /* tp_descr_set */
1549 0, /* tp_dictoffset */
1550 bppy_init, /* tp_init */
1551 0, /* tp_alloc */
1552 };
1553
1554 void _initialize_py_breakpoint ();
1555 void
1556 _initialize_py_breakpoint ()
1557 {
1558 add_setshow_boolean_cmd
1559 ("py-breakpoint", class_maintenance, &pybp_debug,
1560 _("Set Python breakpoint debugging."),
1561 _("Show Python breakpoint debugging."),
1562 _("When on, Python breakpoint debugging is enabled."),
1563 NULL,
1564 show_pybp_debug,
1565 &setdebuglist, &showdebuglist);
1566 }
1567
1568 GDBPY_INITIALIZE_FILE (gdbpy_initialize_breakpoints);
1569 GDBPY_INITIALIZE_FILE (gdbpy_initialize_breakpoint_locations);
1570
1571 /* Python function to set the enabled state of a breakpoint location. */
1572
1573 static int
1574 bplocpy_set_enabled (PyObject *py_self, PyObject *newvalue, void *closure)
1575 {
1576 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1577 BPPY_SET_REQUIRE_VALID (self->owner);
1578 BPLOCPY_SET_REQUIRE_VALID (self->owner, self);
1579
1580 if (newvalue == nullptr)
1581 {
1582 PyErr_SetString (PyExc_TypeError,
1583 _("Cannot delete 'enabled' attribute."));
1584 return -1;
1585 }
1586 else if (!PyBool_Check (newvalue))
1587 {
1588 PyErr_SetString (PyExc_TypeError,
1589 _("The value of 'enabled' must be a boolean."));
1590 return -1;
1591 }
1592
1593 int cmp = PyObject_IsTrue (newvalue);
1594 if (cmp < 0)
1595 return -1;
1596
1597 try
1598 {
1599 enable_disable_bp_location (self->bp_loc, cmp == 1);
1600 }
1601 catch (const gdb_exception &except)
1602 {
1603 GDB_PY_SET_HANDLE_EXCEPTION (except);
1604 }
1605 return 0;
1606 }
1607
1608 /* Python function to test whether or not the breakpoint location is enabled. */
1609
1610 static PyObject *
1611 bplocpy_get_enabled (PyObject *py_self, void *closure)
1612 {
1613 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1614 BPPY_REQUIRE_VALID (self->owner);
1615 BPLOCPY_REQUIRE_VALID (self->owner, self);
1616
1617 if (self->bp_loc->enabled)
1618 Py_RETURN_TRUE;
1619 else
1620 Py_RETURN_FALSE;
1621 }
1622
1623 /* Python function to get address of breakpoint location. */
1624
1625 static PyObject *
1626 bplocpy_get_address (PyObject *py_self, void *closure)
1627 {
1628 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1629 BPPY_REQUIRE_VALID (self->owner);
1630 BPLOCPY_REQUIRE_VALID (self->owner, self);
1631 return gdb_py_object_from_ulongest (self->bp_loc->address).release ();
1632 }
1633
1634 /* Python function to get owner of breakpoint location, which
1635 is of type gdb.Breakpoint. */
1636
1637 static PyObject *
1638 bplocpy_get_owner (PyObject *py_self, void *closure)
1639 {
1640 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1641 BPPY_REQUIRE_VALID (self->owner);
1642 BPLOCPY_REQUIRE_VALID (self->owner, self);
1643 Py_INCREF (self->owner);
1644 return (PyObject *) self->owner;
1645 }
1646
1647 /* Python function to get the source file name path and line number
1648 where this breakpoint location was set. */
1649
1650 static PyObject *
1651 bplocpy_get_source_location (PyObject *py_self, void *closure)
1652 {
1653 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1654 BPPY_REQUIRE_VALID (self->owner);
1655 BPLOCPY_REQUIRE_VALID (self->owner, self);
1656 if (self->bp_loc->symtab)
1657 {
1658 gdbpy_ref<> tup (PyTuple_New (2));
1659 if (tup == nullptr)
1660 return nullptr;
1661 /* symtab->filename is never NULL. */
1662 gdbpy_ref<> filename
1663 = host_string_to_python_string (self->bp_loc->symtab->filename);
1664 if (filename == nullptr)
1665 return nullptr;
1666 auto line = gdb_py_object_from_ulongest (self->bp_loc->line_number);
1667 if (line == nullptr)
1668 return nullptr;
1669 if (PyTuple_SetItem (tup.get (), 0, filename.release ()) == -1
1670 || PyTuple_SetItem (tup.get (), 1, line.release ()) == -1)
1671 return nullptr;
1672 return tup.release ();
1673 }
1674 else
1675 Py_RETURN_NONE;
1676 }
1677
1678 /* Python function to get the function name of where this location was set. */
1679
1680 static PyObject *
1681 bplocpy_get_function (PyObject *py_self, void *closure)
1682 {
1683 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1684 BPPY_REQUIRE_VALID (self->owner);
1685 BPLOCPY_REQUIRE_VALID (self->owner, self);
1686 const auto fn_name = self->bp_loc->function_name.get ();
1687 if (fn_name != nullptr)
1688 return host_string_to_python_string (fn_name).release ();
1689 Py_RETURN_NONE;
1690 }
1691
1692 static PyObject *
1693 bplocpy_get_thread_groups (PyObject *py_self, void *closure)
1694 {
1695 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1696 BPPY_REQUIRE_VALID (self->owner);
1697 BPLOCPY_REQUIRE_VALID (self->owner, self);
1698 gdbpy_ref<> list (PyList_New (0));
1699 if (list == nullptr)
1700 return nullptr;
1701 for (inferior *inf : all_inferiors ())
1702 {
1703 if (inf->pspace == self->bp_loc->pspace)
1704 {
1705 gdbpy_ref<> num = gdb_py_object_from_ulongest (inf->num);
1706 if (num == nullptr)
1707 return nullptr;
1708 if (PyList_Append (list.get (), num.release ()) != 0)
1709 return nullptr;
1710 }
1711 }
1712 return list.release ();
1713 }
1714
1715 static PyObject *
1716 bplocpy_get_fullname (PyObject *py_self, void *closure)
1717 {
1718 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1719 BPPY_REQUIRE_VALID (self->owner);
1720 BPLOCPY_REQUIRE_VALID (self->owner, self);
1721 const auto symtab = self->bp_loc->symtab;
1722 if (symtab != nullptr && symtab->fullname != nullptr)
1723 {
1724 gdbpy_ref<> fullname
1725 = host_string_to_python_string (symtab->fullname);
1726 return fullname.release ();
1727 }
1728 Py_RETURN_NONE;
1729 }
1730
1731 /* De-allocation function to be called for the Python object. */
1732
1733 static void
1734 bplocpy_dealloc (PyObject *py_self)
1735 {
1736 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1737 bp_location_ref_ptr decrementing_ref {self->bp_loc};
1738 Py_XDECREF (self->owner);
1739 Py_TYPE (py_self)->tp_free (py_self);
1740 }
1741
1742 /* __repr__ implementation for gdb.BreakpointLocation. */
1743
1744 static PyObject *
1745 bplocpy_repr (PyObject *py_self)
1746 {
1747 const auto self = (gdbpy_breakpoint_location_object *) py_self;
1748 if (self->owner == nullptr || self->owner->bp == nullptr
1749 || self->owner->bp != self->bp_loc->owner)
1750 return gdb_py_invalid_object_repr (py_self);
1751
1752 const auto enabled = self->bp_loc->enabled ? "enabled" : "disabled";
1753
1754 std::string str (enabled);
1755
1756 str += string_printf (" address=%s",
1757 paddress (self->bp_loc->owner->gdbarch,
1758 self->bp_loc->address));
1759
1760 if (self->bp_loc->requested_address != self->bp_loc->address)
1761 str += string_printf (" requested_address=%s",
1762 paddress (self->bp_loc->owner->gdbarch,
1763 self->bp_loc->requested_address));
1764 if (self->bp_loc->symtab != nullptr)
1765 str += string_printf (" source=%s:%d", self->bp_loc->symtab->filename,
1766 self->bp_loc->line_number);
1767
1768 const auto fn_name = self->bp_loc->function_name.get ();
1769 if (fn_name != nullptr)
1770 {
1771 str += " in ";
1772 str += fn_name;
1773 }
1774
1775 return PyUnicode_FromFormat ("<%s %s>", Py_TYPE (self)->tp_name,
1776 str.c_str ());
1777 }
1778
1779 /* Attribute get/set Python definitions. */
1780
1781 static gdb_PyGetSetDef bp_location_object_getset[] = {
1782 { "enabled", bplocpy_get_enabled, bplocpy_set_enabled,
1783 "Boolean telling whether the breakpoint is enabled.", NULL },
1784 { "owner", bplocpy_get_owner, NULL,
1785 "Get the breakpoint owner object", NULL },
1786 { "address", bplocpy_get_address, NULL,
1787 "Get address of where this location was set", NULL},
1788 { "source", bplocpy_get_source_location, NULL,
1789 "Get file and line number of where this location was set", NULL},
1790 { "function", bplocpy_get_function, NULL,
1791 "Get function of where this location was set", NULL },
1792 { "fullname", bplocpy_get_fullname, NULL,
1793 "Get fullname of where this location was set", NULL },
1794 { "thread_groups", bplocpy_get_thread_groups, NULL,
1795 "Get thread groups where this location is in", NULL },
1796 { NULL } /* Sentinel. */
1797 };
1798
1799 PyTypeObject breakpoint_location_object_type =
1800 {
1801 PyVarObject_HEAD_INIT (NULL, 0)
1802 "gdb.BreakpointLocation", /*tp_name*/
1803 sizeof (gdbpy_breakpoint_location_object), /*tp_basicsize*/
1804 0, /*tp_itemsize*/
1805 bplocpy_dealloc, /*tp_dealloc*/
1806 0, /*tp_print*/
1807 0, /*tp_getattr*/
1808 0, /*tp_setattr*/
1809 0, /*tp_compare*/
1810 bplocpy_repr, /*tp_repr*/
1811 0, /*tp_as_number*/
1812 0, /*tp_as_sequence*/
1813 0, /*tp_as_mapping*/
1814 0, /*tp_hash */
1815 0, /*tp_call*/
1816 0, /*tp_str*/
1817 0, /*tp_getattro*/
1818 0, /*tp_setattro */
1819 0, /*tp_as_buffer*/
1820 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1821 "GDB breakpoint location object", /* tp_doc */
1822 0, /* tp_traverse */
1823 0, /* tp_clear */
1824 0, /* tp_richcompare */
1825 0, /* tp_weaklistoffset */
1826 0, /* tp_iter */
1827 0, /* tp_iternext */
1828 0, /* tp_methods */
1829 0, /* tp_members */
1830 bp_location_object_getset, /* tp_getset */
1831 0, /* tp_base */
1832 0, /* tp_dict */
1833 0, /* tp_descr_get */
1834 0, /* tp_descr_set */
1835 0, /* tp_dictoffset */
1836 0, /* tp_init */
1837 0, /* tp_alloc */
1838 };
1839