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 "free" function for <gdb:breakpoint>. */
79 bpscm_free_breakpoint_smob (SCM self)
81 breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (self);
84 bp_smob->bp->scm_bp_object = NULL;
86 /* Not necessary, done to catch bugs. */
88 bp_smob->containing_scm = SCM_UNDEFINED;
89 bp_smob->stop = SCM_UNDEFINED;
94 /* Return the name of TYPE.
95 This doesn't handle all types, just the ones we export. */
98 bpscm_type_to_string (enum bptype type)
102 case bp_none: return "BP_NONE";
103 case bp_breakpoint: return "BP_BREAKPOINT";
104 case bp_watchpoint: return "BP_WATCHPOINT";
105 case bp_hardware_watchpoint: return "BP_HARDWARE_WATCHPOINT";
106 case bp_read_watchpoint: return "BP_READ_WATCHPOINT";
107 case bp_access_watchpoint: return "BP_ACCESS_WATCHPOINT";
108 default: return "internal/other";
112 /* Return the name of ENABLE_STATE. */
115 bpscm_enable_state_to_string (enum enable_state enable_state)
117 switch (enable_state)
119 case bp_disabled: return "disabled";
120 case bp_enabled: return "enabled";
121 case bp_call_disabled: return "call_disabled";
122 case bp_permanent: return "permanent";
123 default: return "unknown";
127 /* The smob "print" function for <gdb:breakpoint>. */
130 bpscm_print_breakpoint_smob (SCM self, SCM port, scm_print_state *pstate)
132 breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (self);
133 struct breakpoint *b = bp_smob->bp;
135 gdbscm_printf (port, "#<%s", breakpoint_smob_name);
137 /* Only print what we export to the user.
138 The rest are possibly internal implementation details. */
140 gdbscm_printf (port, " #%d", bp_smob->number);
142 /* Careful, the breakpoint may be invalid. */
145 gdbscm_printf (port, " %s %s %s",
146 bpscm_type_to_string (b->type),
147 bpscm_enable_state_to_string (b->enable_state),
148 b->silent ? "silent" : "noisy");
150 gdbscm_printf (port, " hit:%d", b->hit_count);
151 gdbscm_printf (port, " ignore:%d", b->ignore_count);
153 if (b->addr_string != NULL)
154 gdbscm_printf (port, " @%s", b->addr_string);
157 scm_puts (">", port);
159 scm_remember_upto_here_1 (self);
161 /* Non-zero means success. */
165 /* Low level routine to create a <gdb:breakpoint> object. */
168 bpscm_make_breakpoint_smob (void)
170 breakpoint_smob *bp_smob = (breakpoint_smob *)
171 scm_gc_malloc (sizeof (breakpoint_smob), breakpoint_smob_name);
174 bp_smob->number = -1;
176 bp_smob->stop = SCM_BOOL_F;
177 bp_scm = scm_new_smob (breakpoint_smob_tag, (scm_t_bits) bp_smob);
178 bp_smob->containing_scm = bp_scm;
179 gdbscm_init_gsmob (&bp_smob->base);
184 /* Return non-zero if we want a Scheme wrapper for breakpoint B.
185 If FROM_SCHEME is non-zero,this is called for a breakpoint created
186 by the user from Scheme. Otherwise it is zero. */
189 bpscm_want_scm_wrapper_p (struct breakpoint *bp, int from_scheme)
191 /* Don't create <gdb:breakpoint> objects for internal GDB breakpoints. */
192 if (bp->number < 0 && !from_scheme)
195 /* The others are not supported. */
196 if (bp->type != bp_breakpoint
197 && bp->type != bp_watchpoint
198 && bp->type != bp_hardware_watchpoint
199 && bp->type != bp_read_watchpoint
200 && bp->type != bp_access_watchpoint)
206 /* Install the Scheme side of a breakpoint, CONTAINING_SCM, in
210 bpscm_attach_scm_to_breakpoint (struct breakpoint *bp, SCM containing_scm)
212 breakpoint_smob *bp_smob;
214 bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (containing_scm);
215 bp_smob->number = bp->number;
217 bp_smob->containing_scm = containing_scm;
218 bp_smob->bp->scm_bp_object = bp_smob;
220 /* The owner of this breakpoint is not in GC-controlled memory, so we need
221 to protect it from GC until the breakpoint is deleted. */
222 scm_gc_protect_object (containing_scm);
225 /* Return non-zero if SCM is a breakpoint smob. */
228 bpscm_is_breakpoint (SCM scm)
230 return SCM_SMOB_PREDICATE (breakpoint_smob_tag, scm);
233 /* (breakpoint? scm) -> boolean */
236 gdbscm_breakpoint_p (SCM scm)
238 return scm_from_bool (bpscm_is_breakpoint (scm));
241 /* Returns the <gdb:breakpoint> object in SELF.
242 Throws an exception if SELF is not a <gdb:breakpoint> object. */
245 bpscm_get_breakpoint_arg_unsafe (SCM self, int arg_pos, const char *func_name)
247 SCM_ASSERT_TYPE (bpscm_is_breakpoint (self), self, arg_pos, func_name,
248 breakpoint_smob_name);
253 /* Returns a pointer to the breakpoint smob of SELF.
254 Throws an exception if SELF is not a <gdb:breakpoint> object. */
256 static breakpoint_smob *
257 bpscm_get_breakpoint_smob_arg_unsafe (SCM self, int arg_pos,
258 const char *func_name)
260 SCM bp_scm = bpscm_get_breakpoint_arg_unsafe (self, arg_pos, func_name);
261 breakpoint_smob *bp_smob = (breakpoint_smob *) SCM_SMOB_DATA (bp_scm);
266 /* Return non-zero if breakpoint BP_SMOB is valid. */
269 bpscm_is_valid (breakpoint_smob *bp_smob)
271 return bp_smob->bp != NULL;
274 /* Returns the breakpoint smob in SELF, verifying it's valid.
275 Throws an exception if SELF is not a <gdb:breakpoint> object,
278 static breakpoint_smob *
279 bpscm_get_valid_breakpoint_smob_arg_unsafe (SCM self, int arg_pos,
280 const char *func_name)
282 breakpoint_smob *bp_smob
283 = bpscm_get_breakpoint_smob_arg_unsafe (self, arg_pos, func_name);
285 if (!bpscm_is_valid (bp_smob))
287 gdbscm_invalid_object_error (func_name, arg_pos, self,
288 _("<gdb:breakpoint>"));
294 /* Breakpoint methods. */
296 /* (create-breakpoint! string [#:type integer] [#:wp-class integer]
297 [#:internal boolean) -> <gdb:breakpoint> */
300 gdbscm_create_breakpoint_x (SCM spec_scm, SCM rest)
302 const SCM keywords[] = {
303 type_keyword, wp_class_keyword, internal_keyword, SCM_BOOL_F
306 int type_arg_pos = -1, access_type_arg_pos = -1, internal_arg_pos = -1;
307 int type = bp_breakpoint;
308 int access_type = hw_write;
311 volatile struct gdb_exception except;
313 gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "s#iit",
314 spec_scm, &spec, rest,
315 &type_arg_pos, &type,
316 &access_type_arg_pos, &access_type,
317 &internal_arg_pos, &internal);
319 result = bpscm_make_breakpoint_smob ();
320 pending_breakpoint_scm = result;
322 TRY_CATCH (except, RETURN_MASK_ALL)
324 struct cleanup *cleanup = make_cleanup (xfree, spec);
330 create_breakpoint (get_current_arch (),
331 spec, NULL, -1, NULL,
336 &bkpt_breakpoint_ops,
342 if (access_type == hw_write)
343 watch_command_wrapper (spec, 0, internal);
344 else if (access_type == hw_access)
345 awatch_command_wrapper (spec, 0, internal);
346 else if (access_type == hw_read)
347 rwatch_command_wrapper (spec, 0, internal);
349 error (_("Invalid watchpoint access type"));
353 error (_("Invalid breakpoint type"));
356 do_cleanups (cleanup);
358 /* Ensure this gets reset, even if there's an error. */
359 pending_breakpoint_scm = SCM_BOOL_F;
360 GDBSCM_HANDLE_GDB_EXCEPTION (except);
365 /* (breakpoint-delete! <gdb:breakpoint>) -> unspecified
366 Scheme function which deletes the underlying GDB breakpoint. This
367 triggers the breakpoint_deleted observer which will call
368 gdbscm_breakpoint_deleted; that function cleans up the Scheme sections. */
371 gdbscm_breakpoint_delete_x (SCM self)
373 breakpoint_smob *bp_smob
374 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
375 volatile struct gdb_exception except;
377 TRY_CATCH (except, RETURN_MASK_ALL)
379 delete_breakpoint (bp_smob->bp);
381 GDBSCM_HANDLE_GDB_EXCEPTION (except);
383 return SCM_UNSPECIFIED;
386 /* iterate_over_breakpoints function for gdbscm_breakpoints. */
389 bpscm_build_bp_list (struct breakpoint *bp, void *arg)
392 breakpoint_smob *bp_smob = bp->scm_bp_object;
394 /* Lazily create wrappers for breakpoints created outside Scheme. */
398 if (bpscm_want_scm_wrapper_p (bp, 0))
402 bp_scm = bpscm_make_breakpoint_smob ();
403 bpscm_attach_scm_to_breakpoint (bp, bp_scm);
405 bp_smob = bp->scm_bp_object;
409 /* Not all breakpoints will have a companion Scheme object.
410 Only breakpoints that trigger the created_breakpoint observer call,
411 and satisfy certain conditions (see bpscm_want_scm_wrapper_p),
412 get a companion object (this includes Scheme-created breakpoints). */
415 *list = scm_cons (bp_smob->containing_scm, *list);
420 /* (breakpoints) -> list
421 Return a list of all breakpoints. */
424 gdbscm_breakpoints (void)
428 /* If iterate_over_breakpoints returns non-NULL it means the iteration
430 In that case abandon building the list and return #f. */
431 if (iterate_over_breakpoints (bpscm_build_bp_list, &list) != NULL)
434 return scm_reverse_x (list, SCM_EOL);
437 /* (breakpoint-valid? <gdb:breakpoint>) -> boolean
438 Returns #t if SELF is still valid. */
441 gdbscm_breakpoint_valid_p (SCM self)
443 breakpoint_smob *bp_smob
444 = bpscm_get_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
446 return scm_from_bool (bpscm_is_valid (bp_smob));
449 /* (breakpoint-enabled? <gdb:breakpoint>) -> boolean */
452 gdbscm_breakpoint_enabled_p (SCM self)
454 breakpoint_smob *bp_smob
455 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
457 return scm_from_bool (bp_smob->bp->enable_state == bp_enabled);
460 /* (set-breakpoint-enabled? <gdb:breakpoint> boolean) -> unspecified */
463 gdbscm_set_breakpoint_enabled_x (SCM self, SCM newvalue)
465 breakpoint_smob *bp_smob
466 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
467 volatile struct gdb_exception except;
469 SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue), newvalue, SCM_ARG2, FUNC_NAME,
472 TRY_CATCH (except, RETURN_MASK_ALL)
474 if (gdbscm_is_true (newvalue))
475 enable_breakpoint (bp_smob->bp);
477 disable_breakpoint (bp_smob->bp);
479 GDBSCM_HANDLE_GDB_EXCEPTION (except);
481 return SCM_UNSPECIFIED;
484 /* (breakpoint-silent? <gdb:breakpoint>) -> boolean */
487 gdbscm_breakpoint_silent_p (SCM self)
489 breakpoint_smob *bp_smob
490 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
492 return scm_from_bool (bp_smob->bp->silent);
495 /* (set-breakpoint-silent?! <gdb:breakpoint> boolean) -> unspecified */
498 gdbscm_set_breakpoint_silent_x (SCM self, SCM newvalue)
500 breakpoint_smob *bp_smob
501 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
502 volatile struct gdb_exception except;
504 SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue), newvalue, SCM_ARG2, FUNC_NAME,
507 TRY_CATCH (except, RETURN_MASK_ALL)
509 breakpoint_set_silent (bp_smob->bp, gdbscm_is_true (newvalue));
511 GDBSCM_HANDLE_GDB_EXCEPTION (except);
513 return SCM_UNSPECIFIED;
516 /* (breakpoint-ignore-count <gdb:breakpoint>) -> integer */
519 gdbscm_breakpoint_ignore_count (SCM self)
521 breakpoint_smob *bp_smob
522 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
524 return scm_from_long (bp_smob->bp->ignore_count);
527 /* (set-breakpoint-ignore-count! <gdb:breakpoint> integer)
531 gdbscm_set_breakpoint_ignore_count_x (SCM self, SCM newvalue)
533 breakpoint_smob *bp_smob
534 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
536 volatile struct gdb_exception except;
538 SCM_ASSERT_TYPE (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX),
539 newvalue, SCM_ARG2, FUNC_NAME, _("integer"));
541 value = scm_to_long (newvalue);
545 TRY_CATCH (except, RETURN_MASK_ALL)
547 set_ignore_count (bp_smob->number, (int) value, 0);
549 GDBSCM_HANDLE_GDB_EXCEPTION (except);
551 return SCM_UNSPECIFIED;
554 /* (breakpoint-hit-count <gdb:breakpoint>) -> integer */
557 gdbscm_breakpoint_hit_count (SCM self)
559 breakpoint_smob *bp_smob
560 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
562 return scm_from_long (bp_smob->bp->hit_count);
565 /* (set-breakpoint-hit-count! <gdb:breakpoint> integer) -> unspecified */
568 gdbscm_set_breakpoint_hit_count_x (SCM self, SCM newvalue)
570 breakpoint_smob *bp_smob
571 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
574 SCM_ASSERT_TYPE (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX),
575 newvalue, SCM_ARG2, FUNC_NAME, _("integer"));
577 value = scm_to_long (newvalue);
583 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
584 _("hit-count must be zero"));
587 bp_smob->bp->hit_count = 0;
589 return SCM_UNSPECIFIED;
592 /* (breakpoint-thread <gdb:breakpoint>) -> integer */
595 gdbscm_breakpoint_thread (SCM self)
597 breakpoint_smob *bp_smob
598 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
600 if (bp_smob->bp->thread == -1)
603 return scm_from_long (bp_smob->bp->thread);
606 /* (set-breakpoint-thread! <gdb:breakpoint> integer) -> unspecified */
609 gdbscm_set_breakpoint_thread_x (SCM self, SCM newvalue)
611 breakpoint_smob *bp_smob
612 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
615 if (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX))
617 id = scm_to_long (newvalue);
618 if (! valid_thread_id (id))
620 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
621 _("invalid thread id"));
624 else if (gdbscm_is_false (newvalue))
627 SCM_ASSERT_TYPE (0, newvalue, SCM_ARG2, FUNC_NAME, _("integer or #f"));
629 breakpoint_set_thread (bp_smob->bp, id);
631 return SCM_UNSPECIFIED;
634 /* (breakpoint-task <gdb:breakpoint>) -> integer */
637 gdbscm_breakpoint_task (SCM self)
639 breakpoint_smob *bp_smob
640 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
642 if (bp_smob->bp->task == 0)
645 return scm_from_long (bp_smob->bp->task);
648 /* (set-breakpoint-task! <gdb:breakpoint> integer) -> unspecified */
651 gdbscm_set_breakpoint_task_x (SCM self, SCM newvalue)
653 breakpoint_smob *bp_smob
654 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
657 volatile struct gdb_exception except;
659 if (scm_is_signed_integer (newvalue, LONG_MIN, LONG_MAX))
661 id = scm_to_long (newvalue);
663 TRY_CATCH (except, RETURN_MASK_ALL)
665 valid_id = valid_task_id (id);
667 GDBSCM_HANDLE_GDB_EXCEPTION (except);
671 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue,
672 _("invalid task id"));
675 else if (gdbscm_is_false (newvalue))
678 SCM_ASSERT_TYPE (0, newvalue, SCM_ARG2, FUNC_NAME, _("integer or #f"));
680 TRY_CATCH (except, RETURN_MASK_ALL)
682 breakpoint_set_task (bp_smob->bp, id);
684 GDBSCM_HANDLE_GDB_EXCEPTION (except);
686 return SCM_UNSPECIFIED;
689 /* (breakpoint-location <gdb:breakpoint>) -> string */
692 gdbscm_breakpoint_location (SCM self)
694 breakpoint_smob *bp_smob
695 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
698 if (bp_smob->bp->type != bp_breakpoint)
701 str = bp_smob->bp->addr_string;
705 return gdbscm_scm_from_c_string (str);
708 /* (breakpoint-expression <gdb:breakpoint>) -> string
709 This is only valid for watchpoints.
710 Returns #f for non-watchpoints. */
713 gdbscm_breakpoint_expression (SCM self)
715 breakpoint_smob *bp_smob
716 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
718 struct watchpoint *wp;
720 if (!is_watchpoint (bp_smob->bp))
723 wp = (struct watchpoint *) bp_smob->bp;
725 str = wp->exp_string;
729 return gdbscm_scm_from_c_string (str);
732 /* (breakpoint-condition <gdb:breakpoint>) -> string */
735 gdbscm_breakpoint_condition (SCM self)
737 breakpoint_smob *bp_smob
738 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
741 str = bp_smob->bp->cond_string;
745 return gdbscm_scm_from_c_string (str);
748 /* (set-breakpoint-condition! <gdb:breakpoint> string|#f)
752 gdbscm_set_breakpoint_condition_x (SCM self, SCM newvalue)
754 breakpoint_smob *bp_smob
755 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
757 volatile struct gdb_exception except;
759 SCM_ASSERT_TYPE (scm_is_string (newvalue) || gdbscm_is_false (newvalue),
760 newvalue, SCM_ARG2, FUNC_NAME,
763 if (gdbscm_is_false (newvalue))
766 exp = gdbscm_scm_to_c_string (newvalue);
768 TRY_CATCH (except, RETURN_MASK_ALL)
770 set_breakpoint_condition (bp_smob->bp, exp ? exp : "", 0);
773 GDBSCM_HANDLE_GDB_EXCEPTION (except);
775 return SCM_UNSPECIFIED;
778 /* (breakpoint-stop <gdb:breakpoint>) -> procedure or #f */
781 gdbscm_breakpoint_stop (SCM self)
783 breakpoint_smob *bp_smob
784 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
786 return bp_smob->stop;
789 /* (set-breakpoint-stop! <gdb:breakpoint> procedure|#f)
793 gdbscm_set_breakpoint_stop_x (SCM self, SCM newvalue)
795 breakpoint_smob *bp_smob
796 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
797 const struct extension_language_defn *extlang = NULL;
799 SCM_ASSERT_TYPE (gdbscm_is_procedure (newvalue)
800 || gdbscm_is_false (newvalue),
801 newvalue, SCM_ARG2, FUNC_NAME,
802 _("procedure or #f"));
804 if (bp_smob->bp->cond_string != NULL)
805 extlang = get_ext_lang_defn (EXT_LANG_GDB);
807 extlang = get_breakpoint_cond_ext_lang (bp_smob->bp, EXT_LANG_GUILE);
811 = xstrprintf (_("Only one stop condition allowed. There is"
812 " currently a %s stop condition defined for"
813 " this breakpoint."),
814 ext_lang_capitalized_name (extlang));
816 scm_dynwind_begin (0);
817 gdbscm_dynwind_xfree (error_text);
818 gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self, error_text);
819 /* The following line, while unnecessary, is present for completeness
824 bp_smob->stop = newvalue;
826 return SCM_UNSPECIFIED;
829 /* (breakpoint-commands <gdb:breakpoint>) -> string */
832 gdbscm_breakpoint_commands (SCM self)
834 breakpoint_smob *bp_smob
835 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
836 struct breakpoint *bp;
838 volatile struct gdb_exception except;
839 struct ui_file *string_file;
840 struct cleanup *chain;
846 if (bp->commands == NULL)
849 string_file = mem_fileopen ();
850 chain = make_cleanup_ui_file_delete (string_file);
852 ui_out_redirect (current_uiout, string_file);
853 TRY_CATCH (except, RETURN_MASK_ALL)
855 print_command_lines (current_uiout, breakpoint_commands (bp), 0);
857 ui_out_redirect (current_uiout, NULL);
858 if (except.reason < 0)
861 gdbscm_throw_gdb_exception (except);
864 cmdstr = ui_file_xstrdup (string_file, &length);
865 make_cleanup (xfree, cmdstr);
866 result = gdbscm_scm_from_c_string (cmdstr);
872 /* (breakpoint-type <gdb:breakpoint>) -> integer */
875 gdbscm_breakpoint_type (SCM self)
877 breakpoint_smob *bp_smob
878 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
880 return scm_from_long (bp_smob->bp->type);
883 /* (breakpoint-visible? <gdb:breakpoint>) -> boolean */
886 gdbscm_breakpoint_visible (SCM self)
888 breakpoint_smob *bp_smob
889 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
891 return scm_from_bool (bp_smob->bp->number >= 0);
894 /* (breakpoint-number <gdb:breakpoint>) -> integer */
897 gdbscm_breakpoint_number (SCM self)
899 breakpoint_smob *bp_smob
900 = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
902 return scm_from_long (bp_smob->number);
905 /* Return TRUE if "stop" has been set for this breakpoint.
907 This is the extension_language_ops.breakpoint_has_cond "method". */
910 gdbscm_breakpoint_has_cond (const struct extension_language_defn *extlang,
911 struct breakpoint *b)
913 breakpoint_smob *bp_smob = b->scm_bp_object;
918 return gdbscm_is_procedure (bp_smob->stop);
921 /* Call the "stop" method in the breakpoint class.
922 This must only be called if gdbscm_breakpoint_has_cond returns true.
923 If the stop method returns #t, the inferior will be stopped at the
924 breakpoint. Otherwise the inferior will be allowed to continue
925 (assuming other conditions don't indicate "stop").
927 This is the extension_language_ops.breakpoint_cond_says_stop "method". */
929 enum ext_lang_bp_stop
930 gdbscm_breakpoint_cond_says_stop
931 (const struct extension_language_defn *extlang, struct breakpoint *b)
933 breakpoint_smob *bp_smob = b->scm_bp_object;
934 SCM predicate_result;
938 return EXT_LANG_BP_STOP_UNSET;
939 if (!gdbscm_is_procedure (bp_smob->stop))
940 return EXT_LANG_BP_STOP_UNSET;
945 = gdbscm_safe_call_1 (bp_smob->stop, bp_smob->containing_scm, NULL);
947 if (gdbscm_is_exception (predicate_result))
948 ; /* Exception already printed. */
949 /* If the "stop" function returns #f that means
950 the Scheme breakpoint wants GDB to continue. */
951 else if (gdbscm_is_false (predicate_result))
954 return stop ? EXT_LANG_BP_STOP_YES : EXT_LANG_BP_STOP_NO;
957 /* Event callback functions. */
959 /* Callback that is used when a breakpoint is created.
960 For breakpoints created by Scheme, i.e., gdbscm_create_breakpoint_x, finish
961 object creation by connecting the Scheme wrapper to the gdb object.
962 We ignore breakpoints created from gdb or python here, we create the
963 Scheme wrapper for those when there's a need to, e.g.,
964 gdbscm_breakpoints. */
967 bpscm_breakpoint_created (struct breakpoint *bp)
971 if (gdbscm_is_false (pending_breakpoint_scm))
974 /* Verify our caller error checked the user's request. */
975 gdb_assert (bpscm_want_scm_wrapper_p (bp, 1));
977 bp_scm = pending_breakpoint_scm;
978 pending_breakpoint_scm = SCM_BOOL_F;
980 bpscm_attach_scm_to_breakpoint (bp, bp_scm);
983 /* Callback that is used when a breakpoint is deleted. This will
984 invalidate the corresponding Scheme object. */
987 bpscm_breakpoint_deleted (struct breakpoint *b)
990 struct breakpoint *bp;
992 /* TODO: Why the lookup? We have B. */
994 bp = get_breakpoint (num);
997 breakpoint_smob *bp_smob = bp->scm_bp_object;
1002 scm_gc_unprotect_object (bp_smob->containing_scm);
1007 /* Initialize the Scheme breakpoint code. */
1009 static const scheme_integer_constant breakpoint_integer_constants[] =
1011 { "BP_NONE", bp_none },
1012 { "BP_BREAKPOINT", bp_breakpoint },
1013 { "BP_WATCHPOINT", bp_watchpoint },
1014 { "BP_HARDWARE_WATCHPOINT", bp_hardware_watchpoint },
1015 { "BP_READ_WATCHPOINT", bp_read_watchpoint },
1016 { "BP_ACCESS_WATCHPOINT", bp_access_watchpoint },
1018 { "WP_READ", hw_read },
1019 { "WP_WRITE", hw_write },
1020 { "WP_ACCESS", hw_access },
1022 END_INTEGER_CONSTANTS
1025 static const scheme_function breakpoint_functions[] =
1027 { "create-breakpoint!", 1, 0, 1, gdbscm_create_breakpoint_x,
1029 Create and install a GDB breakpoint object.\n\
1032 location [#:type <type>] [#:wp-class <wp-class>] [#:internal <bool>]" },
1034 { "breakpoint-delete!", 1, 0, 0, gdbscm_breakpoint_delete_x,
1036 Delete the breakpoint from GDB." },
1038 { "breakpoints", 0, 0, 0, gdbscm_breakpoints,
1040 Return a list of all GDB breakpoints.\n\
1044 { "breakpoint?", 1, 0, 0, gdbscm_breakpoint_p,
1046 Return #t if the object is a <gdb:breakpoint> object." },
1048 { "breakpoint-valid?", 1, 0, 0, gdbscm_breakpoint_valid_p,
1050 Return #t if the breakpoint has not been deleted from GDB." },
1052 { "breakpoint-number", 1, 0, 0, gdbscm_breakpoint_number,
1054 Return the breakpoint's number." },
1056 { "breakpoint-type", 1, 0, 0, gdbscm_breakpoint_type,
1058 Return the type of the breakpoint." },
1060 { "breakpoint-visible?", 1, 0, 0, gdbscm_breakpoint_visible,
1062 Return #t if the breakpoint is visible to the user." },
1064 { "breakpoint-location", 1, 0, 0, gdbscm_breakpoint_location,
1066 Return the location of the breakpoint as specified by the user." },
1068 { "breakpoint-expression", 1, 0, 0, gdbscm_breakpoint_expression,
1070 Return the expression of the breakpoint as specified by the user.\n\
1071 Valid for watchpoints only, returns #f for non-watchpoints." },
1073 { "breakpoint-enabled?", 1, 0, 0, gdbscm_breakpoint_enabled_p,
1075 Return #t if the breakpoint is enabled." },
1077 { "set-breakpoint-enabled!", 2, 0, 0, gdbscm_set_breakpoint_enabled_x,
1079 Set the breakpoint's enabled state.\n\
1081 Arguments: <gdb:breakpoint> boolean" },
1083 { "breakpoint-silent?", 1, 0, 0, gdbscm_breakpoint_silent_p,
1085 Return #t if the breakpoint is silent." },
1087 { "set-breakpoint-silent!", 2, 0, 0, gdbscm_set_breakpoint_silent_x,
1089 Set the breakpoint's silent state.\n\
1091 Arguments: <gdb:breakpoint> boolean" },
1093 { "breakpoint-ignore-count", 1, 0, 0, gdbscm_breakpoint_ignore_count,
1095 Return the breakpoint's \"ignore\" count." },
1097 { "set-breakpoint-ignore-count!", 2, 0, 0,
1098 gdbscm_set_breakpoint_ignore_count_x,
1100 Set the breakpoint's \"ignore\" count.\n\
1102 Arguments: <gdb:breakpoint> count" },
1104 { "breakpoint-hit-count", 1, 0, 0, gdbscm_breakpoint_hit_count,
1106 Return the breakpoint's \"hit\" count." },
1108 { "set-breakpoint-hit-count!", 2, 0, 0, gdbscm_set_breakpoint_hit_count_x,
1110 Set the breakpoint's \"hit\" count. The value must be zero.\n\
1112 Arguments: <gdb:breakpoint> 0" },
1114 { "breakpoint-thread", 1, 0, 0, gdbscm_breakpoint_thread,
1116 Return the breakpoint's thread id or #f if there isn't one." },
1118 { "set-breakpoint-thread!", 2, 0, 0, gdbscm_set_breakpoint_thread_x,
1120 Set the thread id for this breakpoint.\n\
1122 Arguments: <gdb:breakpoint> thread-id" },
1124 { "breakpoint-task", 1, 0, 0, gdbscm_breakpoint_task,
1126 Return the breakpoint's Ada task-id or #f if there isn't one." },
1128 { "set-breakpoint-task!", 2, 0, 0, gdbscm_set_breakpoint_task_x,
1130 Set the breakpoint's Ada task-id.\n\
1132 Arguments: <gdb:breakpoint> task-id" },
1134 { "breakpoint-condition", 1, 0, 0, gdbscm_breakpoint_condition,
1136 Return the breakpoint's condition as specified by the user.\n\
1137 Return #f if there isn't one." },
1139 { "set-breakpoint-condition!", 2, 0, 0, gdbscm_set_breakpoint_condition_x,
1141 Set the breakpoint's condition.\n\
1143 Arguments: <gdb:breakpoint> condition\n\
1144 condition: a string" },
1146 { "breakpoint-stop", 1, 0, 0, gdbscm_breakpoint_stop,
1148 Return the breakpoint's stop predicate.\n\
1149 Return #f if there isn't one." },
1151 { "set-breakpoint-stop!", 2, 0, 0, gdbscm_set_breakpoint_stop_x,
1153 Set the breakpoint's stop predicate.\n\
1155 Arguments: <gdb:breakpoint> procedure\n\
1156 procedure: A procedure of one argument, the breakpoint.\n\
1157 Its result is true if program execution should stop." },
1159 { "breakpoint-commands", 1, 0, 0, gdbscm_breakpoint_commands,
1161 Return the breakpoint's commands." },
1167 gdbscm_initialize_breakpoints (void)
1170 = gdbscm_make_smob_type (breakpoint_smob_name, sizeof (breakpoint_smob));
1171 scm_set_smob_free (breakpoint_smob_tag, bpscm_free_breakpoint_smob);
1172 scm_set_smob_print (breakpoint_smob_tag, bpscm_print_breakpoint_smob);
1174 observer_attach_breakpoint_created (bpscm_breakpoint_created);
1175 observer_attach_breakpoint_deleted (bpscm_breakpoint_deleted);
1177 gdbscm_define_integer_constants (breakpoint_integer_constants, 1);
1178 gdbscm_define_functions (breakpoint_functions, 1);
1180 type_keyword = scm_from_latin1_keyword ("type");
1181 wp_class_keyword = scm_from_latin1_keyword ("wp-class");
1182 internal_keyword = scm_from_latin1_keyword ("internal");