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
show_pybp_debug(struct ui_file * file,int from_tty,struct cmd_list_element * c,const char * value)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 *
bppy_is_valid(PyObject * self,PyObject * args)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 *
bppy_get_enabled(PyObject * self,void * closure)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 *
bppy_get_silent(PyObject * self,void * closure)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
bppy_set_enabled(PyObject * self,PyObject * newvalue,void * closure)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
bppy_set_silent(PyObject * self,PyObject * newvalue,void * closure)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
bppy_set_thread(PyObject * self,PyObject * newvalue,void * closure)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
bppy_set_inferior(PyObject * self,PyObject * newvalue,void * closure)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
bppy_set_task(PyObject * self,PyObject * newvalue,void * closure)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 *
bppy_delete_breakpoint(PyObject * self,PyObject * args)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
bppy_set_ignore_count(PyObject * self,PyObject * newvalue,void * closure)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
bppy_set_hit_count(PyObject * self,PyObject * newvalue,void * closure)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 *
bppy_get_location(PyObject * self,void * closure)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 *
bppy_get_expression(PyObject * self,void * closure)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 *
bppy_get_condition(PyObject * self,void * closure)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
bppy_set_condition(PyObject * self,PyObject * newvalue,void * closure)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 *
bppy_get_commands(PyObject * self,void * closure)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
bppy_set_commands(PyObject * self,PyObject * newvalue,void * closure)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 *
bppy_get_type(PyObject * self,void * closure)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 *
bppy_get_visibility(PyObject * self,void * closure)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 *
bppy_get_temporary(PyObject * self,void * closure)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 *
bppy_get_pending(PyObject * self,void * closure)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 *
bppy_get_number(PyObject * self,void * closure)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 *
bppy_get_thread(PyObject * self,void * closure)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 *
bppy_get_inferior(PyObject * self,void * closure)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 *
bppy_get_task(PyObject * self,void * closure)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 *
bppy_get_hit_count(PyObject * self,void * closure)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 *
bppy_get_ignore_count(PyObject * self,void * closure)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 *
bppy_get_locations(PyObject * self,void * closure)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
bppy_init_validate_args(const char * spec,char * source,char * function,char * label,char * line,enum bptype type)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
bppy_init(PyObject * self,PyObject * args,PyObject * kwargs)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 (&copy,
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 *
bppy_repr(PyObject * self)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
build_bp_list(struct breakpoint * b,PyObject * list)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
gdbpy_breakpoint_init_breakpoint_type()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 *
gdbpy_breakpoints(PyObject * self,PyObject * args)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
gdbpy_breakpoint_cond_says_stop(const struct extension_language_defn * extlang,struct breakpoint * b)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
gdbpy_breakpoint_has_cond(const struct extension_language_defn * extlang,struct breakpoint * b)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 
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
gdbpy_breakpoint_created(struct breakpoint * bp)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
gdbpy_breakpoint_deleted(struct breakpoint * b)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
gdbpy_breakpoint_modified(struct breakpoint * b)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 
1355 /* Initialize the Python breakpoint code.  */
1356 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
gdbpy_initialize_breakpoints(void)1357 gdbpy_initialize_breakpoints (void)
1358 {
1359   int i;
1360 
1361   if (!gdbpy_breakpoint_init_breakpoint_type ())
1362     return -1;
1363 
1364   if (gdb_pymodule_addobject (gdb_module, "Breakpoint",
1365                                     (PyObject *) &breakpoint_object_type) < 0)
1366     return -1;
1367 
1368   gdb::observers::breakpoint_created.attach (gdbpy_breakpoint_created,
1369                                                        "py-breakpoint");
1370   gdb::observers::breakpoint_deleted.attach (gdbpy_breakpoint_deleted,
1371                                                        "py-breakpoint");
1372   gdb::observers::breakpoint_modified.attach (gdbpy_breakpoint_modified,
1373                                                         "py-breakpoint");
1374 
1375   /* Add breakpoint types constants.  */
1376   for (i = 0; pybp_codes[i].name; ++i)
1377     {
1378       if (PyModule_AddIntConstant (gdb_module, pybp_codes[i].name,
1379                                            pybp_codes[i].code) < 0)
1380           return -1;
1381     }
1382 
1383   /* Add watchpoint types constants.  */
1384   for (i = 0; pybp_watch_types[i].name; ++i)
1385     {
1386       if (PyModule_AddIntConstant (gdb_module, pybp_watch_types[i].name,
1387                                            pybp_watch_types[i].code) < 0)
1388           return -1;
1389     }
1390 
1391   return 0;
1392 }
1393 
1394 /* Initialize the Python BreakpointLocation code.  */
1395 
1396 static int CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
gdbpy_initialize_breakpoint_locations()1397 gdbpy_initialize_breakpoint_locations ()
1398 {
1399   if (PyType_Ready (&breakpoint_location_object_type) < 0)
1400     return -1;
1401 
1402   if (gdb_pymodule_addobject (gdb_module, "BreakpointLocation",
1403                                     (PyObject *) &breakpoint_location_object_type)
1404       < 0)
1405     return -1;
1406   return 0;
1407 }
1408 
1409 
1410 
1411 /* Helper function that overrides this Python object's
1412    PyObject_GenericSetAttr to allow extra validation of the attribute
1413    being set.  */
1414 
1415 static int
local_setattro(PyObject * self,PyObject * name,PyObject * v)1416 local_setattro (PyObject *self, PyObject *name, PyObject *v)
1417 {
1418   gdbpy_breakpoint_object *obj = (gdbpy_breakpoint_object *) self;
1419   gdb::unique_xmalloc_ptr<char> attr (python_string_to_host_string (name));
1420 
1421   if (attr == NULL)
1422     return -1;
1423 
1424   /* If the attribute trying to be set is the "stop" method,
1425      but we already have a condition set in the CLI or other extension
1426      language, disallow this operation.  */
1427   if (strcmp (attr.get (), stop_func) == 0)
1428     {
1429       const struct extension_language_defn *extlang = NULL;
1430 
1431       if (obj->bp->cond_string != NULL)
1432           extlang = get_ext_lang_defn (EXT_LANG_GDB);
1433       if (extlang == NULL)
1434           extlang = get_breakpoint_cond_ext_lang (obj->bp, EXT_LANG_PYTHON);
1435       if (extlang != NULL)
1436           {
1437             std::string error_text
1438               = string_printf (_("Only one stop condition allowed.  There is"
1439                                      " currently a %s stop condition defined for"
1440                                      " this breakpoint."),
1441                                    ext_lang_capitalized_name (extlang));
1442             PyErr_SetString (PyExc_RuntimeError, error_text.c_str ());
1443             return -1;
1444           }
1445     }
1446 
1447   return PyObject_GenericSetAttr (self, name, v);
1448 }
1449 
1450 static gdb_PyGetSetDef breakpoint_object_getset[] = {
1451   { "enabled", bppy_get_enabled, bppy_set_enabled,
1452     "Boolean telling whether the breakpoint is enabled.", NULL },
1453   { "silent", bppy_get_silent, bppy_set_silent,
1454     "Boolean telling whether the breakpoint is silent.", NULL },
1455   { "thread", bppy_get_thread, bppy_set_thread,
1456     "Thread ID for the breakpoint.\n\
1457 If the value is a thread ID (integer), then this is a thread-specific breakpoint.\n\
1458 If the value is None, then this breakpoint is not thread-specific.\n\
1459 No other type of value can be used.", NULL },
1460   { "inferior", bppy_get_inferior, bppy_set_inferior,
1461     "Inferior ID for the breakpoint.\n\
1462 If the value is an inferior ID (integer), then this is an inferior-specific\n\
1463 breakpoint.  If the value is None, then this breakpoint is not\n\
1464 inferior-specific.  No other type of value can be used.", NULL },
1465   { "task", bppy_get_task, bppy_set_task,
1466     "Thread ID for the breakpoint.\n\
1467 If the value is a task ID (integer), then this is an Ada task-specific breakpoint.\n\
1468 If the value is None, then this breakpoint is not task-specific.\n\
1469 No other type of value can be used.", NULL },
1470   { "ignore_count", bppy_get_ignore_count, bppy_set_ignore_count,
1471     "Number of times this breakpoint should be automatically continued.",
1472     NULL },
1473   { "number", bppy_get_number, NULL,
1474     "Breakpoint's number assigned by GDB.", NULL },
1475   { "hit_count", bppy_get_hit_count, bppy_set_hit_count,
1476     "Number of times the breakpoint has been hit.\n\
1477 Can be set to zero to clear the count. No other value is valid\n\
1478 when setting this property.", NULL },
1479   { "location", bppy_get_location, NULL,
1480     "Location of the breakpoint, as specified by the user.", NULL},
1481   { "expression", bppy_get_expression, NULL,
1482     "Expression of the breakpoint, as specified by the user.", NULL},
1483   { "condition", bppy_get_condition, bppy_set_condition,
1484     "Condition of the breakpoint, as specified by the user,\
1485 or None if no condition set."},
1486   { "commands", bppy_get_commands, bppy_set_commands,
1487     "Commands of the breakpoint, as specified by the user."},
1488   { "type", bppy_get_type, NULL,
1489     "Type of breakpoint."},
1490   { "visible", bppy_get_visibility, NULL,
1491     "Whether the breakpoint is visible to the user."},
1492   { "temporary", bppy_get_temporary, NULL,
1493     "Whether this breakpoint is a temporary breakpoint."},
1494   { "pending", bppy_get_pending, NULL,
1495     "Whether this breakpoint is a pending breakpoint."},
1496   { "locations", bppy_get_locations, NULL,
1497     "Get locations where this breakpoint was set"},
1498   { NULL }  /* Sentinel.  */
1499 };
1500 
1501 static PyMethodDef breakpoint_object_methods[] =
1502 {
1503   { "is_valid", bppy_is_valid, METH_NOARGS,
1504     "Return true if this breakpoint is valid, false if not." },
1505   { "delete", bppy_delete_breakpoint, METH_NOARGS,
1506     "Delete the underlying GDB breakpoint." },
1507   { NULL } /* Sentinel.  */
1508 };
1509 
1510 PyTypeObject breakpoint_object_type =
1511 {
1512   PyVarObject_HEAD_INIT (NULL, 0)
1513   "gdb.Breakpoint",             /*tp_name*/
1514   sizeof (gdbpy_breakpoint_object), /*tp_basicsize*/
1515   0,                                      /*tp_itemsize*/
1516   0,                                      /*tp_dealloc*/
1517   0,                                      /*tp_print*/
1518   0,                                      /*tp_getattr*/
1519   0,                                      /*tp_setattr*/
1520   0,                                      /*tp_compare*/
1521   bppy_repr,                     /*tp_repr*/
1522   0,                                      /*tp_as_number*/
1523   0,                                      /*tp_as_sequence*/
1524   0,                                      /*tp_as_mapping*/
1525   0,                                      /*tp_hash */
1526   0,                                      /*tp_call*/
1527   0,                                      /*tp_str*/
1528   0,                                      /*tp_getattro*/
1529   (setattrofunc)local_setattro,   /*tp_setattro */
1530   0,                                      /*tp_as_buffer*/
1531   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
1532   "GDB breakpoint object",      /* tp_doc */
1533   0,                                      /* tp_traverse */
1534   0,                                      /* tp_clear */
1535   0,                                      /* tp_richcompare */
1536   0,                                      /* tp_weaklistoffset */
1537   0,                                      /* tp_iter */
1538   0,                                      /* tp_iternext */
1539   breakpoint_object_methods,    /* tp_methods */
1540   0,                                      /* tp_members */
1541   breakpoint_object_getset,     /* tp_getset */
1542   0,                                      /* tp_base */
1543   0,                                      /* tp_dict */
1544   0,                                      /* tp_descr_get */
1545   0,                                      /* tp_descr_set */
1546   0,                                      /* tp_dictoffset */
1547   bppy_init,                              /* tp_init */
1548   0,                                      /* tp_alloc */
1549 };
1550 
1551 void _initialize_py_breakpoint ();
1552 void
_initialize_py_breakpoint()1553 _initialize_py_breakpoint ()
1554 {
1555   add_setshow_boolean_cmd
1556       ("py-breakpoint", class_maintenance, &pybp_debug,
1557           _("Set Python breakpoint debugging."),
1558           _("Show Python breakpoint debugging."),
1559           _("When on, Python breakpoint debugging is enabled."),
1560           NULL,
1561           show_pybp_debug,
1562           &setdebuglist, &showdebuglist);
1563 }
1564 
1565 GDBPY_INITIALIZE_FILE (gdbpy_initialize_breakpoints);
1566 GDBPY_INITIALIZE_FILE (gdbpy_initialize_breakpoint_locations);
1567 
1568 /* Python function to set the enabled state of a breakpoint location.  */
1569 
1570 static int
bplocpy_set_enabled(PyObject * py_self,PyObject * newvalue,void * closure)1571 bplocpy_set_enabled (PyObject *py_self, PyObject *newvalue, void *closure)
1572 {
1573   auto *self = (gdbpy_breakpoint_location_object *) py_self;
1574   BPPY_SET_REQUIRE_VALID (self->owner);
1575   BPLOCPY_SET_REQUIRE_VALID (self->owner, self);
1576 
1577   if (newvalue == nullptr)
1578     {
1579       PyErr_SetString (PyExc_TypeError,
1580                            _("Cannot delete 'enabled' attribute."));
1581       return -1;
1582     }
1583   else if (!PyBool_Check (newvalue))
1584     {
1585       PyErr_SetString (PyExc_TypeError,
1586                            _("The value of 'enabled' must be a boolean."));
1587       return -1;
1588     }
1589 
1590   int cmp = PyObject_IsTrue (newvalue);
1591   if (cmp < 0)
1592     return -1;
1593 
1594   try
1595     {
1596       enable_disable_bp_location (self->bp_loc, cmp == 1);
1597     }
1598   catch (const gdb_exception &except)
1599     {
1600       GDB_PY_SET_HANDLE_EXCEPTION (except);
1601     }
1602   return 0;
1603 }
1604 
1605 /* Python function to test whether or not the breakpoint location is enabled.  */
1606 
1607 static PyObject *
bplocpy_get_enabled(PyObject * py_self,void * closure)1608 bplocpy_get_enabled (PyObject *py_self, void *closure)
1609 {
1610   auto *self = (gdbpy_breakpoint_location_object *) py_self;
1611   BPPY_REQUIRE_VALID (self->owner);
1612   BPLOCPY_REQUIRE_VALID (self->owner, self);
1613 
1614   if (self->bp_loc->enabled)
1615     Py_RETURN_TRUE;
1616   else
1617     Py_RETURN_FALSE;
1618 }
1619 
1620 /* Python function to get address of breakpoint location.  */
1621 
1622 static PyObject *
bplocpy_get_address(PyObject * py_self,void * closure)1623 bplocpy_get_address (PyObject *py_self, void *closure)
1624 {
1625   auto *self = (gdbpy_breakpoint_location_object *) py_self;
1626   BPPY_REQUIRE_VALID (self->owner);
1627   BPLOCPY_REQUIRE_VALID (self->owner, self);
1628   return gdb_py_object_from_ulongest (self->bp_loc->address).release ();
1629 }
1630 
1631 /* Python function to get owner of breakpoint location, which
1632    is of type gdb.Breakpoint.  */
1633 
1634 static PyObject *
bplocpy_get_owner(PyObject * py_self,void * closure)1635 bplocpy_get_owner (PyObject *py_self, void *closure)
1636 {
1637   auto *self = (gdbpy_breakpoint_location_object *) py_self;
1638   BPPY_REQUIRE_VALID (self->owner);
1639   BPLOCPY_REQUIRE_VALID (self->owner, self);
1640   Py_INCREF (self->owner);
1641   return (PyObject *) self->owner;
1642 }
1643 
1644 /* Python function to get the source file name path and line number
1645    where this breakpoint location was set.   */
1646 
1647 static PyObject *
bplocpy_get_source_location(PyObject * py_self,void * closure)1648 bplocpy_get_source_location (PyObject *py_self, void *closure)
1649 {
1650   auto *self = (gdbpy_breakpoint_location_object *) py_self;
1651   BPPY_REQUIRE_VALID (self->owner);
1652   BPLOCPY_REQUIRE_VALID (self->owner, self);
1653   if (self->bp_loc->symtab)
1654     {
1655       gdbpy_ref<> tup (PyTuple_New (2));
1656       if (tup == nullptr)
1657           return nullptr;
1658       /* symtab->filename is never NULL. */
1659       gdbpy_ref<> filename
1660           = host_string_to_python_string (self->bp_loc->symtab->filename);
1661       if (filename == nullptr)
1662           return nullptr;
1663       auto line = gdb_py_object_from_ulongest (self->bp_loc->line_number);
1664       if (line == nullptr)
1665           return nullptr;
1666       if (PyTuple_SetItem (tup.get (), 0, filename.release ()) == -1
1667             || PyTuple_SetItem (tup.get (), 1, line.release ()) == -1)
1668           return nullptr;
1669       return tup.release ();
1670     }
1671   else
1672     Py_RETURN_NONE;
1673 }
1674 
1675 /* Python function to get the function name of where this location was set.  */
1676 
1677 static PyObject *
bplocpy_get_function(PyObject * py_self,void * closure)1678 bplocpy_get_function (PyObject *py_self, void *closure)
1679 {
1680   auto *self = (gdbpy_breakpoint_location_object *) py_self;
1681   BPPY_REQUIRE_VALID (self->owner);
1682   BPLOCPY_REQUIRE_VALID (self->owner, self);
1683   const auto fn_name = self->bp_loc->function_name.get ();
1684   if (fn_name != nullptr)
1685     return host_string_to_python_string (fn_name).release ();
1686   Py_RETURN_NONE;
1687 }
1688 
1689 static PyObject *
bplocpy_get_thread_groups(PyObject * py_self,void * closure)1690 bplocpy_get_thread_groups (PyObject *py_self, void *closure)
1691 {
1692   auto *self = (gdbpy_breakpoint_location_object *) py_self;
1693   BPPY_REQUIRE_VALID (self->owner);
1694   BPLOCPY_REQUIRE_VALID (self->owner, self);
1695   gdbpy_ref<> list (PyList_New (0));
1696   if (list == nullptr)
1697     return nullptr;
1698   for (inferior *inf : all_inferiors ())
1699     {
1700       if (inf->pspace == self->bp_loc->pspace)
1701           {
1702             gdbpy_ref<> num = gdb_py_object_from_ulongest (inf->num);
1703             if (num == nullptr)
1704               return nullptr;
1705             if (PyList_Append (list.get (), num.release ()) != 0)
1706               return nullptr;
1707           }
1708     }
1709   return list.release ();
1710 }
1711 
1712 static PyObject *
bplocpy_get_fullname(PyObject * py_self,void * closure)1713 bplocpy_get_fullname (PyObject *py_self, void *closure)
1714 {
1715   auto *self = (gdbpy_breakpoint_location_object *) py_self;
1716   BPPY_REQUIRE_VALID (self->owner);
1717   BPLOCPY_REQUIRE_VALID (self->owner, self);
1718   const auto symtab = self->bp_loc->symtab;
1719   if (symtab != nullptr && symtab->fullname != nullptr)
1720     {
1721       gdbpy_ref<> fullname
1722           = host_string_to_python_string (symtab->fullname);
1723       return fullname.release ();
1724     }
1725   Py_RETURN_NONE;
1726 }
1727 
1728 /* De-allocation function to be called for the Python object.  */
1729 
1730 static void
bplocpy_dealloc(PyObject * py_self)1731 bplocpy_dealloc (PyObject *py_self)
1732 {
1733   auto *self = (gdbpy_breakpoint_location_object *) py_self;
1734   bp_location_ref_ptr decrementing_ref {self->bp_loc};
1735   Py_XDECREF (self->owner);
1736   Py_TYPE (py_self)->tp_free (py_self);
1737 }
1738 
1739 /* __repr__ implementation for gdb.BreakpointLocation.  */
1740 
1741 static PyObject *
bplocpy_repr(PyObject * py_self)1742 bplocpy_repr (PyObject *py_self)
1743 {
1744   const auto self = (gdbpy_breakpoint_location_object *) py_self;
1745   if (self->owner == nullptr || self->owner->bp == nullptr
1746       || self->owner->bp != self->bp_loc->owner)
1747     return gdb_py_invalid_object_repr (py_self);
1748 
1749   const auto enabled = self->bp_loc->enabled ? "enabled" : "disabled";
1750 
1751   std::string str (enabled);
1752 
1753   str += string_printf (" address=%s",
1754                               paddress (self->bp_loc->owner->gdbarch,
1755                                           self->bp_loc->address));
1756 
1757   if (self->bp_loc->requested_address != self->bp_loc->address)
1758     str += string_printf (" requested_address=%s",
1759                                 paddress (self->bp_loc->owner->gdbarch,
1760                                             self->bp_loc->requested_address));
1761   if (self->bp_loc->symtab != nullptr)
1762     str += string_printf (" source=%s:%d", self->bp_loc->symtab->filename,
1763                                 self->bp_loc->line_number);
1764 
1765   const auto fn_name = self->bp_loc->function_name.get ();
1766   if (fn_name != nullptr)
1767     {
1768       str += " in ";
1769       str += fn_name;
1770     }
1771 
1772   return PyUnicode_FromFormat ("<%s %s>", Py_TYPE (self)->tp_name,
1773                                      str.c_str ());
1774 }
1775 
1776 /* Attribute get/set Python definitions. */
1777 
1778 static gdb_PyGetSetDef bp_location_object_getset[] = {
1779   { "enabled", bplocpy_get_enabled, bplocpy_set_enabled,
1780     "Boolean telling whether the breakpoint is enabled.", NULL },
1781   { "owner", bplocpy_get_owner, NULL,
1782     "Get the breakpoint owner object", NULL },
1783   { "address", bplocpy_get_address, NULL,
1784     "Get address of where this location was set", NULL},
1785   { "source", bplocpy_get_source_location, NULL,
1786     "Get file and line number of where this location was set", NULL},
1787   { "function", bplocpy_get_function, NULL,
1788     "Get function of where this location was set", NULL },
1789   { "fullname", bplocpy_get_fullname, NULL,
1790     "Get fullname of where this location was set", NULL },
1791   { "thread_groups", bplocpy_get_thread_groups, NULL,
1792     "Get thread groups where this location is in", NULL },
1793   { NULL }  /* Sentinel.  */
1794 };
1795 
1796 PyTypeObject breakpoint_location_object_type =
1797 {
1798   PyVarObject_HEAD_INIT (NULL, 0)
1799   "gdb.BreakpointLocation",             /*tp_name*/
1800   sizeof (gdbpy_breakpoint_location_object), /*tp_basicsize*/
1801   0,                                              /*tp_itemsize*/
1802   bplocpy_dealloc,                                /*tp_dealloc*/
1803   0,                                              /*tp_print*/
1804   0,                                              /*tp_getattr*/
1805   0,                                              /*tp_setattr*/
1806   0,                                              /*tp_compare*/
1807   bplocpy_repr,                        /*tp_repr*/
1808   0,                                              /*tp_as_number*/
1809   0,                                              /*tp_as_sequence*/
1810   0,                                              /*tp_as_mapping*/
1811   0,                                              /*tp_hash */
1812   0,                                              /*tp_call*/
1813   0,                                              /*tp_str*/
1814   0,                                              /*tp_getattro*/
1815   0,                                              /*tp_setattro */
1816   0,                                              /*tp_as_buffer*/
1817   Py_TPFLAGS_DEFAULT,                             /*tp_flags*/
1818   "GDB breakpoint location object",     /* tp_doc */
1819   0,                                              /* tp_traverse */
1820   0,                                              /* tp_clear */
1821   0,                                              /* tp_richcompare */
1822   0,                                              /* tp_weaklistoffset */
1823   0,                                              /* tp_iter */
1824   0,                                              /* tp_iternext */
1825   0,                                              /* tp_methods */
1826   0,                                              /* tp_members */
1827   bp_location_object_getset,            /* tp_getset */
1828   0,                                              /* tp_base */
1829   0,                                              /* tp_dict */
1830   0,                                              /* tp_descr_get */
1831   0,                                              /* tp_descr_set */
1832   0,                                              /* tp_dictoffset */
1833   0,                                              /* tp_init */
1834   0,                                              /* tp_alloc */
1835 };
1836