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