xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/guile/scm-breakpoint.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /* Scheme interface to breakpoints.
2 
3    Copyright (C) 2008-2019 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 /* See README file in this directory for implementation notes, coding
21    conventions, et.al.  */
22 
23 #include "defs.h"
24 #include "value.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 "guile-internal.h"
34 #include "location.h"
35 
36 /* The <gdb:breakpoint> smob.
37    N.B.: The name of this struct is known to breakpoint.h.
38 
39    Note: Breakpoints are added to gdb using a two step process:
40    1) Call make-breakpoint to create a <gdb:breakpoint> object.
41    2) Call register-breakpoint! to add the breakpoint to gdb.
42    It is done this way so that the constructor, make-breakpoint, doesn't have
43    any side-effects.  This means that the smob needs to store everything
44    that was passed to make-breakpoint.  */
45 
46 typedef struct gdbscm_breakpoint_object
47 {
48   /* This always appears first.  */
49   gdb_smob base;
50 
51   /* Non-zero if this breakpoint was created with make-breakpoint.  */
52   int is_scheme_bkpt;
53 
54   /* For breakpoints created with make-breakpoint, these are the parameters
55      that were passed to make-breakpoint.  These values are not used except
56      to register the breakpoint with GDB.  */
57   struct
58   {
59     /* The string representation of the breakpoint.
60        Space for this lives in GC space.  */
61     char *location;
62 
63     /* The kind of breakpoint.
64        At the moment this can only be one of bp_breakpoint, bp_watchpoint.  */
65     enum bptype type;
66 
67     /* If a watchpoint, the kind of watchpoint.  */
68     enum target_hw_bp_type access_type;
69 
70     /* Non-zero if the breakpoint is an "internal" breakpoint.  */
71     int is_internal;
72   } spec;
73 
74   /* The breakpoint number according to gdb.
75      For breakpoints created from Scheme, this has the value -1 until the
76      breakpoint is registered with gdb.
77      This is recorded here because BP will be NULL when deleted.  */
78   int number;
79 
80   /* The gdb breakpoint object, or NULL if the breakpoint has not been
81      registered yet, or has been deleted.  */
82   struct breakpoint *bp;
83 
84   /* Backlink to our containing <gdb:breakpoint> smob.
85      This is needed when we are deleted, we need to unprotect the object
86      from GC.  */
87   SCM containing_scm;
88 
89   /* A stop condition or #f.  */
90   SCM stop;
91 } breakpoint_smob;
92 
93 static const char breakpoint_smob_name[] = "gdb:breakpoint";
94 
95 /* The tag Guile knows the breakpoint smob by.  */
96 static scm_t_bits breakpoint_smob_tag;
97 
98 /* Variables used to pass information between the breakpoint_smob
99    constructor and the breakpoint-created hook function.  */
100 static SCM pending_breakpoint_scm = SCM_BOOL_F;
101 
102 /* Keywords used by create-breakpoint!.  */
103 static SCM type_keyword;
104 static SCM wp_class_keyword;
105 static SCM internal_keyword;
106 
107 /* Administrivia for breakpoint smobs.  */
108 
109 /* The smob "free" function for <gdb:breakpoint>.  */
110 
111 static size_t
112 bpscm_free_breakpoint_smob (SCM self)
113 {
114   breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (self);
115 
116   if (bp_smob->bp)
117     bp_smob->bp->scm_bp_object = NULL;
118 
119   /* Not necessary, done to catch bugs.  */
120   bp_smob->bp = NULL;
121   bp_smob->containing_scm = SCM_UNDEFINED;
122   bp_smob->stop = SCM_UNDEFINED;
123 
124   return 0;
125 }
126 
127 /* Return the name of TYPE.
128    This doesn't handle all types, just the ones we export.  */
129 
130 static const char *
131 bpscm_type_to_string (enum bptype type)
132 {
133   switch (type)
134     {
135     case bp_none: return "BP_NONE";
136     case bp_breakpoint: return "BP_BREAKPOINT";
137     case bp_watchpoint: return "BP_WATCHPOINT";
138     case bp_hardware_watchpoint: return "BP_HARDWARE_WATCHPOINT";
139     case bp_read_watchpoint: return "BP_READ_WATCHPOINT";
140     case bp_access_watchpoint: return "BP_ACCESS_WATCHPOINT";
141     default: return "internal/other";
142     }
143 }
144 
145 /* Return the name of ENABLE_STATE.  */
146 
147 static const char *
148 bpscm_enable_state_to_string (enum enable_state enable_state)
149 {
150   switch (enable_state)
151     {
152     case bp_disabled: return "disabled";
153     case bp_enabled: return "enabled";
154     case bp_call_disabled: return "call_disabled";
155     default: return "unknown";
156     }
157 }
158 
159 /* The smob "print" function for <gdb:breakpoint>.  */
160 
161 static int
162 bpscm_print_breakpoint_smob (SCM self, SCM port, scm_print_state *pstate)
163 {
164   breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (self);
165   struct breakpoint *b = bp_smob->bp;
166 
167   gdbscm_printf (port, "#<%s", breakpoint_smob_name);
168 
169   /* Only print what we export to the user.
170      The rest are possibly internal implementation details.  */
171 
172   gdbscm_printf (port, " #%d", bp_smob->number);
173 
174   /* Careful, the breakpoint may be invalid.  */
175   if (b != NULL)
176     {
177       const char *str;
178 
179       gdbscm_printf (port, " %s %s %s",
180 		     bpscm_type_to_string (b->type),
181 		     bpscm_enable_state_to_string (b->enable_state),
182 		     b->silent ? "silent" : "noisy");
183 
184       gdbscm_printf (port, " hit:%d", b->hit_count);
185       gdbscm_printf (port, " ignore:%d", b->ignore_count);
186 
187       str = event_location_to_string (b->location.get ());
188       if (str != NULL)
189 	gdbscm_printf (port, " @%s", str);
190     }
191 
192   scm_puts (">", port);
193 
194   scm_remember_upto_here_1 (self);
195 
196   /* Non-zero means success.  */
197   return 1;
198 }
199 
200 /* Low level routine to create a <gdb:breakpoint> object.  */
201 
202 static SCM
203 bpscm_make_breakpoint_smob (void)
204 {
205   breakpoint_smob *bp_smob = (breakpoint_smob *)
206     scm_gc_malloc (sizeof (breakpoint_smob), breakpoint_smob_name);
207   SCM bp_scm;
208 
209   memset (bp_smob, 0, sizeof (*bp_smob));
210   bp_smob->number = -1;
211   bp_smob->stop = SCM_BOOL_F;
212   bp_scm = scm_new_smob (breakpoint_smob_tag, (scm_t_bits) bp_smob);
213   bp_smob->containing_scm = bp_scm;
214   gdbscm_init_gsmob (&bp_smob->base);
215 
216   return bp_scm;
217 }
218 
219 /* Return non-zero if we want a Scheme wrapper for breakpoint B.
220    If FROM_SCHEME is non-zero,this is called for a breakpoint created
221    by the user from Scheme.  Otherwise it is zero.  */
222 
223 static int
224 bpscm_want_scm_wrapper_p (struct breakpoint *bp, int from_scheme)
225 {
226   /* Don't create <gdb:breakpoint> objects for internal GDB breakpoints.  */
227   if (bp->number < 0 && !from_scheme)
228     return 0;
229 
230   /* The others are not supported.  */
231   if (bp->type != bp_breakpoint
232       && bp->type != bp_watchpoint
233       && bp->type != bp_hardware_watchpoint
234       && bp->type != bp_read_watchpoint
235       && bp->type != bp_access_watchpoint)
236     return 0;
237 
238   return 1;
239 }
240 
241 /* Install the Scheme side of a breakpoint, CONTAINING_SCM, in
242    the gdb side BP.  */
243 
244 static void
245 bpscm_attach_scm_to_breakpoint (struct breakpoint *bp, SCM containing_scm)
246 {
247   breakpoint_smob *bp_smob;
248 
249   bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (containing_scm);
250   bp_smob->number = bp->number;
251   bp_smob->bp = bp;
252   bp_smob->containing_scm = containing_scm;
253   bp_smob->bp->scm_bp_object = bp_smob;
254 
255   /* The owner of this breakpoint is not in GC-controlled memory, so we need
256      to protect it from GC until the breakpoint is deleted.  */
257   scm_gc_protect_object (containing_scm);
258 }
259 
260 /* Return non-zero if SCM is a breakpoint smob.  */
261 
262 static int
263 bpscm_is_breakpoint (SCM scm)
264 {
265   return SCM_SMOB_PREDICATE (breakpoint_smob_tag, scm);
266 }
267 
268 /* (breakpoint? scm) -> boolean */
269 
270 static SCM
271 gdbscm_breakpoint_p (SCM scm)
272 {
273   return scm_from_bool (bpscm_is_breakpoint (scm));
274 }
275 
276 /* Returns the <gdb:breakpoint> object in SELF.
277    Throws an exception if SELF is not a <gdb:breakpoint> object.  */
278 
279 static SCM
280 bpscm_get_breakpoint_arg_unsafe (SCM self, int arg_pos, const char *func_name)
281 {
282   SCM_ASSERT_TYPE (bpscm_is_breakpoint (self), self, arg_pos, func_name,
283 		   breakpoint_smob_name);
284 
285   return self;
286 }
287 
288 /* Returns a pointer to the breakpoint smob of SELF.
289    Throws an exception if SELF is not a <gdb:breakpoint> object.  */
290 
291 static breakpoint_smob *
292 bpscm_get_breakpoint_smob_arg_unsafe (SCM self, int arg_pos,
293 				      const char *func_name)
294 {
295   SCM bp_scm = bpscm_get_breakpoint_arg_unsafe (self, arg_pos, func_name);
296   breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (bp_scm);
297 
298   return bp_smob;
299 }
300 
301 /* Return non-zero if breakpoint BP_SMOB is valid.  */
302 
303 static int
304 bpscm_is_valid (breakpoint_smob *bp_smob)
305 {
306   return bp_smob->bp != NULL;
307 }
308 
309 /* Returns the breakpoint smob in SELF, verifying it's valid.
310    Throws an exception if SELF is not a <gdb:breakpoint> object,
311    or is invalid.  */
312 
313 static breakpoint_smob *
314 bpscm_get_valid_breakpoint_smob_arg_unsafe (SCM self, int arg_pos,
315 					    const char *func_name)
316 {
317   breakpoint_smob *bp_smob
318     = bpscm_get_breakpoint_smob_arg_unsafe (self, arg_pos, func_name);
319 
320   if (!bpscm_is_valid (bp_smob))
321     {
322       gdbscm_invalid_object_error (func_name, arg_pos, self,
323 				   _("<gdb:breakpoint>"));
324     }
325 
326   return bp_smob;
327 }
328 
329 /* Breakpoint methods.  */
330 
331 /* (make-breakpoint string [#:type integer] [#:wp-class integer]
332     [#:internal boolean) -> <gdb:breakpoint>
333 
334    The result is the <gdb:breakpoint> Scheme object.
335    The breakpoint is not available to be used yet, however.
336    It must still be added to gdb with register-breakpoint!.  */
337 
338 static SCM
339 gdbscm_make_breakpoint (SCM location_scm, SCM rest)
340 {
341   const SCM keywords[] = {
342     type_keyword, wp_class_keyword, internal_keyword, SCM_BOOL_F
343   };
344   char *s;
345   char *location;
346   int type_arg_pos = -1, access_type_arg_pos = -1, internal_arg_pos = -1;
347   enum bptype type = bp_breakpoint;
348   enum target_hw_bp_type access_type = hw_write;
349   int internal = 0;
350   SCM result;
351   breakpoint_smob *bp_smob;
352 
353   gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "s#iit",
354 			      location_scm, &location, rest,
355 			      &type_arg_pos, &type,
356 			      &access_type_arg_pos, &access_type,
357 			      &internal_arg_pos, &internal);
358 
359   result = bpscm_make_breakpoint_smob ();
360   bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (result);
361 
362   s = location;
363   location = gdbscm_gc_xstrdup (s);
364   xfree (s);
365 
366   switch (type)
367     {
368     case bp_breakpoint:
369       if (access_type_arg_pos > 0)
370 	{
371 	  gdbscm_misc_error (FUNC_NAME, access_type_arg_pos,
372 			     scm_from_int (access_type),
373 			     _("access type with breakpoint is not allowed"));
374 	}
375       break;
376     case bp_watchpoint:
377       switch (access_type)
378 	{
379 	case hw_write:
380 	case hw_access:
381 	case hw_read:
382 	  break;
383 	default:
384 	  gdbscm_out_of_range_error (FUNC_NAME, access_type_arg_pos,
385 				     scm_from_int (access_type),
386 				     _("invalid watchpoint class"));
387 	}
388       break;
389     default:
390       gdbscm_out_of_range_error (FUNC_NAME, access_type_arg_pos,
391 				 scm_from_int (type),
392 				 _("invalid breakpoint type"));
393     }
394 
395   bp_smob->is_scheme_bkpt = 1;
396   bp_smob->spec.location = location;
397   bp_smob->spec.type = type;
398   bp_smob->spec.access_type = access_type;
399   bp_smob->spec.is_internal = internal;
400 
401   return result;
402 }
403 
404 /* (register-breakpoint! <gdb:breakpoint>) -> unspecified
405 
406    It is an error to register a breakpoint created outside of Guile,
407    or an already-registered breakpoint.  */
408 
409 static SCM
410 gdbscm_register_breakpoint_x (SCM self)
411 {
412   breakpoint_smob *bp_smob
413     = bpscm_get_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
414   struct gdb_exception except = exception_none;
415   const char *location, *copy;
416 
417   /* We only support registering breakpoints created with make-breakpoint.  */
418   if (!bp_smob->is_scheme_bkpt)
419     scm_misc_error (FUNC_NAME, _("not a Scheme breakpoint"), SCM_EOL);
420 
421   if (bpscm_is_valid (bp_smob))
422     scm_misc_error (FUNC_NAME, _("breakpoint is already registered"), SCM_EOL);
423 
424   pending_breakpoint_scm = self;
425   location = bp_smob->spec.location;
426   copy = skip_spaces (location);
427   event_location_up eloc
428     = string_to_event_location_basic (&copy,
429 				      current_language,
430 				      symbol_name_match_type::WILD);
431 
432   TRY
433     {
434       int internal = bp_smob->spec.is_internal;
435 
436       switch (bp_smob->spec.type)
437 	{
438 	case bp_breakpoint:
439 	  {
440 	    create_breakpoint (get_current_arch (),
441 			       eloc.get (), NULL, -1, NULL,
442 			       0,
443 			       0, bp_breakpoint,
444 			       0,
445 			       AUTO_BOOLEAN_TRUE,
446 			       &bkpt_breakpoint_ops,
447 			       0, 1, internal, 0);
448 	    break;
449 	  }
450 	case bp_watchpoint:
451 	  {
452 	    enum target_hw_bp_type access_type = bp_smob->spec.access_type;
453 
454 	    if (access_type == hw_write)
455 	      watch_command_wrapper (location, 0, internal);
456 	    else if (access_type == hw_access)
457 	      awatch_command_wrapper (location, 0, internal);
458 	    else if (access_type == hw_read)
459 	      rwatch_command_wrapper (location, 0, internal);
460 	    else
461 	      gdb_assert_not_reached ("invalid access type");
462 	    break;
463 	  }
464 	default:
465 	  gdb_assert_not_reached ("invalid breakpoint type");
466 	}
467     }
468   CATCH (ex, RETURN_MASK_ALL)
469     {
470       except = ex;
471     }
472   END_CATCH
473 
474   /* Ensure this gets reset, even if there's an error.  */
475   pending_breakpoint_scm = SCM_BOOL_F;
476   GDBSCM_HANDLE_GDB_EXCEPTION (except);
477 
478   return SCM_UNSPECIFIED;
479 }
480 
481 /* (delete-breakpoint! <gdb:breakpoint>) -> unspecified
482    Scheme function which deletes (removes) the underlying GDB breakpoint
483    from GDB's list of breakpoints.  This triggers the breakpoint_deleted
484    observer which will call gdbscm_breakpoint_deleted; that function cleans
485    up the Scheme bits.  */
486 
487 static SCM
488 gdbscm_delete_breakpoint_x (SCM self)
489 {
490   breakpoint_smob *bp_smob
491     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
492 
493   TRY
494     {
495       delete_breakpoint (bp_smob->bp);
496     }
497   CATCH (except, RETURN_MASK_ALL)
498     {
499       GDBSCM_HANDLE_GDB_EXCEPTION (except);
500     }
501   END_CATCH
502 
503   return SCM_UNSPECIFIED;
504 }
505 
506 /* iterate_over_breakpoints function for gdbscm_breakpoints.  */
507 
508 static int
509 bpscm_build_bp_list (struct breakpoint *bp, void *arg)
510 {
511   SCM *list = (SCM *) arg;
512   breakpoint_smob *bp_smob = bp->scm_bp_object;
513 
514   /* Lazily create wrappers for breakpoints created outside Scheme.  */
515 
516   if (bp_smob == NULL)
517     {
518       if (bpscm_want_scm_wrapper_p (bp, 0))
519 	{
520 	  SCM bp_scm;
521 
522 	  bp_scm = bpscm_make_breakpoint_smob ();
523 	  bpscm_attach_scm_to_breakpoint (bp, bp_scm);
524 	  /* Refetch it.  */
525 	  bp_smob = bp->scm_bp_object;
526 	}
527     }
528 
529   /* Not all breakpoints will have a companion Scheme object.
530      Only breakpoints that trigger the created_breakpoint observer call,
531      and satisfy certain conditions (see bpscm_want_scm_wrapper_p),
532      get a companion object (this includes Scheme-created breakpoints).  */
533 
534   if (bp_smob != NULL)
535     *list = scm_cons (bp_smob->containing_scm, *list);
536 
537   return 0;
538 }
539 
540 /* (breakpoints) -> list
541    Return a list of all breakpoints.  */
542 
543 static SCM
544 gdbscm_breakpoints (void)
545 {
546   SCM list = SCM_EOL;
547 
548   /* If iterate_over_breakpoints returns non-NULL it means the iteration
549      terminated early.
550      In that case abandon building the list and return #f.  */
551   if (iterate_over_breakpoints (bpscm_build_bp_list, &list) != NULL)
552     return SCM_BOOL_F;
553 
554   return scm_reverse_x (list, SCM_EOL);
555 }
556 
557 /* (breakpoint-valid? <gdb:breakpoint>) -> boolean
558    Returns #t if SELF is still valid.  */
559 
560 static SCM
561 gdbscm_breakpoint_valid_p (SCM self)
562 {
563   breakpoint_smob *bp_smob
564     = bpscm_get_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
565 
566   return scm_from_bool (bpscm_is_valid (bp_smob));
567 }
568 
569 /* (breakpoint-enabled? <gdb:breakpoint>) -> boolean */
570 
571 static SCM
572 gdbscm_breakpoint_enabled_p (SCM self)
573 {
574   breakpoint_smob *bp_smob
575     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
576 
577   return scm_from_bool (bp_smob->bp->enable_state == bp_enabled);
578 }
579 
580 /* (set-breakpoint-enabled? <gdb:breakpoint> boolean) -> unspecified */
581 
582 static SCM
583 gdbscm_set_breakpoint_enabled_x (SCM self, SCM newvalue)
584 {
585   breakpoint_smob *bp_smob
586     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
587 
588   SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue), newvalue, SCM_ARG2, FUNC_NAME,
589 		   _("boolean"));
590 
591   TRY
592     {
593       if (gdbscm_is_true (newvalue))
594 	enable_breakpoint (bp_smob->bp);
595       else
596 	disable_breakpoint (bp_smob->bp);
597     }
598   CATCH (except, RETURN_MASK_ALL)
599     {
600       GDBSCM_HANDLE_GDB_EXCEPTION (except);
601     }
602   END_CATCH
603 
604   return SCM_UNSPECIFIED;
605 }
606 
607 /* (breakpoint-silent? <gdb:breakpoint>) -> boolean */
608 
609 static SCM
610 gdbscm_breakpoint_silent_p (SCM self)
611 {
612   breakpoint_smob *bp_smob
613     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
614 
615   return scm_from_bool (bp_smob->bp->silent);
616 }
617 
618 /* (set-breakpoint-silent?! <gdb:breakpoint> boolean) -> unspecified */
619 
620 static SCM
621 gdbscm_set_breakpoint_silent_x (SCM self, SCM newvalue)
622 {
623   breakpoint_smob *bp_smob
624     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
625 
626   SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue), newvalue, SCM_ARG2, FUNC_NAME,
627 		   _("boolean"));
628 
629   TRY
630     {
631       breakpoint_set_silent (bp_smob->bp, gdbscm_is_true (newvalue));
632     }
633   CATCH (except, RETURN_MASK_ALL)
634     {
635       GDBSCM_HANDLE_GDB_EXCEPTION (except);
636     }
637   END_CATCH
638 
639   return SCM_UNSPECIFIED;
640 }
641 
642 /* (breakpoint-ignore-count <gdb:breakpoint>) -> integer */
643 
644 static SCM
645 gdbscm_breakpoint_ignore_count (SCM self)
646 {
647   breakpoint_smob *bp_smob
648     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
649 
650   return scm_from_long (bp_smob->bp->ignore_count);
651 }
652 
653 /* (set-breakpoint-ignore-count! <gdb:breakpoint> integer)
654      -> unspecified */
655 
656 static SCM
657 gdbscm_set_breakpoint_ignore_count_x (SCM self, SCM newvalue)
658 {
659   breakpoint_smob *bp_smob
660     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
661   long value;
662 
663   SCM_ASSERT_TYPE (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX),
664 		   newvalue, SCM_ARG2, FUNC_NAME, _("integer"));
665 
666   value = scm_to_long (newvalue);
667   if (value < 0)
668     value = 0;
669 
670   TRY
671     {
672       set_ignore_count (bp_smob->number, (int) value, 0);
673     }
674   CATCH (except, RETURN_MASK_ALL)
675     {
676       GDBSCM_HANDLE_GDB_EXCEPTION (except);
677     }
678   END_CATCH
679 
680   return SCM_UNSPECIFIED;
681 }
682 
683 /* (breakpoint-hit-count <gdb:breakpoint>) -> integer */
684 
685 static SCM
686 gdbscm_breakpoint_hit_count (SCM self)
687 {
688   breakpoint_smob *bp_smob
689     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
690 
691   return scm_from_long (bp_smob->bp->hit_count);
692 }
693 
694 /* (set-breakpoint-hit-count! <gdb:breakpoint> integer) -> unspecified */
695 
696 static SCM
697 gdbscm_set_breakpoint_hit_count_x (SCM self, SCM newvalue)
698 {
699   breakpoint_smob *bp_smob
700     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
701   long value;
702 
703   SCM_ASSERT_TYPE (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX),
704 		   newvalue, SCM_ARG2, FUNC_NAME, _("integer"));
705 
706   value = scm_to_long (newvalue);
707   if (value < 0)
708     value = 0;
709 
710   if (value != 0)
711     {
712       gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
713 				 _("hit-count must be zero"));
714     }
715 
716   bp_smob->bp->hit_count = 0;
717 
718   return SCM_UNSPECIFIED;
719 }
720 
721 /* (breakpoint-thread <gdb:breakpoint>) -> integer */
722 
723 static SCM
724 gdbscm_breakpoint_thread (SCM self)
725 {
726   breakpoint_smob *bp_smob
727     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
728 
729   if (bp_smob->bp->thread == -1)
730     return SCM_BOOL_F;
731 
732   return scm_from_long (bp_smob->bp->thread);
733 }
734 
735 /* (set-breakpoint-thread! <gdb:breakpoint> integer) -> unspecified */
736 
737 static SCM
738 gdbscm_set_breakpoint_thread_x (SCM self, SCM newvalue)
739 {
740   breakpoint_smob *bp_smob
741     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
742   long id;
743 
744   if (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX))
745     {
746       id = scm_to_long (newvalue);
747       if (!valid_global_thread_id (id))
748 	{
749 	  gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
750 				     _("invalid thread id"));
751 	}
752     }
753   else if (gdbscm_is_false (newvalue))
754     id = -1;
755   else
756     SCM_ASSERT_TYPE (0, newvalue, SCM_ARG2, FUNC_NAME, _("integer or #f"));
757 
758   breakpoint_set_thread (bp_smob->bp, id);
759 
760   return SCM_UNSPECIFIED;
761 }
762 
763 /* (breakpoint-task <gdb:breakpoint>) -> integer */
764 
765 static SCM
766 gdbscm_breakpoint_task (SCM self)
767 {
768   breakpoint_smob *bp_smob
769     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
770 
771   if (bp_smob->bp->task == 0)
772     return SCM_BOOL_F;
773 
774   return scm_from_long (bp_smob->bp->task);
775 }
776 
777 /* (set-breakpoint-task! <gdb:breakpoint> integer) -> unspecified */
778 
779 static SCM
780 gdbscm_set_breakpoint_task_x (SCM self, SCM newvalue)
781 {
782   breakpoint_smob *bp_smob
783     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
784   long id;
785   int valid_id = 0;
786 
787   if (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX))
788     {
789       id = scm_to_long (newvalue);
790 
791       TRY
792 	{
793 	  valid_id = valid_task_id (id);
794 	}
795       CATCH (except, RETURN_MASK_ALL)
796 	{
797 	  GDBSCM_HANDLE_GDB_EXCEPTION (except);
798 	}
799       END_CATCH
800 
801       if (! valid_id)
802 	{
803 	  gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
804 				     _("invalid task id"));
805 	}
806     }
807   else if (gdbscm_is_false (newvalue))
808     id = 0;
809   else
810     SCM_ASSERT_TYPE (0, newvalue, SCM_ARG2, FUNC_NAME, _("integer or #f"));
811 
812   TRY
813     {
814       breakpoint_set_task (bp_smob->bp, id);
815     }
816   CATCH (except, RETURN_MASK_ALL)
817     {
818       GDBSCM_HANDLE_GDB_EXCEPTION (except);
819     }
820   END_CATCH
821 
822   return SCM_UNSPECIFIED;
823 }
824 
825 /* (breakpoint-location <gdb:breakpoint>) -> string */
826 
827 static SCM
828 gdbscm_breakpoint_location (SCM self)
829 {
830   breakpoint_smob *bp_smob
831     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
832   const char *str;
833 
834   if (bp_smob->bp->type != bp_breakpoint)
835     return SCM_BOOL_F;
836 
837   str = event_location_to_string (bp_smob->bp->location.get ());
838   if (! str)
839     str = "";
840 
841   return gdbscm_scm_from_c_string (str);
842 }
843 
844 /* (breakpoint-expression <gdb:breakpoint>) -> string
845    This is only valid for watchpoints.
846    Returns #f for non-watchpoints.  */
847 
848 static SCM
849 gdbscm_breakpoint_expression (SCM self)
850 {
851   breakpoint_smob *bp_smob
852     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
853   struct watchpoint *wp;
854 
855   if (!is_watchpoint (bp_smob->bp))
856     return SCM_BOOL_F;
857 
858   wp = (struct watchpoint *) bp_smob->bp;
859 
860   const char *str = wp->exp_string;
861   if (! str)
862     str = "";
863 
864   return gdbscm_scm_from_c_string (str);
865 }
866 
867 /* (breakpoint-condition <gdb:breakpoint>) -> string */
868 
869 static SCM
870 gdbscm_breakpoint_condition (SCM self)
871 {
872   breakpoint_smob *bp_smob
873     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
874   char *str;
875 
876   str = bp_smob->bp->cond_string;
877   if (! str)
878     return SCM_BOOL_F;
879 
880   return gdbscm_scm_from_c_string (str);
881 }
882 
883 /* (set-breakpoint-condition! <gdb:breakpoint> string|#f)
884    -> unspecified */
885 
886 static SCM
887 gdbscm_set_breakpoint_condition_x (SCM self, SCM newvalue)
888 {
889   breakpoint_smob *bp_smob
890     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
891 
892   SCM_ASSERT_TYPE (scm_is_string (newvalue) || gdbscm_is_false (newvalue),
893 		   newvalue, SCM_ARG2, FUNC_NAME,
894 		   _("string or #f"));
895 
896   return gdbscm_wrap ([=]
897     {
898       gdb::unique_xmalloc_ptr<char> exp
899 	= (gdbscm_is_false (newvalue)
900 	   ? nullptr
901 	   : gdbscm_scm_to_c_string (newvalue));
902 
903       set_breakpoint_condition (bp_smob->bp, exp ? exp.get () : "", 0);
904 
905       return SCM_UNSPECIFIED;
906     });
907 }
908 
909 /* (breakpoint-stop <gdb:breakpoint>) -> procedure or #f */
910 
911 static SCM
912 gdbscm_breakpoint_stop (SCM self)
913 {
914   breakpoint_smob *bp_smob
915     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
916 
917   return bp_smob->stop;
918 }
919 
920 /* (set-breakpoint-stop! <gdb:breakpoint> procedure|#f)
921    -> unspecified */
922 
923 static SCM
924 gdbscm_set_breakpoint_stop_x (SCM self, SCM newvalue)
925 {
926   breakpoint_smob *bp_smob
927     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
928   const struct extension_language_defn *extlang = NULL;
929 
930   SCM_ASSERT_TYPE (gdbscm_is_procedure (newvalue)
931 		   || gdbscm_is_false (newvalue),
932 		   newvalue, SCM_ARG2, FUNC_NAME,
933 		   _("procedure or #f"));
934 
935   if (bp_smob->bp->cond_string != NULL)
936     extlang = get_ext_lang_defn (EXT_LANG_GDB);
937   if (extlang == NULL)
938     extlang = get_breakpoint_cond_ext_lang (bp_smob->bp, EXT_LANG_GUILE);
939   if (extlang != NULL)
940     {
941       char *error_text
942 	= xstrprintf (_("Only one stop condition allowed.  There is"
943 			" currently a %s stop condition defined for"
944 			" this breakpoint."),
945 		      ext_lang_capitalized_name (extlang));
946 
947       scm_dynwind_begin ((scm_t_dynwind_flags) 0);
948       gdbscm_dynwind_xfree (error_text);
949       gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self, error_text);
950       /* The following line, while unnecessary, is present for completeness
951 	 sake.  */
952       scm_dynwind_end ();
953     }
954 
955   bp_smob->stop = newvalue;
956 
957   return SCM_UNSPECIFIED;
958 }
959 
960 /* (breakpoint-commands <gdb:breakpoint>) -> string */
961 
962 static SCM
963 gdbscm_breakpoint_commands (SCM self)
964 {
965   breakpoint_smob *bp_smob
966     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
967   struct breakpoint *bp;
968   SCM result;
969 
970   bp = bp_smob->bp;
971 
972   if (bp->commands == NULL)
973     return SCM_BOOL_F;
974 
975   string_file buf;
976 
977   current_uiout->redirect (&buf);
978   TRY
979     {
980       print_command_lines (current_uiout, breakpoint_commands (bp), 0);
981     }
982   CATCH (except, RETURN_MASK_ALL)
983     {
984       current_uiout->redirect (NULL);
985       gdbscm_throw_gdb_exception (except);
986     }
987   END_CATCH
988 
989   current_uiout->redirect (NULL);
990   result = gdbscm_scm_from_c_string (buf.c_str ());
991 
992   return result;
993 }
994 
995 /* (breakpoint-type <gdb:breakpoint>) -> integer */
996 
997 static SCM
998 gdbscm_breakpoint_type (SCM self)
999 {
1000   breakpoint_smob *bp_smob
1001     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
1002 
1003   return scm_from_long (bp_smob->bp->type);
1004 }
1005 
1006 /* (breakpoint-visible? <gdb:breakpoint>) -> boolean */
1007 
1008 static SCM
1009 gdbscm_breakpoint_visible (SCM self)
1010 {
1011   breakpoint_smob *bp_smob
1012     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
1013 
1014   return scm_from_bool (bp_smob->bp->number >= 0);
1015 }
1016 
1017 /* (breakpoint-number <gdb:breakpoint>) -> integer */
1018 
1019 static SCM
1020 gdbscm_breakpoint_number (SCM self)
1021 {
1022   breakpoint_smob *bp_smob
1023     = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
1024 
1025   return scm_from_long (bp_smob->number);
1026 }
1027 
1028 /* Return TRUE if "stop" has been set for this breakpoint.
1029 
1030    This is the extension_language_ops.breakpoint_has_cond "method".  */
1031 
1032 int
1033 gdbscm_breakpoint_has_cond (const struct extension_language_defn *extlang,
1034 			    struct breakpoint *b)
1035 {
1036   breakpoint_smob *bp_smob = b->scm_bp_object;
1037 
1038   if (bp_smob == NULL)
1039     return 0;
1040 
1041   return gdbscm_is_procedure (bp_smob->stop);
1042 }
1043 
1044 /* Call the "stop" method in the breakpoint class.
1045    This must only be called if gdbscm_breakpoint_has_cond returns true.
1046    If the stop method returns #t, the inferior will be stopped at the
1047    breakpoint.  Otherwise the inferior will be allowed to continue
1048    (assuming other conditions don't indicate "stop").
1049 
1050    This is the extension_language_ops.breakpoint_cond_says_stop "method".  */
1051 
1052 enum ext_lang_bp_stop
1053 gdbscm_breakpoint_cond_says_stop
1054   (const struct extension_language_defn *extlang, struct breakpoint *b)
1055 {
1056   breakpoint_smob *bp_smob = b->scm_bp_object;
1057   SCM predicate_result;
1058   int stop;
1059 
1060   if (bp_smob == NULL)
1061     return EXT_LANG_BP_STOP_UNSET;
1062   if (!gdbscm_is_procedure (bp_smob->stop))
1063     return EXT_LANG_BP_STOP_UNSET;
1064 
1065   stop = 1;
1066 
1067   predicate_result
1068     = gdbscm_safe_call_1 (bp_smob->stop, bp_smob->containing_scm, NULL);
1069 
1070   if (gdbscm_is_exception (predicate_result))
1071     ; /* Exception already printed.  */
1072   /* If the "stop" function returns #f that means
1073      the Scheme breakpoint wants GDB to continue.  */
1074   else if (gdbscm_is_false (predicate_result))
1075     stop = 0;
1076 
1077   return stop ? EXT_LANG_BP_STOP_YES : EXT_LANG_BP_STOP_NO;
1078 }
1079 
1080 /* Event callback functions.  */
1081 
1082 /* Callback that is used when a breakpoint is created.
1083    For breakpoints created by Scheme, i.e., gdbscm_create_breakpoint_x, finish
1084    object creation by connecting the Scheme wrapper to the gdb object.
1085    We ignore breakpoints created from gdb or python here, we create the
1086    Scheme wrapper for those when there's a need to, e.g.,
1087    gdbscm_breakpoints.  */
1088 
1089 static void
1090 bpscm_breakpoint_created (struct breakpoint *bp)
1091 {
1092   SCM bp_scm;
1093 
1094   if (gdbscm_is_false (pending_breakpoint_scm))
1095     return;
1096 
1097   /* Verify our caller error checked the user's request.  */
1098   gdb_assert (bpscm_want_scm_wrapper_p (bp, 1));
1099 
1100   bp_scm = pending_breakpoint_scm;
1101   pending_breakpoint_scm = SCM_BOOL_F;
1102 
1103   bpscm_attach_scm_to_breakpoint (bp, bp_scm);
1104 }
1105 
1106 /* Callback that is used when a breakpoint is deleted.  This will
1107    invalidate the corresponding Scheme object.  */
1108 
1109 static void
1110 bpscm_breakpoint_deleted (struct breakpoint *b)
1111 {
1112   int num = b->number;
1113   struct breakpoint *bp;
1114 
1115   /* TODO: Why the lookup?  We have B.  */
1116 
1117   bp = get_breakpoint (num);
1118   if (bp)
1119     {
1120       breakpoint_smob *bp_smob = bp->scm_bp_object;
1121 
1122       if (bp_smob)
1123 	{
1124 	  bp_smob->bp = NULL;
1125 	  bp_smob->number = -1;
1126 	  bp_smob->stop = SCM_BOOL_F;
1127 	  scm_gc_unprotect_object (bp_smob->containing_scm);
1128 	}
1129     }
1130 }
1131 
1132 /* Initialize the Scheme breakpoint code.  */
1133 
1134 static const scheme_integer_constant breakpoint_integer_constants[] =
1135 {
1136   { "BP_NONE", bp_none },
1137   { "BP_BREAKPOINT", bp_breakpoint },
1138   { "BP_WATCHPOINT", bp_watchpoint },
1139   { "BP_HARDWARE_WATCHPOINT", bp_hardware_watchpoint },
1140   { "BP_READ_WATCHPOINT", bp_read_watchpoint },
1141   { "BP_ACCESS_WATCHPOINT", bp_access_watchpoint },
1142 
1143   { "WP_READ", hw_read },
1144   { "WP_WRITE", hw_write },
1145   { "WP_ACCESS", hw_access },
1146 
1147   END_INTEGER_CONSTANTS
1148 };
1149 
1150 static const scheme_function breakpoint_functions[] =
1151 {
1152   { "make-breakpoint", 1, 0, 1, as_a_scm_t_subr (gdbscm_make_breakpoint),
1153     "\
1154 Create a GDB breakpoint object.\n\
1155 \n\
1156   Arguments:\n\
1157     location [#:type <type>] [#:wp-class <wp-class>] [#:internal <bool>]\n\
1158   Returns:\n\
1159     <gdb:breakpoint object" },
1160 
1161   { "register-breakpoint!", 1, 0, 0,
1162     as_a_scm_t_subr (gdbscm_register_breakpoint_x),
1163     "\
1164 Register a <gdb:breakpoint> object with GDB." },
1165 
1166   { "delete-breakpoint!", 1, 0, 0, as_a_scm_t_subr (gdbscm_delete_breakpoint_x),
1167     "\
1168 Delete the breakpoint from GDB." },
1169 
1170   { "breakpoints", 0, 0, 0, as_a_scm_t_subr (gdbscm_breakpoints),
1171     "\
1172 Return a list of all GDB breakpoints.\n\
1173 \n\
1174   Arguments: none" },
1175 
1176   { "breakpoint?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_p),
1177     "\
1178 Return #t if the object is a <gdb:breakpoint> object." },
1179 
1180   { "breakpoint-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_valid_p),
1181     "\
1182 Return #t if the breakpoint has not been deleted from GDB." },
1183 
1184   { "breakpoint-number", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_number),
1185     "\
1186 Return the breakpoint's number." },
1187 
1188   { "breakpoint-type", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_type),
1189     "\
1190 Return the type of the breakpoint." },
1191 
1192   { "breakpoint-visible?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_visible),
1193     "\
1194 Return #t if the breakpoint is visible to the user." },
1195 
1196   { "breakpoint-location", 1, 0, 0,
1197     as_a_scm_t_subr (gdbscm_breakpoint_location),
1198     "\
1199 Return the location of the breakpoint as specified by the user." },
1200 
1201   { "breakpoint-expression", 1, 0, 0,
1202     as_a_scm_t_subr (gdbscm_breakpoint_expression),
1203     "\
1204 Return the expression of the breakpoint as specified by the user.\n\
1205 Valid for watchpoints only, returns #f for non-watchpoints." },
1206 
1207   { "breakpoint-enabled?", 1, 0, 0,
1208     as_a_scm_t_subr (gdbscm_breakpoint_enabled_p),
1209     "\
1210 Return #t if the breakpoint is enabled." },
1211 
1212   { "set-breakpoint-enabled!", 2, 0, 0,
1213     as_a_scm_t_subr (gdbscm_set_breakpoint_enabled_x),
1214     "\
1215 Set the breakpoint's enabled state.\n\
1216 \n\
1217   Arguments: <gdb:breakpoint> boolean" },
1218 
1219   { "breakpoint-silent?", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_silent_p),
1220     "\
1221 Return #t if the breakpoint is silent." },
1222 
1223   { "set-breakpoint-silent!", 2, 0, 0,
1224     as_a_scm_t_subr (gdbscm_set_breakpoint_silent_x),
1225     "\
1226 Set the breakpoint's silent state.\n\
1227 \n\
1228   Arguments: <gdb:breakpoint> boolean" },
1229 
1230   { "breakpoint-ignore-count", 1, 0, 0,
1231     as_a_scm_t_subr (gdbscm_breakpoint_ignore_count),
1232     "\
1233 Return the breakpoint's \"ignore\" count." },
1234 
1235   { "set-breakpoint-ignore-count!", 2, 0, 0,
1236     as_a_scm_t_subr (gdbscm_set_breakpoint_ignore_count_x),
1237     "\
1238 Set the breakpoint's \"ignore\" count.\n\
1239 \n\
1240   Arguments: <gdb:breakpoint> count" },
1241 
1242   { "breakpoint-hit-count", 1, 0, 0,
1243     as_a_scm_t_subr (gdbscm_breakpoint_hit_count),
1244     "\
1245 Return the breakpoint's \"hit\" count." },
1246 
1247   { "set-breakpoint-hit-count!", 2, 0, 0,
1248     as_a_scm_t_subr (gdbscm_set_breakpoint_hit_count_x),
1249     "\
1250 Set the breakpoint's \"hit\" count.  The value must be zero.\n\
1251 \n\
1252   Arguments: <gdb:breakpoint> 0" },
1253 
1254   { "breakpoint-thread", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_thread),
1255     "\
1256 Return the breakpoint's global thread id or #f if there isn't one." },
1257 
1258   { "set-breakpoint-thread!", 2, 0, 0,
1259     as_a_scm_t_subr (gdbscm_set_breakpoint_thread_x),
1260     "\
1261 Set the global thread id for this breakpoint.\n\
1262 \n\
1263   Arguments: <gdb:breakpoint> global-thread-id" },
1264 
1265   { "breakpoint-task", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_task),
1266     "\
1267 Return the breakpoint's Ada task-id or #f if there isn't one." },
1268 
1269   { "set-breakpoint-task!", 2, 0, 0,
1270     as_a_scm_t_subr (gdbscm_set_breakpoint_task_x),
1271     "\
1272 Set the breakpoint's Ada task-id.\n\
1273 \n\
1274   Arguments: <gdb:breakpoint> task-id" },
1275 
1276   { "breakpoint-condition", 1, 0, 0,
1277     as_a_scm_t_subr (gdbscm_breakpoint_condition),
1278     "\
1279 Return the breakpoint's condition as specified by the user.\n\
1280 Return #f if there isn't one." },
1281 
1282   { "set-breakpoint-condition!", 2, 0, 0,
1283     as_a_scm_t_subr (gdbscm_set_breakpoint_condition_x),
1284     "\
1285 Set the breakpoint's condition.\n\
1286 \n\
1287   Arguments: <gdb:breakpoint> condition\n\
1288     condition: a string" },
1289 
1290   { "breakpoint-stop", 1, 0, 0, as_a_scm_t_subr (gdbscm_breakpoint_stop),
1291     "\
1292 Return the breakpoint's stop predicate.\n\
1293 Return #f if there isn't one." },
1294 
1295   { "set-breakpoint-stop!", 2, 0, 0,
1296     as_a_scm_t_subr (gdbscm_set_breakpoint_stop_x),
1297     "\
1298 Set the breakpoint's stop predicate.\n\
1299 \n\
1300   Arguments: <gdb:breakpoint> procedure\n\
1301     procedure: A procedure of one argument, the breakpoint.\n\
1302       Its result is true if program execution should stop." },
1303 
1304   { "breakpoint-commands", 1, 0, 0,
1305     as_a_scm_t_subr (gdbscm_breakpoint_commands),
1306     "\
1307 Return the breakpoint's commands." },
1308 
1309   END_FUNCTIONS
1310 };
1311 
1312 void
1313 gdbscm_initialize_breakpoints (void)
1314 {
1315   breakpoint_smob_tag
1316     = gdbscm_make_smob_type (breakpoint_smob_name, sizeof (breakpoint_smob));
1317   scm_set_smob_free (breakpoint_smob_tag, bpscm_free_breakpoint_smob);
1318   scm_set_smob_print (breakpoint_smob_tag, bpscm_print_breakpoint_smob);
1319 
1320   gdb::observers::breakpoint_created.attach (bpscm_breakpoint_created);
1321   gdb::observers::breakpoint_deleted.attach (bpscm_breakpoint_deleted);
1322 
1323   gdbscm_define_integer_constants (breakpoint_integer_constants, 1);
1324   gdbscm_define_functions (breakpoint_functions, 1);
1325 
1326   type_keyword = scm_from_latin1_keyword ("type");
1327   wp_class_keyword = scm_from_latin1_keyword ("wp-class");
1328   internal_keyword = scm_from_latin1_keyword ("internal");
1329 }
1330