1 /* Scheme interface to breakpoints.
3 Copyright (C) 2008-2014 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
20 /* See README file in this directory for implementation notes, coding
21 conventions, et.al. */
25 #include "exceptions.h"
26 #include "breakpoint.h"
28 #include "gdbthread.h"
30 #include "cli/cli-script.h"
32 #include "arch-utils.h"
34 #include "guile-internal.h"
36 /* The <gdb:breakpoint> smob.
37 N.B.: The name of this struct is known to breakpoint.h. */
39 typedef struct gdbscm_breakpoint_object
41 /* This always appears first. */
44 /* The breakpoint number according to gdb.
45 This is recorded here because BP will be NULL when deleted. */
48 /* The gdb breakpoint object, or NULL if the breakpoint has been deleted. */
49 struct breakpoint
*bp
;
51 /* Backlink to our containing <gdb:breakpoint> smob.
52 This is needed when we are deleted, we need to unprotect the object
56 /* A stop condition or #f. */
60 static const char breakpoint_smob_name
[] = "gdb:breakpoint";
62 /* The tag Guile knows the breakpoint smob by. */
63 static scm_t_bits breakpoint_smob_tag
;
65 /* Variables used to pass information between the breakpoint_smob
66 constructor and the breakpoint-created hook function. */
67 static SCM pending_breakpoint_scm
= SCM_BOOL_F
;
69 /* Keywords used by create-breakpoint!. */
70 static SCM type_keyword
;
71 static SCM wp_class_keyword
;
72 static SCM internal_keyword
;
74 /* Administrivia for breakpoint smobs. */
76 /* The smob "mark" function for <gdb:breakpoint>. */
79 bpscm_mark_breakpoint_smob (SCM self
)
81 breakpoint_smob
*bp_smob
= (breakpoint_smob
*) SCM_SMOB_DATA (self
);
83 /* We don't mark containing_scm here. It is just a backlink to our
84 container, and is gc'protected until the breakpoint is deleted. */
86 scm_gc_mark (bp_smob
->stop
);
89 return gdbscm_mark_gsmob (&bp_smob
->base
);
92 /* The smob "free" function for <gdb:breakpoint>. */
95 bpscm_free_breakpoint_smob (SCM self
)
97 breakpoint_smob
*bp_smob
= (breakpoint_smob
*) SCM_SMOB_DATA (self
);
100 bp_smob
->bp
->scm_bp_object
= NULL
;
102 /* Not necessary, done to catch bugs. */
104 bp_smob
->containing_scm
= SCM_UNDEFINED
;
105 bp_smob
->stop
= SCM_UNDEFINED
;
110 /* Return the name of TYPE.
111 This doesn't handle all types, just the ones we export. */
114 bpscm_type_to_string (enum bptype type
)
118 case bp_none
: return "BP_NONE";
119 case bp_breakpoint
: return "BP_BREAKPOINT";
120 case bp_watchpoint
: return "BP_WATCHPOINT";
121 case bp_hardware_watchpoint
: return "BP_HARDWARE_WATCHPOINT";
122 case bp_read_watchpoint
: return "BP_READ_WATCHPOINT";
123 case bp_access_watchpoint
: return "BP_ACCESS_WATCHPOINT";
124 default: return "internal/other";
128 /* Return the name of ENABLE_STATE. */
131 bpscm_enable_state_to_string (enum enable_state enable_state
)
133 switch (enable_state
)
135 case bp_disabled
: return "disabled";
136 case bp_enabled
: return "enabled";
137 case bp_call_disabled
: return "call_disabled";
138 case bp_permanent
: return "permanent";
139 default: return "unknown";
143 /* The smob "print" function for <gdb:breakpoint>. */
146 bpscm_print_breakpoint_smob (SCM self
, SCM port
, scm_print_state
*pstate
)
148 breakpoint_smob
*bp_smob
= (breakpoint_smob
*) SCM_SMOB_DATA (self
);
149 struct breakpoint
*b
= bp_smob
->bp
;
151 gdbscm_printf (port
, "#<%s", breakpoint_smob_name
);
153 /* Only print what we export to the user.
154 The rest are possibly internal implementation details. */
156 gdbscm_printf (port
, " #%d", bp_smob
->number
);
158 /* Careful, the breakpoint may be invalid. */
161 gdbscm_printf (port
, " %s %s %s",
162 bpscm_type_to_string (b
->type
),
163 bpscm_enable_state_to_string (b
->enable_state
),
164 b
->silent
? "silent" : "noisy");
166 gdbscm_printf (port
, " hit:%d", b
->hit_count
);
167 gdbscm_printf (port
, " ignore:%d", b
->ignore_count
);
169 if (b
->addr_string
!= NULL
)
170 gdbscm_printf (port
, " @%s", b
->addr_string
);
173 scm_puts (">", port
);
175 scm_remember_upto_here_1 (self
);
177 /* Non-zero means success. */
181 /* Low level routine to create a <gdb:breakpoint> object. */
184 bpscm_make_breakpoint_smob (void)
186 breakpoint_smob
*bp_smob
= (breakpoint_smob
*)
187 scm_gc_malloc (sizeof (breakpoint_smob
), breakpoint_smob_name
);
190 bp_smob
->number
= -1;
192 bp_smob
->stop
= SCM_BOOL_F
;
193 bp_scm
= scm_new_smob (breakpoint_smob_tag
, (scm_t_bits
) bp_smob
);
194 bp_smob
->containing_scm
= bp_scm
;
195 gdbscm_init_gsmob (&bp_smob
->base
);
200 /* Return non-zero if we want a Scheme wrapper for breakpoint B.
201 If FROM_SCHEME is non-zero,this is called for a breakpoint created
202 by the user from Scheme. Otherwise it is zero. */
205 bpscm_want_scm_wrapper_p (struct breakpoint
*bp
, int from_scheme
)
207 /* Don't create <gdb:breakpoint> objects for internal GDB breakpoints. */
208 if (bp
->number
< 0 && !from_scheme
)
211 /* The others are not supported. */
212 if (bp
->type
!= bp_breakpoint
213 && bp
->type
!= bp_watchpoint
214 && bp
->type
!= bp_hardware_watchpoint
215 && bp
->type
!= bp_read_watchpoint
216 && bp
->type
!= bp_access_watchpoint
)
222 /* Install the Scheme side of a breakpoint, CONTAINING_SCM, in
226 bpscm_attach_scm_to_breakpoint (struct breakpoint
*bp
, SCM containing_scm
)
228 breakpoint_smob
*bp_smob
;
230 bp_smob
= (breakpoint_smob
*) SCM_SMOB_DATA (containing_scm
);
231 bp_smob
->number
= bp
->number
;
233 bp_smob
->containing_scm
= containing_scm
;
234 bp_smob
->bp
->scm_bp_object
= bp_smob
;
236 /* The owner of this breakpoint is not in GC-controlled memory, so we need
237 to protect it from GC until the breakpoint is deleted. */
238 scm_gc_protect_object (containing_scm
);
241 /* Return non-zero if SCM is a breakpoint smob. */
244 bpscm_is_breakpoint (SCM scm
)
246 return SCM_SMOB_PREDICATE (breakpoint_smob_tag
, scm
);
249 /* (breakpoint? scm) -> boolean */
252 gdbscm_breakpoint_p (SCM scm
)
254 return scm_from_bool (bpscm_is_breakpoint (scm
));
257 /* Returns the <gdb:breakpoint> object in SELF.
258 Throws an exception if SELF is not a <gdb:breakpoint> object. */
261 bpscm_get_breakpoint_arg_unsafe (SCM self
, int arg_pos
, const char *func_name
)
263 SCM_ASSERT_TYPE (bpscm_is_breakpoint (self
), self
, arg_pos
, func_name
,
264 breakpoint_smob_name
);
269 /* Returns a pointer to the breakpoint smob of SELF.
270 Throws an exception if SELF is not a <gdb:breakpoint> object. */
272 static breakpoint_smob
*
273 bpscm_get_breakpoint_smob_arg_unsafe (SCM self
, int arg_pos
,
274 const char *func_name
)
276 SCM bp_scm
= bpscm_get_breakpoint_arg_unsafe (self
, arg_pos
, func_name
);
277 breakpoint_smob
*bp_smob
= (breakpoint_smob
*) SCM_SMOB_DATA (bp_scm
);
282 /* Return non-zero if breakpoint BP_SMOB is valid. */
285 bpscm_is_valid (breakpoint_smob
*bp_smob
)
287 return bp_smob
->bp
!= NULL
;
290 /* Returns the breakpoint smob in SELF, verifying it's valid.
291 Throws an exception if SELF is not a <gdb:breakpoint> object,
294 static breakpoint_smob
*
295 bpscm_get_valid_breakpoint_smob_arg_unsafe (SCM self
, int arg_pos
,
296 const char *func_name
)
298 breakpoint_smob
*bp_smob
299 = bpscm_get_breakpoint_smob_arg_unsafe (self
, arg_pos
, func_name
);
301 if (!bpscm_is_valid (bp_smob
))
303 gdbscm_invalid_object_error (func_name
, arg_pos
, self
,
304 _("<gdb:breakpoint>"));
310 /* Breakpoint methods. */
312 /* (create-breakpoint! string [#:type integer] [#:wp-class integer]
313 [#:internal boolean) -> <gdb:breakpoint> */
316 gdbscm_create_breakpoint_x (SCM spec_scm
, SCM rest
)
318 const SCM keywords
[] = {
319 type_keyword
, wp_class_keyword
, internal_keyword
, SCM_BOOL_F
322 int type_arg_pos
= -1, access_type_arg_pos
= -1, internal_arg_pos
= -1;
323 int type
= bp_breakpoint
;
324 int access_type
= hw_write
;
327 volatile struct gdb_exception except
;
329 gdbscm_parse_function_args (FUNC_NAME
, SCM_ARG1
, keywords
, "s#iit",
330 spec_scm
, &spec
, rest
,
331 &type_arg_pos
, &type
,
332 &access_type_arg_pos
, &access_type
,
333 &internal_arg_pos
, &internal
);
335 result
= bpscm_make_breakpoint_smob ();
336 pending_breakpoint_scm
= result
;
338 TRY_CATCH (except
, RETURN_MASK_ALL
)
340 struct cleanup
*cleanup
= make_cleanup (xfree
, spec
);
346 create_breakpoint (get_current_arch (),
347 spec
, NULL
, -1, NULL
,
352 &bkpt_breakpoint_ops
,
358 if (access_type
== hw_write
)
359 watch_command_wrapper (spec
, 0, internal
);
360 else if (access_type
== hw_access
)
361 awatch_command_wrapper (spec
, 0, internal
);
362 else if (access_type
== hw_read
)
363 rwatch_command_wrapper (spec
, 0, internal
);
365 error (_("Invalid watchpoint access type"));
369 error (_("Invalid breakpoint type"));
372 do_cleanups (cleanup
);
374 /* Ensure this gets reset, even if there's an error. */
375 pending_breakpoint_scm
= SCM_BOOL_F
;
376 GDBSCM_HANDLE_GDB_EXCEPTION (except
);
381 /* (breakpoint-delete! <gdb:breakpoint>) -> unspecified
382 Scheme function which deletes the underlying GDB breakpoint. This
383 triggers the breakpoint_deleted observer which will call
384 gdbscm_breakpoint_deleted; that function cleans up the Scheme sections. */
387 gdbscm_breakpoint_delete_x (SCM self
)
389 breakpoint_smob
*bp_smob
390 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
391 volatile struct gdb_exception except
;
393 TRY_CATCH (except
, RETURN_MASK_ALL
)
395 delete_breakpoint (bp_smob
->bp
);
397 GDBSCM_HANDLE_GDB_EXCEPTION (except
);
399 return SCM_UNSPECIFIED
;
402 /* iterate_over_breakpoints function for gdbscm_breakpoints. */
405 bpscm_build_bp_list (struct breakpoint
*bp
, void *arg
)
408 breakpoint_smob
*bp_smob
= bp
->scm_bp_object
;
410 /* Lazily create wrappers for breakpoints created outside Scheme. */
414 if (bpscm_want_scm_wrapper_p (bp
, 0))
418 bp_scm
= bpscm_make_breakpoint_smob ();
419 bpscm_attach_scm_to_breakpoint (bp
, bp_scm
);
421 bp_smob
= bp
->scm_bp_object
;
425 /* Not all breakpoints will have a companion Scheme object.
426 Only breakpoints that trigger the created_breakpoint observer call,
427 and satisfy certain conditions (see bpscm_want_scm_wrapper_p),
428 get a companion object (this includes Scheme-created breakpoints). */
431 *list
= scm_cons (bp_smob
->containing_scm
, *list
);
436 /* (breakpoints) -> list
437 Return a list of all breakpoints. */
440 gdbscm_breakpoints (void)
444 /* If iterate_over_breakpoints returns non-NULL it means the iteration
446 In that case abandon building the list and return #f. */
447 if (iterate_over_breakpoints (bpscm_build_bp_list
, &list
) != NULL
)
450 return scm_reverse_x (list
, SCM_EOL
);
453 /* (breakpoint-valid? <gdb:breakpoint>) -> boolean
454 Returns #t if SELF is still valid. */
457 gdbscm_breakpoint_valid_p (SCM self
)
459 breakpoint_smob
*bp_smob
460 = bpscm_get_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
462 return scm_from_bool (bpscm_is_valid (bp_smob
));
465 /* (breakpoint-enabled? <gdb:breakpoint>) -> boolean */
468 gdbscm_breakpoint_enabled_p (SCM self
)
470 breakpoint_smob
*bp_smob
471 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
473 return scm_from_bool (bp_smob
->bp
->enable_state
== bp_enabled
);
476 /* (set-breakpoint-enabled? <gdb:breakpoint> boolean) -> unspecified */
479 gdbscm_set_breakpoint_enabled_x (SCM self
, SCM newvalue
)
481 breakpoint_smob
*bp_smob
482 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
483 volatile struct gdb_exception except
;
485 SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue
), newvalue
, SCM_ARG2
, FUNC_NAME
,
488 TRY_CATCH (except
, RETURN_MASK_ALL
)
490 if (gdbscm_is_true (newvalue
))
491 enable_breakpoint (bp_smob
->bp
);
493 disable_breakpoint (bp_smob
->bp
);
495 GDBSCM_HANDLE_GDB_EXCEPTION (except
);
497 return SCM_UNSPECIFIED
;
500 /* (breakpoint-silent? <gdb:breakpoint>) -> boolean */
503 gdbscm_breakpoint_silent_p (SCM self
)
505 breakpoint_smob
*bp_smob
506 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
508 return scm_from_bool (bp_smob
->bp
->silent
);
511 /* (set-breakpoint-silent?! <gdb:breakpoint> boolean) -> unspecified */
514 gdbscm_set_breakpoint_silent_x (SCM self
, SCM newvalue
)
516 breakpoint_smob
*bp_smob
517 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
518 volatile struct gdb_exception except
;
520 SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue
), newvalue
, SCM_ARG2
, FUNC_NAME
,
523 TRY_CATCH (except
, RETURN_MASK_ALL
)
525 breakpoint_set_silent (bp_smob
->bp
, gdbscm_is_true (newvalue
));
527 GDBSCM_HANDLE_GDB_EXCEPTION (except
);
529 return SCM_UNSPECIFIED
;
532 /* (breakpoint-ignore-count <gdb:breakpoint>) -> integer */
535 gdbscm_breakpoint_ignore_count (SCM self
)
537 breakpoint_smob
*bp_smob
538 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
540 return scm_from_long (bp_smob
->bp
->ignore_count
);
543 /* (set-breakpoint-ignore-count! <gdb:breakpoint> integer)
547 gdbscm_set_breakpoint_ignore_count_x (SCM self
, SCM newvalue
)
549 breakpoint_smob
*bp_smob
550 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
552 volatile struct gdb_exception except
;
554 SCM_ASSERT_TYPE (scm_is_signed_integer (newvalue
, LONG_MIN
, LONG_MAX
),
555 newvalue
, SCM_ARG2
, FUNC_NAME
, _("integer"));
557 value
= scm_to_long (newvalue
);
561 TRY_CATCH (except
, RETURN_MASK_ALL
)
563 set_ignore_count (bp_smob
->number
, (int) value
, 0);
565 GDBSCM_HANDLE_GDB_EXCEPTION (except
);
567 return SCM_UNSPECIFIED
;
570 /* (breakpoint-hit-count <gdb:breakpoint>) -> integer */
573 gdbscm_breakpoint_hit_count (SCM self
)
575 breakpoint_smob
*bp_smob
576 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
578 return scm_from_long (bp_smob
->bp
->hit_count
);
581 /* (set-breakpoint-hit-count! <gdb:breakpoint> integer) -> unspecified */
584 gdbscm_set_breakpoint_hit_count_x (SCM self
, SCM newvalue
)
586 breakpoint_smob
*bp_smob
587 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
590 SCM_ASSERT_TYPE (scm_is_signed_integer (newvalue
, LONG_MIN
, LONG_MAX
),
591 newvalue
, SCM_ARG2
, FUNC_NAME
, _("integer"));
593 value
= scm_to_long (newvalue
);
599 gdbscm_out_of_range_error (FUNC_NAME
, SCM_ARG2
, newvalue
,
600 _("hit-count must be zero"));
603 bp_smob
->bp
->hit_count
= 0;
605 return SCM_UNSPECIFIED
;
608 /* (breakpoint-thread <gdb:breakpoint>) -> integer */
611 gdbscm_breakpoint_thread (SCM self
)
613 breakpoint_smob
*bp_smob
614 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
616 if (bp_smob
->bp
->thread
== -1)
619 return scm_from_long (bp_smob
->bp
->thread
);
622 /* (set-breakpoint-thread! <gdb:breakpoint> integer) -> unspecified */
625 gdbscm_set_breakpoint_thread_x (SCM self
, SCM newvalue
)
627 breakpoint_smob
*bp_smob
628 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
631 if (scm_is_signed_integer (newvalue
, LONG_MIN
, LONG_MAX
))
633 id
= scm_to_long (newvalue
);
634 if (! valid_thread_id (id
))
636 gdbscm_out_of_range_error (FUNC_NAME
, SCM_ARG2
, newvalue
,
637 _("invalid thread id"));
640 else if (gdbscm_is_false (newvalue
))
643 SCM_ASSERT_TYPE (0, newvalue
, SCM_ARG2
, FUNC_NAME
, _("integer or #f"));
645 breakpoint_set_thread (bp_smob
->bp
, id
);
647 return SCM_UNSPECIFIED
;
650 /* (breakpoint-task <gdb:breakpoint>) -> integer */
653 gdbscm_breakpoint_task (SCM self
)
655 breakpoint_smob
*bp_smob
656 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
658 if (bp_smob
->bp
->task
== 0)
661 return scm_from_long (bp_smob
->bp
->task
);
664 /* (set-breakpoint-task! <gdb:breakpoint> integer) -> unspecified */
667 gdbscm_set_breakpoint_task_x (SCM self
, SCM newvalue
)
669 breakpoint_smob
*bp_smob
670 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
673 volatile struct gdb_exception except
;
675 if (scm_is_signed_integer (newvalue
, LONG_MIN
, LONG_MAX
))
677 id
= scm_to_long (newvalue
);
679 TRY_CATCH (except
, RETURN_MASK_ALL
)
681 valid_id
= valid_task_id (id
);
683 GDBSCM_HANDLE_GDB_EXCEPTION (except
);
687 gdbscm_out_of_range_error (FUNC_NAME
, SCM_ARG2
, newvalue
,
688 _("invalid task id"));
691 else if (gdbscm_is_false (newvalue
))
694 SCM_ASSERT_TYPE (0, newvalue
, SCM_ARG2
, FUNC_NAME
, _("integer or #f"));
696 TRY_CATCH (except
, RETURN_MASK_ALL
)
698 breakpoint_set_task (bp_smob
->bp
, id
);
700 GDBSCM_HANDLE_GDB_EXCEPTION (except
);
702 return SCM_UNSPECIFIED
;
705 /* (breakpoint-location <gdb:breakpoint>) -> string */
708 gdbscm_breakpoint_location (SCM self
)
710 breakpoint_smob
*bp_smob
711 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
714 if (bp_smob
->bp
->type
!= bp_breakpoint
)
717 str
= bp_smob
->bp
->addr_string
;
721 return gdbscm_scm_from_c_string (str
);
724 /* (breakpoint-expression <gdb:breakpoint>) -> string
725 This is only valid for watchpoints.
726 Returns #f for non-watchpoints. */
729 gdbscm_breakpoint_expression (SCM self
)
731 breakpoint_smob
*bp_smob
732 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
734 struct watchpoint
*wp
;
736 if (!is_watchpoint (bp_smob
->bp
))
739 wp
= (struct watchpoint
*) bp_smob
->bp
;
741 str
= wp
->exp_string
;
745 return gdbscm_scm_from_c_string (str
);
748 /* (breakpoint-condition <gdb:breakpoint>) -> string */
751 gdbscm_breakpoint_condition (SCM self
)
753 breakpoint_smob
*bp_smob
754 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
757 str
= bp_smob
->bp
->cond_string
;
761 return gdbscm_scm_from_c_string (str
);
764 /* (set-breakpoint-condition! <gdb:breakpoint> string|#f)
768 gdbscm_set_breakpoint_condition_x (SCM self
, SCM newvalue
)
770 breakpoint_smob
*bp_smob
771 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
773 volatile struct gdb_exception except
;
775 SCM_ASSERT_TYPE (scm_is_string (newvalue
) || gdbscm_is_false (newvalue
),
776 newvalue
, SCM_ARG2
, FUNC_NAME
,
779 if (gdbscm_is_false (newvalue
))
782 exp
= gdbscm_scm_to_c_string (newvalue
);
784 TRY_CATCH (except
, RETURN_MASK_ALL
)
786 set_breakpoint_condition (bp_smob
->bp
, exp
? exp
: "", 0);
789 GDBSCM_HANDLE_GDB_EXCEPTION (except
);
791 return SCM_UNSPECIFIED
;
794 /* (breakpoint-stop <gdb:breakpoint>) -> procedure or #f */
797 gdbscm_breakpoint_stop (SCM self
)
799 breakpoint_smob
*bp_smob
800 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
802 return bp_smob
->stop
;
805 /* (set-breakpoint-stop! <gdb:breakpoint> procedure|#f)
809 gdbscm_set_breakpoint_stop_x (SCM self
, SCM newvalue
)
811 breakpoint_smob
*bp_smob
812 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
813 const struct extension_language_defn
*extlang
= NULL
;
815 SCM_ASSERT_TYPE (gdbscm_is_procedure (newvalue
)
816 || gdbscm_is_false (newvalue
),
817 newvalue
, SCM_ARG2
, FUNC_NAME
,
818 _("procedure or #f"));
820 if (bp_smob
->bp
->cond_string
!= NULL
)
821 extlang
= get_ext_lang_defn (EXT_LANG_GDB
);
823 extlang
= get_breakpoint_cond_ext_lang (bp_smob
->bp
, EXT_LANG_GUILE
);
827 = xstrprintf (_("Only one stop condition allowed. There is"
828 " currently a %s stop condition defined for"
829 " this breakpoint."),
830 ext_lang_capitalized_name (extlang
));
832 scm_dynwind_begin (0);
833 gdbscm_dynwind_xfree (error_text
);
834 gdbscm_out_of_range_error (FUNC_NAME
, SCM_ARG1
, self
, error_text
);
835 /* The following line, while unnecessary, is present for completeness
840 bp_smob
->stop
= newvalue
;
842 return SCM_UNSPECIFIED
;
845 /* (breakpoint-commands <gdb:breakpoint>) -> string */
848 gdbscm_breakpoint_commands (SCM self
)
850 breakpoint_smob
*bp_smob
851 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
852 struct breakpoint
*bp
;
854 volatile struct gdb_exception except
;
855 struct ui_file
*string_file
;
856 struct cleanup
*chain
;
862 if (bp
->commands
== NULL
)
865 string_file
= mem_fileopen ();
866 chain
= make_cleanup_ui_file_delete (string_file
);
868 ui_out_redirect (current_uiout
, string_file
);
869 TRY_CATCH (except
, RETURN_MASK_ALL
)
871 print_command_lines (current_uiout
, breakpoint_commands (bp
), 0);
873 ui_out_redirect (current_uiout
, NULL
);
874 if (except
.reason
< 0)
877 gdbscm_throw_gdb_exception (except
);
880 cmdstr
= ui_file_xstrdup (string_file
, &length
);
881 make_cleanup (xfree
, cmdstr
);
882 result
= gdbscm_scm_from_c_string (cmdstr
);
888 /* (breakpoint-type <gdb:breakpoint>) -> integer */
891 gdbscm_breakpoint_type (SCM self
)
893 breakpoint_smob
*bp_smob
894 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
896 return scm_from_long (bp_smob
->bp
->type
);
899 /* (breakpoint-visible? <gdb:breakpoint>) -> boolean */
902 gdbscm_breakpoint_visible (SCM self
)
904 breakpoint_smob
*bp_smob
905 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
907 return scm_from_bool (bp_smob
->bp
->number
>= 0);
910 /* (breakpoint-number <gdb:breakpoint>) -> integer */
913 gdbscm_breakpoint_number (SCM self
)
915 breakpoint_smob
*bp_smob
916 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self
, SCM_ARG1
, FUNC_NAME
);
918 return scm_from_long (bp_smob
->number
);
921 /* Return TRUE if "stop" has been set for this breakpoint.
923 This is the extension_language_ops.breakpoint_has_cond "method". */
926 gdbscm_breakpoint_has_cond (const struct extension_language_defn
*extlang
,
927 struct breakpoint
*b
)
929 breakpoint_smob
*bp_smob
= b
->scm_bp_object
;
934 return gdbscm_is_procedure (bp_smob
->stop
);
937 /* Call the "stop" method in the breakpoint class.
938 This must only be called if gdbscm_breakpoint_has_cond returns true.
939 If the stop method returns #t, the inferior will be stopped at the
940 breakpoint. Otherwise the inferior will be allowed to continue
941 (assuming other conditions don't indicate "stop").
943 This is the extension_language_ops.breakpoint_cond_says_stop "method". */
945 enum ext_lang_bp_stop
946 gdbscm_breakpoint_cond_says_stop
947 (const struct extension_language_defn
*extlang
, struct breakpoint
*b
)
949 breakpoint_smob
*bp_smob
= b
->scm_bp_object
;
950 SCM predicate_result
;
954 return EXT_LANG_BP_STOP_UNSET
;
955 if (!gdbscm_is_procedure (bp_smob
->stop
))
956 return EXT_LANG_BP_STOP_UNSET
;
961 = gdbscm_safe_call_1 (bp_smob
->stop
, bp_smob
->containing_scm
, NULL
);
963 if (gdbscm_is_exception (predicate_result
))
964 ; /* Exception already printed. */
965 /* If the "stop" function returns #f that means
966 the Scheme breakpoint wants GDB to continue. */
967 else if (gdbscm_is_false (predicate_result
))
970 return stop
? EXT_LANG_BP_STOP_YES
: EXT_LANG_BP_STOP_NO
;
973 /* Event callback functions. */
975 /* Callback that is used when a breakpoint is created.
976 For breakpoints created by Scheme, i.e., gdbscm_create_breakpoint_x, finish
977 object creation by connecting the Scheme wrapper to the gdb object.
978 We ignore breakpoints created from gdb or python here, we create the
979 Scheme wrapper for those when there's a need to, e.g.,
980 gdbscm_breakpoints. */
983 bpscm_breakpoint_created (struct breakpoint
*bp
)
987 if (gdbscm_is_false (pending_breakpoint_scm
))
990 /* Verify our caller error checked the user's request. */
991 gdb_assert (bpscm_want_scm_wrapper_p (bp
, 1));
993 bp_scm
= pending_breakpoint_scm
;
994 pending_breakpoint_scm
= SCM_BOOL_F
;
996 bpscm_attach_scm_to_breakpoint (bp
, bp_scm
);
999 /* Callback that is used when a breakpoint is deleted. This will
1000 invalidate the corresponding Scheme object. */
1003 bpscm_breakpoint_deleted (struct breakpoint
*b
)
1005 int num
= b
->number
;
1006 struct breakpoint
*bp
;
1008 /* TODO: Why the lookup? We have B. */
1010 bp
= get_breakpoint (num
);
1013 breakpoint_smob
*bp_smob
= bp
->scm_bp_object
;
1018 scm_gc_unprotect_object (bp_smob
->containing_scm
);
1023 /* Initialize the Scheme breakpoint code. */
1025 static const scheme_integer_constant breakpoint_integer_constants
[] =
1027 { "BP_NONE", bp_none
},
1028 { "BP_BREAKPOINT", bp_breakpoint
},
1029 { "BP_WATCHPOINT", bp_watchpoint
},
1030 { "BP_HARDWARE_WATCHPOINT", bp_hardware_watchpoint
},
1031 { "BP_READ_WATCHPOINT", bp_read_watchpoint
},
1032 { "BP_ACCESS_WATCHPOINT", bp_access_watchpoint
},
1034 { "WP_READ", hw_read
},
1035 { "WP_WRITE", hw_write
},
1036 { "WP_ACCESS", hw_access
},
1038 END_INTEGER_CONSTANTS
1041 static const scheme_function breakpoint_functions
[] =
1043 { "create-breakpoint!", 1, 0, 1, gdbscm_create_breakpoint_x
,
1045 Create and install a GDB breakpoint object.\n\
1048 location [#:type <type>] [#:wp-class <wp-class>] [#:internal <bool>]" },
1050 { "breakpoint-delete!", 1, 0, 0, gdbscm_breakpoint_delete_x
,
1052 Delete the breakpoint from GDB." },
1054 { "breakpoints", 0, 0, 0, gdbscm_breakpoints
,
1056 Return a list of all GDB breakpoints.\n\
1060 { "breakpoint?", 1, 0, 0, gdbscm_breakpoint_p
,
1062 Return #t if the object is a <gdb:breakpoint> object." },
1064 { "breakpoint-valid?", 1, 0, 0, gdbscm_breakpoint_valid_p
,
1066 Return #t if the breakpoint has not been deleted from GDB." },
1068 { "breakpoint-number", 1, 0, 0, gdbscm_breakpoint_number
,
1070 Return the breakpoint's number." },
1072 { "breakpoint-type", 1, 0, 0, gdbscm_breakpoint_type
,
1074 Return the type of the breakpoint." },
1076 { "breakpoint-visible?", 1, 0, 0, gdbscm_breakpoint_visible
,
1078 Return #t if the breakpoint is visible to the user." },
1080 { "breakpoint-location", 1, 0, 0, gdbscm_breakpoint_location
,
1082 Return the location of the breakpoint as specified by the user." },
1084 { "breakpoint-expression", 1, 0, 0, gdbscm_breakpoint_expression
,
1086 Return the expression of the breakpoint as specified by the user.\n\
1087 Valid for watchpoints only, returns #f for non-watchpoints." },
1089 { "breakpoint-enabled?", 1, 0, 0, gdbscm_breakpoint_enabled_p
,
1091 Return #t if the breakpoint is enabled." },
1093 { "set-breakpoint-enabled!", 2, 0, 0, gdbscm_set_breakpoint_enabled_x
,
1095 Set the breakpoint's enabled state.\n\
1097 Arguments: <gdb:breakpoint boolean" },
1099 { "breakpoint-silent?", 1, 0, 0, gdbscm_breakpoint_silent_p
,
1101 Return #t if the breakpoint is silent." },
1103 { "set-breakpoint-silent!", 2, 0, 0, gdbscm_set_breakpoint_silent_x
,
1105 Set the breakpoint's silent state.\n\
1107 Arguments: <gdb:breakpoint> boolean" },
1109 { "breakpoint-ignore-count", 1, 0, 0, gdbscm_breakpoint_ignore_count
,
1111 Return the breakpoint's \"ignore\" count." },
1113 { "set-breakpoint-ignore-count!", 2, 0, 0,
1114 gdbscm_set_breakpoint_ignore_count_x
,
1116 Set the breakpoint's \"ignore\" count.\n\
1118 Arguments: <gdb:breakpoint> count" },
1120 { "breakpoint-hit-count", 1, 0, 0, gdbscm_breakpoint_hit_count
,
1122 Return the breakpoint's \"hit\" count." },
1124 { "set-breakpoint-hit-count!", 2, 0, 0, gdbscm_set_breakpoint_hit_count_x
,
1126 Set the breakpoint's \"hit\" count. The value must be zero.\n\
1128 Arguments: <gdb:breakpoint> 0" },
1130 { "breakpoint-thread", 1, 0, 0, gdbscm_breakpoint_thread
,
1132 Return the breakpoint's thread id or #f if there isn't one." },
1134 { "set-breakpoint-thread!", 2, 0, 0, gdbscm_set_breakpoint_thread_x
,
1136 Set the thread id for this breakpoint.\n\
1138 Arguments: <gdb:breakpoint> thread-id" },
1140 { "breakpoint-task", 1, 0, 0, gdbscm_breakpoint_task
,
1142 Return the breakpoint's Ada task-id or #f if there isn't one." },
1144 { "set-breakpoint-task!", 2, 0, 0, gdbscm_set_breakpoint_task_x
,
1146 Set the breakpoint's Ada task-id.\n\
1148 Arguments: <gdb:breakpoint> task-id" },
1150 { "breakpoint-condition", 1, 0, 0, gdbscm_breakpoint_condition
,
1152 Return the breakpoint's condition as specified by the user.\n\
1153 Return #f if there isn't one." },
1155 { "set-breakpoint-condition!", 2, 0, 0, gdbscm_set_breakpoint_condition_x
,
1157 Set the breakpoint's condition.\n\
1159 Arguments: <gdb:breakpoint> condition\n\
1160 condition: a string" },
1162 { "breakpoint-stop", 1, 0, 0, gdbscm_breakpoint_stop
,
1164 Return the breakpoint's stop predicate.\n\
1165 Return #f if there isn't one." },
1167 { "set-breakpoint-stop!", 2, 0, 0, gdbscm_set_breakpoint_stop_x
,
1169 Set the breakpoint's stop predicate.\n\
1171 Arguments: <gdb:breakpoint> procedure\n\
1172 procedure: A procedure of one argument, the breakpoint.\n\
1173 Its result is true if program execution should stop." },
1175 { "breakpoint-commands", 1, 0, 0, gdbscm_breakpoint_commands
,
1177 Return the breakpoint's commands." },
1183 gdbscm_initialize_breakpoints (void)
1186 = gdbscm_make_smob_type (breakpoint_smob_name
, sizeof (breakpoint_smob
));
1187 scm_set_smob_mark (breakpoint_smob_tag
, bpscm_mark_breakpoint_smob
);
1188 scm_set_smob_free (breakpoint_smob_tag
, bpscm_free_breakpoint_smob
);
1189 scm_set_smob_print (breakpoint_smob_tag
, bpscm_print_breakpoint_smob
);
1191 observer_attach_breakpoint_created (bpscm_breakpoint_created
);
1192 observer_attach_breakpoint_deleted (bpscm_breakpoint_deleted
);
1194 gdbscm_define_integer_constants (breakpoint_integer_constants
, 1);
1195 gdbscm_define_functions (breakpoint_functions
, 1);
1197 type_keyword
= scm_from_latin1_keyword ("type");
1198 wp_class_keyword
= scm_from_latin1_keyword ("wp-class");
1199 internal_keyword
= scm_from_latin1_keyword ("internal");