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