py-breakpoint.c revision 1.1.1.10 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 return gdbpy_handle_gdb_exception (-1, 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 return gdbpy_handle_gdb_exception (-1, 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 return gdbpy_handle_gdb_exception (nullptr, 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 return gdbpy_handle_gdb_exception (-1, 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 (const gdb_exception &ex)
615 {
616 return gdbpy_handle_gdb_exception (-1, 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 return gdbpy_handle_gdb_exception (nullptr, except);
644 }
645
646 return host_string_to_python_string (stb.c_str ()).release ();
647 }
648
649 /* Set the commands attached to a breakpoint. Returns 0 on success.
650 Returns -1 on error, with a python exception set. */
651 static int
652 bppy_set_commands (PyObject *self, PyObject *newvalue, void *closure)
653 {
654 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
655
656 BPPY_SET_REQUIRE_VALID (self_bp);
657
658 gdb::unique_xmalloc_ptr<char> commands
659 (python_string_to_host_string (newvalue));
660 if (commands == nullptr)
661 return -1;
662
663 try
664 {
665 bool first = true;
666 char *save_ptr = nullptr;
667 auto reader
668 = [&] (std::string &buffer)
669 {
670 const char *result = strtok_r (first ? commands.get () : nullptr,
671 "\n", &save_ptr);
672 first = false;
673 return result;
674 };
675
676 counted_command_line lines = read_command_lines_1 (reader, 1, nullptr);
677 breakpoint_set_commands (self_bp->bp, std::move (lines));
678 }
679 catch (const gdb_exception &ex)
680 {
681 return gdbpy_handle_gdb_exception (-1, ex);
682 }
683
684 return 0;
685 }
686
687 /* Python function to get the breakpoint type. */
688 static PyObject *
689 bppy_get_type (PyObject *self, void *closure)
690 {
691 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
692
693 BPPY_REQUIRE_VALID (self_bp);
694
695 return gdb_py_object_from_longest (self_bp->bp->type).release ();
696 }
697
698 /* Python function to get the visibility of the breakpoint. */
699
700 static PyObject *
701 bppy_get_visibility (PyObject *self, void *closure)
702 {
703 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
704
705 BPPY_REQUIRE_VALID (self_bp);
706
707 if (user_breakpoint_p (self_bp->bp))
708 Py_RETURN_TRUE;
709
710 Py_RETURN_FALSE;
711 }
712
713 /* Python function to determine if the breakpoint is a temporary
714 breakpoint. */
715
716 static PyObject *
717 bppy_get_temporary (PyObject *self, void *closure)
718 {
719 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
720
721 BPPY_REQUIRE_VALID (self_bp);
722
723 if (self_bp->bp->disposition == disp_del
724 || self_bp->bp->disposition == disp_del_at_next_stop)
725 Py_RETURN_TRUE;
726
727 Py_RETURN_FALSE;
728 }
729
730 /* Python function to determine if the breakpoint is a pending
731 breakpoint. */
732
733 static PyObject *
734 bppy_get_pending (PyObject *self, void *closure)
735 {
736 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
737
738 BPPY_REQUIRE_VALID (self_bp);
739
740 if (is_watchpoint (self_bp->bp))
741 Py_RETURN_FALSE;
742 if (pending_breakpoint_p (self_bp->bp))
743 Py_RETURN_TRUE;
744
745 Py_RETURN_FALSE;
746 }
747
748 /* Python function to get the breakpoint's number. */
749 static PyObject *
750 bppy_get_number (PyObject *self, void *closure)
751 {
752 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
753
754 BPPY_REQUIRE_VALID (self_bp);
755
756 return gdb_py_object_from_longest (self_bp->number).release ();
757 }
758
759 /* Python function to get the breakpoint's thread ID. */
760 static PyObject *
761 bppy_get_thread (PyObject *self, void *closure)
762 {
763 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
764
765 BPPY_REQUIRE_VALID (self_bp);
766
767 if (self_bp->bp->thread == -1)
768 Py_RETURN_NONE;
769
770 return gdb_py_object_from_longest (self_bp->bp->thread).release ();
771 }
772
773 /* Python function to get the breakpoint's inferior ID. */
774 static PyObject *
775 bppy_get_inferior (PyObject *self, void *closure)
776 {
777 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
778
779 BPPY_REQUIRE_VALID (self_bp);
780
781 if (self_bp->bp->inferior == -1)
782 Py_RETURN_NONE;
783
784 return gdb_py_object_from_longest (self_bp->bp->inferior).release ();
785 }
786
787 /* Python function to get the breakpoint's task ID (in Ada). */
788 static PyObject *
789 bppy_get_task (PyObject *self, void *closure)
790 {
791 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
792
793 BPPY_REQUIRE_VALID (self_bp);
794
795 if (self_bp->bp->task == -1)
796 Py_RETURN_NONE;
797
798 return gdb_py_object_from_longest (self_bp->bp->task).release ();
799 }
800
801 /* Python function to get the breakpoint's hit count. */
802 static PyObject *
803 bppy_get_hit_count (PyObject *self, void *closure)
804 {
805 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
806
807 BPPY_REQUIRE_VALID (self_bp);
808
809 return gdb_py_object_from_longest (self_bp->bp->hit_count).release ();
810 }
811
812 /* Python function to get the breakpoint's ignore count. */
813 static PyObject *
814 bppy_get_ignore_count (PyObject *self, void *closure)
815 {
816 gdbpy_breakpoint_object *self_bp = (gdbpy_breakpoint_object *) self;
817
818 BPPY_REQUIRE_VALID (self_bp);
819
820 return gdb_py_object_from_longest (self_bp->bp->ignore_count).release ();
821 }
822
823 /* Python function to get the breakpoint locations of an owner breakpoint. */
824
825 static PyObject *
826 bppy_get_locations (PyObject *self, void *closure)
827 {
828 using py_bploc_t = gdbpy_breakpoint_location_object;
829 auto *self_bp = (gdbpy_breakpoint_object *) self;
830 BPPY_REQUIRE_VALID (self_bp);
831
832 gdbpy_ref<> list (PyList_New (0));
833 if (list == nullptr)
834 return nullptr;
835
836 for (bp_location &loc : self_bp->bp->locations ())
837 {
838 gdbpy_ref<py_bploc_t> py_bploc
839 (PyObject_New (py_bploc_t, &breakpoint_location_object_type));
840 if (py_bploc == nullptr)
841 return nullptr;
842
843 bp_location_ref_ptr ref = bp_location_ref_ptr::new_reference (&loc);
844 /* The location takes a reference to the owner breakpoint.
845 Decrements when they are de-allocated in bplocpy_dealloc */
846 Py_INCREF (self);
847 py_bploc->owner = self_bp;
848 py_bploc->bp_loc = ref.release ();
849 if (PyList_Append (list.get (), (PyObject *) py_bploc.get ()) != 0)
850 return nullptr;
851 }
852 return list.release ();
853 }
854
855 /* Internal function to validate the Python parameters/keywords
856 provided to bppy_init. */
857
858 static int
859 bppy_init_validate_args (const char *spec, char *source,
860 char *function, char *label,
861 char *line, enum bptype type)
862 {
863 /* If spec is defined, ensure that none of the explicit location
864 keywords are also defined. */
865 if (spec != NULL)
866 {
867 if (source != NULL || function != NULL || label != NULL || line != NULL)
868 {
869 PyErr_SetString (PyExc_RuntimeError,
870 _("Breakpoints specified with spec cannot "
871 "have source, function, label or line defined."));
872 return -1;
873 }
874 }
875 else
876 {
877 /* If spec isn't defined, ensure that the user is not trying to
878 define a watchpoint with an explicit location. */
879 if (type == bp_watchpoint)
880 {
881 PyErr_SetString (PyExc_RuntimeError,
882 _("Watchpoints cannot be set by explicit "
883 "location parameters."));
884 return -1;
885 }
886 else
887 {
888 /* Otherwise, ensure some explicit locations are defined. */
889 if (source == NULL && function == NULL && label == NULL
890 && line == NULL)
891 {
892 PyErr_SetString (PyExc_RuntimeError,
893 _("Neither spec nor explicit location set."));
894 return -1;
895 }
896 /* Finally, if source is specified, ensure that line, label
897 or function are specified too. */
898 if (source != NULL && function == NULL && label == NULL
899 && line == NULL)
900 {
901 PyErr_SetString (PyExc_RuntimeError,
902 _("Specifying a source must also include a "
903 "line, label or function."));
904 return -1;
905 }
906 }
907 }
908 return 1;
909 }
910
911 /* Python function to create a new breakpoint. */
912 static int
913 bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
914 {
915 static const char *keywords[] = { "spec", "type", "wp_class", "internal",
916 "temporary","source", "function",
917 "label", "line", "qualified", NULL };
918 const char *spec = NULL;
919 enum bptype type = bp_breakpoint;
920 int access_type = hw_write;
921 PyObject *internal = NULL;
922 PyObject *temporary = NULL;
923 PyObject *lineobj = NULL;;
924 int internal_bp = 0;
925 int temporary_bp = 0;
926 gdb::unique_xmalloc_ptr<char> line;
927 char *label = NULL;
928 char *source = NULL;
929 char *function = NULL;
930 PyObject *qualified = Py_False;
931
932 if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "|siiOOsssOO!", keywords,
933 &spec, &type, &access_type,
934 &internal,
935 &temporary, &source,
936 &function, &label, &lineobj,
937 &PyBool_Type, &qualified))
938 return -1;
939
940
941 if (lineobj != NULL)
942 {
943 if (PyLong_Check (lineobj))
944 line = xstrprintf ("%ld", PyLong_AsLong (lineobj));
945 else if (PyUnicode_Check (lineobj))
946 line = python_string_to_host_string (lineobj);
947 else
948 {
949 PyErr_SetString (PyExc_RuntimeError,
950 _("Line keyword should be an integer or a string. "));
951 return -1;
952 }
953 }
954
955 if (internal)
956 {
957 internal_bp = PyObject_IsTrue (internal);
958 if (internal_bp == -1)
959 return -1;
960 }
961
962 if (temporary != NULL)
963 {
964 temporary_bp = PyObject_IsTrue (temporary);
965 if (temporary_bp == -1)
966 return -1;
967 }
968
969 if (bppy_init_validate_args (spec, source, function, label, line.get (),
970 type) == -1)
971 return -1;
972
973 bppy_pending_object = (gdbpy_breakpoint_object *) self;
974 bppy_pending_object->number = -1;
975 bppy_pending_object->bp = NULL;
976
977 try
978 {
979 switch (type)
980 {
981 case bp_breakpoint:
982 case bp_hardware_breakpoint:
983 {
984 location_spec_up locspec;
985 gdb_assert (PyBool_Check (qualified));
986 symbol_name_match_type func_name_match_type
987 = (qualified == Py_True
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 return gdbpy_handle_gdb_exception (-1, except);
1059 }
1060
1061 BPPY_SET_REQUIRE_VALID ((gdbpy_breakpoint_object *) self);
1062 return 0;
1063 }
1064
1065 /* __repr__ implementation for gdb.Breakpoint. */
1066
1067 static PyObject *
1068 bppy_repr (PyObject *self)
1069 {
1070 const auto bp = (struct gdbpy_breakpoint_object*) self;
1071 if (bp->bp == nullptr)
1072 return PyUnicode_FromFormat ("<%s (invalid)>", Py_TYPE (self)->tp_name);
1073
1074 std::string str = " ";
1075 if (bp->bp->thread != -1)
1076 str += string_printf ("thread=%d ", bp->bp->thread);
1077 if (bp->bp->task > 0)
1078 str += string_printf ("task=%d ", bp->bp->task);
1079 if (bp->bp->enable_count > 0)
1080 str += string_printf ("enable_count=%d ", bp->bp->enable_count);
1081 str.pop_back ();
1082
1083 return PyUnicode_FromFormat ("<%s%s number=%d hits=%d%s>",
1084 Py_TYPE (self)->tp_name,
1085 (bp->bp->enable_state == bp_enabled
1086 ? "" : " disabled"), bp->bp->number,
1087 bp->bp->hit_count, str.c_str ());
1088 }
1089
1090 /* Append to LIST the breakpoint Python object associated to B.
1091
1092 Return true on success. Return false on failure, with the Python error
1093 indicator set. */
1094
1095 static bool
1096 build_bp_list (struct breakpoint *b, PyObject *list)
1097 {
1098 PyObject *bp = (PyObject *) b->py_bp_object;
1099
1100 /* Not all breakpoints will have a companion Python object.
1101 Only breakpoints that were created via bppy_new, or
1102 breakpoints that were created externally and are tracked by
1103 the Python Scripting API. */
1104 if (bp == nullptr)
1105 return true;
1106
1107 return PyList_Append (list, bp) == 0;
1108 }
1109
1110 /* See python-internal.h. */
1111
1112 bool
1113 gdbpy_breakpoint_init_breakpoint_type ()
1114 {
1115 if (breakpoint_object_type.tp_new == nullptr)
1116 {
1117 breakpoint_object_type.tp_new = PyType_GenericNew;
1118 if (gdbpy_type_ready (&breakpoint_object_type) < 0)
1119 {
1120 /* Reset tp_new back to nullptr so future calls to this function
1121 will try calling PyType_Ready again. */
1122 breakpoint_object_type.tp_new = nullptr;
1123 return false;
1124 }
1125 }
1126
1127 return true;
1128 }
1129
1130 /* Static function to return a tuple holding all breakpoints. */
1131
1132 PyObject *
1133 gdbpy_breakpoints (PyObject *self, PyObject *args)
1134 {
1135 if (bppy_live == 0)
1136 return PyTuple_New (0);
1137
1138 gdbpy_ref<> list (PyList_New (0));
1139 if (list == NULL)
1140 return NULL;
1141
1142 /* If build_bp_list returns false, it signals an error condition. In that
1143 case abandon building the list and return nullptr. */
1144 for (breakpoint &bp : all_breakpoints ())
1145 if (!build_bp_list (&bp, list.get ()))
1146 return nullptr;
1147
1148 return PyList_AsTuple (list.get ());
1149 }
1150
1151 /* Call the "stop" method (if implemented) in the breakpoint
1152 class. If the method returns True, the inferior will be
1153 stopped at the breakpoint. Otherwise the inferior will be
1154 allowed to continue. */
1155
1156 enum ext_lang_bp_stop
1157 gdbpy_breakpoint_cond_says_stop (const struct extension_language_defn *extlang,
1158 struct breakpoint *b)
1159 {
1160 int stop;
1161 struct gdbpy_breakpoint_object *bp_obj = b->py_bp_object;
1162 PyObject *py_bp = (PyObject *) bp_obj;
1163
1164 if (bp_obj == NULL)
1165 return EXT_LANG_BP_STOP_UNSET;
1166
1167 stop = -1;
1168
1169 gdbpy_enter enter_py (b->gdbarch);
1170
1171 if (bp_obj->is_finish_bp)
1172 bpfinishpy_pre_stop_hook (bp_obj);
1173
1174 if (PyObject_HasAttrString (py_bp, stop_func))
1175 {
1176 gdbpy_ref<> result = gdbpy_call_method (py_bp, stop_func);
1177
1178 stop = 1;
1179 if (result != NULL)
1180 {
1181 int evaluate = PyObject_IsTrue (result.get ());
1182
1183 if (evaluate == -1)
1184 gdbpy_print_stack ();
1185
1186 /* If the "stop" function returns False that means
1187 the Python breakpoint wants GDB to continue. */
1188 if (! evaluate)
1189 stop = 0;
1190 }
1191 else
1192 gdbpy_print_stack ();
1193 }
1194
1195 if (bp_obj->is_finish_bp)
1196 bpfinishpy_post_stop_hook (bp_obj);
1197
1198 if (stop < 0)
1199 return EXT_LANG_BP_STOP_UNSET;
1200 return stop ? EXT_LANG_BP_STOP_YES : EXT_LANG_BP_STOP_NO;
1201 }
1202
1203 /* Checks if the "stop" method exists in this breakpoint.
1204 Used by condition_command to ensure mutual exclusion of breakpoint
1205 conditions. */
1206
1207 int
1208 gdbpy_breakpoint_has_cond (const struct extension_language_defn *extlang,
1209 struct breakpoint *b)
1210 {
1211 PyObject *py_bp;
1212
1213 if (b->py_bp_object == NULL)
1214 return 0;
1215
1216 py_bp = (PyObject *) b->py_bp_object;
1217
1218 gdbpy_enter enter_py (b->gdbarch);
1219 return PyObject_HasAttrString (py_bp, stop_func);
1220 }
1221
1222
1223
1225 /* Event callback functions. */
1226
1227 /* Callback that is used when a breakpoint is created. This function
1228 will create a new Python breakpoint object. */
1229 static void
1230 gdbpy_breakpoint_created (struct breakpoint *bp)
1231 {
1232 PYBP_SCOPED_DEBUG_ENTER_EXIT;
1233
1234 gdbpy_breakpoint_object *newbp;
1235
1236 if (!user_breakpoint_p (bp) && bppy_pending_object == NULL)
1237 {
1238 pybp_debug_printf ("not attaching python object to this breakpoint");
1239 return;
1240 }
1241
1242 if (bp->type != bp_breakpoint
1243 && bp->type != bp_hardware_breakpoint
1244 && bp->type != bp_watchpoint
1245 && bp->type != bp_hardware_watchpoint
1246 && bp->type != bp_read_watchpoint
1247 && bp->type != bp_access_watchpoint
1248 && bp->type != bp_catchpoint)
1249 {
1250 pybp_debug_printf ("is not a breakpoint or watchpoint");
1251 return;
1252 }
1253
1254 gdbpy_enter enter_py (bp->gdbarch);
1255
1256 if (bppy_pending_object)
1257 {
1258 newbp = bppy_pending_object;
1259 Py_INCREF (newbp);
1260 bppy_pending_object = NULL;
1261 pybp_debug_printf ("attaching existing breakpoint object");
1262 }
1263 else
1264 {
1265 newbp = PyObject_New (gdbpy_breakpoint_object, &breakpoint_object_type);
1266 pybp_debug_printf ("attaching new breakpoint object");
1267 }
1268 if (newbp)
1269 {
1270 newbp->number = bp->number;
1271 newbp->bp = bp;
1272 newbp->bp->py_bp_object = newbp;
1273 newbp->is_finish_bp = 0;
1274 ++bppy_live;
1275 }
1276 else
1277 {
1278 PyErr_SetString (PyExc_RuntimeError,
1279 _("Error while creating breakpoint from GDB."));
1280 gdbpy_print_stack ();
1281 }
1282
1283 if (!evregpy_no_listeners_p (gdb_py_events.breakpoint_created))
1284 {
1285 if (evpy_emit_event ((PyObject *) newbp,
1286 gdb_py_events.breakpoint_created) < 0)
1287 gdbpy_print_stack ();
1288 }
1289 }
1290
1291 /* Callback that is used when a breakpoint is deleted. This will
1292 invalidate the corresponding Python object. */
1293 static void
1294 gdbpy_breakpoint_deleted (struct breakpoint *b)
1295 {
1296 PYBP_SCOPED_DEBUG_ENTER_EXIT;
1297
1298 int num = b->number;
1299 struct breakpoint *bp = NULL;
1300
1301 bp = get_breakpoint (num);
1302 if (bp)
1303 {
1304 gdbpy_enter enter_py (b->gdbarch);
1305
1306 gdbpy_ref<gdbpy_breakpoint_object> bp_obj (bp->py_bp_object);
1307 if (bp_obj != NULL)
1308 {
1309 if (bp_obj->is_finish_bp)
1310 bpfinishpy_pre_delete_hook (bp_obj.get ());
1311
1312 if (!evregpy_no_listeners_p (gdb_py_events.breakpoint_deleted))
1313 {
1314 if (evpy_emit_event ((PyObject *) bp_obj.get (),
1315 gdb_py_events.breakpoint_deleted) < 0)
1316 gdbpy_print_stack ();
1317 }
1318
1319 bp_obj->bp = NULL;
1320 --bppy_live;
1321 }
1322 }
1323 }
1324
1325 /* Callback that is used when a breakpoint is modified. */
1326
1327 static void
1328 gdbpy_breakpoint_modified (struct breakpoint *b)
1329 {
1330 PYBP_SCOPED_DEBUG_ENTER_EXIT;
1331
1332 int num = b->number;
1333 struct breakpoint *bp = NULL;
1334
1335 bp = get_breakpoint (num);
1336 if (bp)
1337 {
1338 gdbpy_enter enter_py (b->gdbarch);
1339
1340 PyObject *bp_obj = (PyObject *) bp->py_bp_object;
1341 if (bp_obj)
1342 {
1343 if (!evregpy_no_listeners_p (gdb_py_events.breakpoint_modified))
1344 {
1345 if (evpy_emit_event (bp_obj,
1346 gdb_py_events.breakpoint_modified) < 0)
1347 gdbpy_print_stack ();
1348 }
1349 }
1350 }
1351 }
1352
1353
1354
1356 /* Initialize the Python breakpoint code. */
1357 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
1358 gdbpy_initialize_breakpoints (void)
1359 {
1360 int i;
1361
1362 if (!gdbpy_breakpoint_init_breakpoint_type ())
1363 return -1;
1364
1365 gdb::observers::breakpoint_created.attach (gdbpy_breakpoint_created,
1366 "py-breakpoint");
1367 gdb::observers::breakpoint_deleted.attach (gdbpy_breakpoint_deleted,
1368 "py-breakpoint");
1369 gdb::observers::breakpoint_modified.attach (gdbpy_breakpoint_modified,
1370 "py-breakpoint");
1371
1372 /* Add breakpoint types constants. */
1373 for (i = 0; pybp_codes[i].name; ++i)
1374 {
1375 if (PyModule_AddIntConstant (gdb_module, pybp_codes[i].name,
1376 pybp_codes[i].code) < 0)
1377 return -1;
1378 }
1379
1380 /* Add watchpoint types constants. */
1381 for (i = 0; pybp_watch_types[i].name; ++i)
1382 {
1383 if (PyModule_AddIntConstant (gdb_module, pybp_watch_types[i].name,
1384 pybp_watch_types[i].code) < 0)
1385 return -1;
1386 }
1387
1388 return 0;
1389 }
1390
1391 /* Initialize the Python BreakpointLocation code. */
1392
1393 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
1394 gdbpy_initialize_breakpoint_locations ()
1395 {
1396 return gdbpy_type_ready (&breakpoint_location_object_type);
1397 }
1398
1399
1400
1402 /* Helper function that overrides this Python object's
1403 PyObject_GenericSetAttr to allow extra validation of the attribute
1404 being set. */
1405
1406 static int
1407 local_setattro (PyObject *self, PyObject *name, PyObject *v)
1408 {
1409 gdbpy_breakpoint_object *obj = (gdbpy_breakpoint_object *) self;
1410 gdb::unique_xmalloc_ptr<char> attr (python_string_to_host_string (name));
1411
1412 if (attr == NULL)
1413 return -1;
1414
1415 /* If the attribute trying to be set is the "stop" method,
1416 but we already have a condition set in the CLI or other extension
1417 language, disallow this operation. */
1418 if (strcmp (attr.get (), stop_func) == 0)
1419 {
1420 const struct extension_language_defn *extlang = NULL;
1421
1422 if (obj->bp->cond_string != NULL)
1423 extlang = get_ext_lang_defn (EXT_LANG_GDB);
1424 if (extlang == NULL)
1425 extlang = get_breakpoint_cond_ext_lang (obj->bp, EXT_LANG_PYTHON);
1426 if (extlang != NULL)
1427 {
1428 std::string error_text
1429 = string_printf (_("Only one stop condition allowed. There is"
1430 " currently a %s stop condition defined for"
1431 " this breakpoint."),
1432 ext_lang_capitalized_name (extlang));
1433 PyErr_SetString (PyExc_RuntimeError, error_text.c_str ());
1434 return -1;
1435 }
1436 }
1437
1438 return PyObject_GenericSetAttr (self, name, v);
1439 }
1440
1441 static gdb_PyGetSetDef breakpoint_object_getset[] = {
1442 { "enabled", bppy_get_enabled, bppy_set_enabled,
1443 "Boolean telling whether the breakpoint is enabled.", NULL },
1444 { "silent", bppy_get_silent, bppy_set_silent,
1445 "Boolean telling whether the breakpoint is silent.", NULL },
1446 { "thread", bppy_get_thread, bppy_set_thread,
1447 "Thread ID for the breakpoint.\n\
1448 If the value is a thread ID (integer), then this is a thread-specific breakpoint.\n\
1449 If the value is None, then this breakpoint is not thread-specific.\n\
1450 No other type of value can be used.", NULL },
1451 { "inferior", bppy_get_inferior, bppy_set_inferior,
1452 "Inferior ID for the breakpoint.\n\
1453 If the value is an inferior ID (integer), then this is an inferior-specific\n\
1454 breakpoint. If the value is None, then this breakpoint is not\n\
1455 inferior-specific. No other type of value can be used.", NULL },
1456 { "task", bppy_get_task, bppy_set_task,
1457 "Thread ID for the breakpoint.\n\
1458 If the value is a task ID (integer), then this is an Ada task-specific breakpoint.\n\
1459 If the value is None, then this breakpoint is not task-specific.\n\
1460 No other type of value can be used.", NULL },
1461 { "ignore_count", bppy_get_ignore_count, bppy_set_ignore_count,
1462 "Number of times this breakpoint should be automatically continued.",
1463 NULL },
1464 { "number", bppy_get_number, NULL,
1465 "Breakpoint's number assigned by GDB.", NULL },
1466 { "hit_count", bppy_get_hit_count, bppy_set_hit_count,
1467 "Number of times the breakpoint has been hit.\n\
1468 Can be set to zero to clear the count. No other value is valid\n\
1469 when setting this property.", NULL },
1470 { "location", bppy_get_location, NULL,
1471 "Location of the breakpoint, as specified by the user.", NULL},
1472 { "expression", bppy_get_expression, NULL,
1473 "Expression of the breakpoint, as specified by the user.", NULL},
1474 { "condition", bppy_get_condition, bppy_set_condition,
1475 "Condition of the breakpoint, as specified by the user,\
1476 or None if no condition set."},
1477 { "commands", bppy_get_commands, bppy_set_commands,
1478 "Commands of the breakpoint, as specified by the user."},
1479 { "type", bppy_get_type, NULL,
1480 "Type of breakpoint."},
1481 { "visible", bppy_get_visibility, NULL,
1482 "Whether the breakpoint is visible to the user."},
1483 { "temporary", bppy_get_temporary, NULL,
1484 "Whether this breakpoint is a temporary breakpoint."},
1485 { "pending", bppy_get_pending, NULL,
1486 "Whether this breakpoint is a pending breakpoint."},
1487 { "locations", bppy_get_locations, NULL,
1488 "Get locations where this breakpoint was set"},
1489 { NULL } /* Sentinel. */
1490 };
1491
1492 static PyMethodDef breakpoint_object_methods[] =
1493 {
1494 { "is_valid", bppy_is_valid, METH_NOARGS,
1495 "Return true if this breakpoint is valid, false if not." },
1496 { "delete", bppy_delete_breakpoint, METH_NOARGS,
1497 "Delete the underlying GDB breakpoint." },
1498 { NULL } /* Sentinel. */
1499 };
1500
1501 PyTypeObject breakpoint_object_type =
1502 {
1503 PyVarObject_HEAD_INIT (NULL, 0)
1504 "gdb.Breakpoint", /*tp_name*/
1505 sizeof (gdbpy_breakpoint_object), /*tp_basicsize*/
1506 0, /*tp_itemsize*/
1507 0, /*tp_dealloc*/
1508 0, /*tp_print*/
1509 0, /*tp_getattr*/
1510 0, /*tp_setattr*/
1511 0, /*tp_compare*/
1512 bppy_repr, /*tp_repr*/
1513 0, /*tp_as_number*/
1514 0, /*tp_as_sequence*/
1515 0, /*tp_as_mapping*/
1516 0, /*tp_hash */
1517 0, /*tp_call*/
1518 0, /*tp_str*/
1519 0, /*tp_getattro*/
1520 (setattrofunc)local_setattro, /*tp_setattro */
1521 0, /*tp_as_buffer*/
1522 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1523 "GDB breakpoint object", /* tp_doc */
1524 0, /* tp_traverse */
1525 0, /* tp_clear */
1526 0, /* tp_richcompare */
1527 0, /* tp_weaklistoffset */
1528 0, /* tp_iter */
1529 0, /* tp_iternext */
1530 breakpoint_object_methods, /* tp_methods */
1531 0, /* tp_members */
1532 breakpoint_object_getset, /* tp_getset */
1533 0, /* tp_base */
1534 0, /* tp_dict */
1535 0, /* tp_descr_get */
1536 0, /* tp_descr_set */
1537 0, /* tp_dictoffset */
1538 bppy_init, /* tp_init */
1539 0, /* tp_alloc */
1540 };
1541
1542 void _initialize_py_breakpoint ();
1543 void
1544 _initialize_py_breakpoint ()
1545 {
1546 add_setshow_boolean_cmd
1547 ("py-breakpoint", class_maintenance, &pybp_debug,
1548 _("Set Python breakpoint debugging."),
1549 _("Show Python breakpoint debugging."),
1550 _("When on, Python breakpoint debugging is enabled."),
1551 NULL,
1552 show_pybp_debug,
1553 &setdebuglist, &showdebuglist);
1554 }
1555
1556 GDBPY_INITIALIZE_FILE (gdbpy_initialize_breakpoints);
1557 GDBPY_INITIALIZE_FILE (gdbpy_initialize_breakpoint_locations);
1558
1559 /* Python function to set the enabled state of a breakpoint location. */
1560
1561 static int
1562 bplocpy_set_enabled (PyObject *py_self, PyObject *newvalue, void *closure)
1563 {
1564 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1565 BPPY_SET_REQUIRE_VALID (self->owner);
1566 BPLOCPY_SET_REQUIRE_VALID (self->owner, self);
1567
1568 if (newvalue == nullptr)
1569 {
1570 PyErr_SetString (PyExc_TypeError,
1571 _("Cannot delete 'enabled' attribute."));
1572 return -1;
1573 }
1574 else if (!PyBool_Check (newvalue))
1575 {
1576 PyErr_SetString (PyExc_TypeError,
1577 _("The value of 'enabled' must be a boolean."));
1578 return -1;
1579 }
1580
1581 int cmp = PyObject_IsTrue (newvalue);
1582 if (cmp < 0)
1583 return -1;
1584
1585 try
1586 {
1587 enable_disable_bp_location (self->bp_loc, cmp == 1);
1588 }
1589 catch (const gdb_exception &except)
1590 {
1591 return gdbpy_handle_gdb_exception (-1, except);
1592 }
1593 return 0;
1594 }
1595
1596 /* Python function to test whether or not the breakpoint location is enabled. */
1597
1598 static PyObject *
1599 bplocpy_get_enabled (PyObject *py_self, void *closure)
1600 {
1601 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1602 BPPY_REQUIRE_VALID (self->owner);
1603 BPLOCPY_REQUIRE_VALID (self->owner, self);
1604
1605 if (self->bp_loc->enabled)
1606 Py_RETURN_TRUE;
1607 else
1608 Py_RETURN_FALSE;
1609 }
1610
1611 /* Python function to get address of breakpoint location. */
1612
1613 static PyObject *
1614 bplocpy_get_address (PyObject *py_self, void *closure)
1615 {
1616 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1617 BPPY_REQUIRE_VALID (self->owner);
1618 BPLOCPY_REQUIRE_VALID (self->owner, self);
1619 return gdb_py_object_from_ulongest (self->bp_loc->address).release ();
1620 }
1621
1622 /* Python function to get owner of breakpoint location, which
1623 is of type gdb.Breakpoint. */
1624
1625 static PyObject *
1626 bplocpy_get_owner (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 Py_INCREF (self->owner);
1632 return (PyObject *) self->owner;
1633 }
1634
1635 /* Python function to get the source file name path and line number
1636 where this breakpoint location was set. */
1637
1638 static PyObject *
1639 bplocpy_get_source_location (PyObject *py_self, void *closure)
1640 {
1641 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1642 BPPY_REQUIRE_VALID (self->owner);
1643 BPLOCPY_REQUIRE_VALID (self->owner, self);
1644 if (self->bp_loc->symtab)
1645 {
1646 gdbpy_ref<> tup (PyTuple_New (2));
1647 if (tup == nullptr)
1648 return nullptr;
1649 /* symtab->filename is never NULL. */
1650 gdbpy_ref<> filename
1651 = host_string_to_python_string (self->bp_loc->symtab->filename);
1652 if (filename == nullptr)
1653 return nullptr;
1654 auto line = gdb_py_object_from_ulongest (self->bp_loc->line_number);
1655 if (line == nullptr)
1656 return nullptr;
1657 if (PyTuple_SetItem (tup.get (), 0, filename.release ()) == -1
1658 || PyTuple_SetItem (tup.get (), 1, line.release ()) == -1)
1659 return nullptr;
1660 return tup.release ();
1661 }
1662 else
1663 Py_RETURN_NONE;
1664 }
1665
1666 /* Python function to get the function name of where this location was set. */
1667
1668 static PyObject *
1669 bplocpy_get_function (PyObject *py_self, void *closure)
1670 {
1671 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1672 BPPY_REQUIRE_VALID (self->owner);
1673 BPLOCPY_REQUIRE_VALID (self->owner, self);
1674 const auto fn_name = self->bp_loc->function_name.get ();
1675 if (fn_name != nullptr)
1676 return host_string_to_python_string (fn_name).release ();
1677 Py_RETURN_NONE;
1678 }
1679
1680 static PyObject *
1681 bplocpy_get_thread_groups (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 gdbpy_ref<> list (PyList_New (0));
1687 if (list == nullptr)
1688 return nullptr;
1689 for (inferior *inf : all_inferiors ())
1690 {
1691 if (inf->pspace == self->bp_loc->pspace)
1692 {
1693 gdbpy_ref<> num = gdb_py_object_from_ulongest (inf->num);
1694 if (num == nullptr)
1695 return nullptr;
1696 if (PyList_Append (list.get (), num.get ()) != 0)
1697 return nullptr;
1698 }
1699 }
1700 return list.release ();
1701 }
1702
1703 static PyObject *
1704 bplocpy_get_fullname (PyObject *py_self, void *closure)
1705 {
1706 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1707 BPPY_REQUIRE_VALID (self->owner);
1708 BPLOCPY_REQUIRE_VALID (self->owner, self);
1709 const auto symtab = self->bp_loc->symtab;
1710 if (symtab != nullptr && symtab->fullname () != nullptr)
1711 {
1712 gdbpy_ref<> fullname
1713 = host_string_to_python_string (symtab->fullname ());
1714 return fullname.release ();
1715 }
1716 Py_RETURN_NONE;
1717 }
1718
1719 /* De-allocation function to be called for the Python object. */
1720
1721 static void
1722 bplocpy_dealloc (PyObject *py_self)
1723 {
1724 auto *self = (gdbpy_breakpoint_location_object *) py_self;
1725 bp_location_ref_ptr decrementing_ref {self->bp_loc};
1726 Py_XDECREF (self->owner);
1727 Py_TYPE (py_self)->tp_free (py_self);
1728 }
1729
1730 /* __repr__ implementation for gdb.BreakpointLocation. */
1731
1732 static PyObject *
1733 bplocpy_repr (PyObject *py_self)
1734 {
1735 const auto self = (gdbpy_breakpoint_location_object *) py_self;
1736 if (self->owner == nullptr || self->owner->bp == nullptr
1737 || self->owner->bp != self->bp_loc->owner)
1738 return gdb_py_invalid_object_repr (py_self);
1739
1740 const auto enabled = self->bp_loc->enabled ? "enabled" : "disabled";
1741
1742 std::string str (enabled);
1743
1744 str += string_printf (" address=%s",
1745 paddress (self->bp_loc->owner->gdbarch,
1746 self->bp_loc->address));
1747
1748 if (self->bp_loc->requested_address != self->bp_loc->address)
1749 str += string_printf (" requested_address=%s",
1750 paddress (self->bp_loc->owner->gdbarch,
1751 self->bp_loc->requested_address));
1752 if (self->bp_loc->symtab != nullptr)
1753 str += string_printf (" source=%s:%d", self->bp_loc->symtab->filename,
1754 self->bp_loc->line_number);
1755
1756 const auto fn_name = self->bp_loc->function_name.get ();
1757 if (fn_name != nullptr)
1758 {
1759 str += " in ";
1760 str += fn_name;
1761 }
1762
1763 return PyUnicode_FromFormat ("<%s %s>", Py_TYPE (self)->tp_name,
1764 str.c_str ());
1765 }
1766
1767 /* Attribute get/set Python definitions. */
1768
1769 static gdb_PyGetSetDef bp_location_object_getset[] = {
1770 { "enabled", bplocpy_get_enabled, bplocpy_set_enabled,
1771 "Boolean telling whether the breakpoint is enabled.", NULL },
1772 { "owner", bplocpy_get_owner, NULL,
1773 "Get the breakpoint owner object", NULL },
1774 { "address", bplocpy_get_address, NULL,
1775 "Get address of where this location was set", NULL},
1776 { "source", bplocpy_get_source_location, NULL,
1777 "Get file and line number of where this location was set", NULL},
1778 { "function", bplocpy_get_function, NULL,
1779 "Get function of where this location was set", NULL },
1780 { "fullname", bplocpy_get_fullname, NULL,
1781 "Get fullname of where this location was set", NULL },
1782 { "thread_groups", bplocpy_get_thread_groups, NULL,
1783 "Get thread groups where this location is in", NULL },
1784 { NULL } /* Sentinel. */
1785 };
1786
1787 PyTypeObject breakpoint_location_object_type =
1788 {
1789 PyVarObject_HEAD_INIT (NULL, 0)
1790 "gdb.BreakpointLocation", /*tp_name*/
1791 sizeof (gdbpy_breakpoint_location_object), /*tp_basicsize*/
1792 0, /*tp_itemsize*/
1793 bplocpy_dealloc, /*tp_dealloc*/
1794 0, /*tp_print*/
1795 0, /*tp_getattr*/
1796 0, /*tp_setattr*/
1797 0, /*tp_compare*/
1798 bplocpy_repr, /*tp_repr*/
1799 0, /*tp_as_number*/
1800 0, /*tp_as_sequence*/
1801 0, /*tp_as_mapping*/
1802 0, /*tp_hash */
1803 0, /*tp_call*/
1804 0, /*tp_str*/
1805 0, /*tp_getattro*/
1806 0, /*tp_setattro */
1807 0, /*tp_as_buffer*/
1808 Py_TPFLAGS_DEFAULT, /*tp_flags*/
1809 "GDB breakpoint location object", /* tp_doc */
1810 0, /* tp_traverse */
1811 0, /* tp_clear */
1812 0, /* tp_richcompare */
1813 0, /* tp_weaklistoffset */
1814 0, /* tp_iter */
1815 0, /* tp_iternext */
1816 0, /* tp_methods */
1817 0, /* tp_members */
1818 bp_location_object_getset, /* tp_getset */
1819 0, /* tp_base */
1820 0, /* tp_dict */
1821 0, /* tp_descr_get */
1822 0, /* tp_descr_set */
1823 0, /* tp_dictoffset */
1824 0, /* tp_init */
1825 0, /* tp_alloc */
1826 };
1827