GDB (xrefs)
Loading...
Searching...
No Matches
scm-exception.c
Go to the documentation of this file.
1/* GDB/Scheme exception support.
2
3 Copyright (C) 2014-2023 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20/* See README file in this directory for implementation notes, coding
21 conventions, et.al. */
22
23/* Notes:
24
25 IWBN to support SRFI 34/35. At the moment we follow Guile's own
26 exception mechanism.
27
28 The non-static functions in this file have prefix gdbscm_ and
29 not exscm_ on purpose. */
30
31#include "defs.h"
32#include <signal.h>
33#include "guile-internal.h"
34
35/* The <gdb:exception> smob.
36 This is used to record and handle Scheme exceptions.
37 One important invariant is that <gdb:exception> smobs are never a valid
38 result of a function, other than to signify an exception occurred. */
39
41{
42 /* This always appears first. */
44
45 /* The key and args parameters to "throw". */
46 SCM key;
47 SCM args;
48};
49
50static const char exception_smob_name[] = "gdb:exception";
51
52/* The tag Guile knows the exception smob by. */
53static scm_t_bits exception_smob_tag;
54
55/* A generic error in struct gdb_exception.
56 I.e., not RETURN_QUIT and not MEMORY_ERROR. */
57static SCM error_symbol;
58
59/* An error occurred accessing inferior memory.
60 This is not a Scheme programming error. */
62
63/* User interrupt, e.g., RETURN_QUIT in struct gdb_exception. */
64static SCM signal_symbol;
65
66/* A user error, e.g., bad arg to gdb command. */
68
69/* Printing the stack is done by first capturing the stack and recording it in
70 a <gdb:exception> object with this key and with the ARGS field set to
71 (cons real-key (cons stack real-args)).
72 See gdbscm_make_exception_with_stack. */
74
75/* The key to use for an invalid object exception. An invalid object is one
76 where the underlying object has been removed from GDB. */
78
79/* Values for "guile print-stack" as symbols. */
80static SCM none_symbol;
81static SCM message_symbol;
82static SCM full_symbol;
83
85 "%print-exception-message";
86
87/* Variable containing %print-exception-message.
88 It is not defined until late in initialization, after our init routine
89 has run. Cope by looking it up lazily. */
91
93 "%print-exception-with-stack";
94
95/* Variable containing %print-exception-with-stack.
96 It is not defined until late in initialization, after our init routine
97 has run. Cope by looking it up lazily. */
99
100/* Counter to keep track of the number of times we create a <gdb:exception>
101 object, for performance monitoring purposes. */
102static unsigned long gdbscm_exception_count = 0;
103
104/* Administrivia for exception smobs. */
105
106/* The smob "print" function for <gdb:exception>. */
107
108static int
109exscm_print_exception_smob (SCM self, SCM port, scm_print_state *pstate)
110{
111 exception_smob *e_smob = (exception_smob *) SCM_SMOB_DATA (self);
112
113 gdbscm_printf (port, "#<%s ", exception_smob_name);
114 scm_write (e_smob->key, port);
115 scm_puts (" ", port);
116 scm_write (e_smob->args, port);
117 scm_puts (">", port);
118
119 scm_remember_upto_here_1 (self);
120
121 /* Non-zero means success. */
122 return 1;
123}
124
125/* (make-exception key args) -> <gdb:exception> */
126
127SCM
128gdbscm_make_exception (SCM key, SCM args)
129{
130 exception_smob *e_smob = (exception_smob *)
131 scm_gc_malloc (sizeof (exception_smob), exception_smob_name);
132 SCM smob;
133
134 e_smob->key = key;
135 e_smob->args = args;
136 smob = scm_new_smob (exception_smob_tag, (scm_t_bits) e_smob);
137 gdbscm_init_gsmob (&e_smob->base);
138
140
141 return smob;
142}
143
144/* Return non-zero if SCM is a <gdb:exception> object. */
145
146int
148{
149 return SCM_SMOB_PREDICATE (exception_smob_tag, scm);
150}
151
152/* (exception? scm) -> boolean */
153
154static SCM
156{
157 return scm_from_bool (gdbscm_is_exception (scm));
158}
159
160/* (exception-key <gdb:exception>) -> key */
161
162SCM
164{
165 exception_smob *e_smob;
166
167 SCM_ASSERT_TYPE (gdbscm_is_exception (self), self, SCM_ARG1, FUNC_NAME,
168 "gdb:exception");
169
170 e_smob = (exception_smob *) SCM_SMOB_DATA (self);
171 return e_smob->key;
172}
173
174/* (exception-args <gdb:exception>) -> arg-list */
175
176SCM
178{
179 exception_smob *e_smob;
180
181 SCM_ASSERT_TYPE (gdbscm_is_exception (self), self, SCM_ARG1, FUNC_NAME,
182 "gdb:exception");
183
184 e_smob = (exception_smob *) SCM_SMOB_DATA (self);
185 return e_smob->args;
186}
187
188/* Wrap an exception in a <gdb:exception> object that includes STACK.
189 gdbscm_print_exception_with_stack knows how to unwrap it. */
190
191SCM
192gdbscm_make_exception_with_stack (SCM key, SCM args, SCM stack)
193{
195 scm_cons (key, scm_cons (stack, args)));
196}
197
198/* Version of scm_error_scm that creates a gdb:exception object that can later
199 be passed to gdbscm_throw.
200 KEY is a symbol denoting the kind of error.
201 SUBR is either #f or a string marking the function in which the error
202 occurred.
203 MESSAGE is either #f or the error message string. It may contain ~a and ~s
204 modifiers, provided by ARGS.
205 ARGS is a list of args to MESSAGE.
206 DATA is an arbitrary object, its value depends on KEY. The value to pass
207 here is a bit underspecified by Guile. */
208
209SCM
210gdbscm_make_error_scm (SCM key, SCM subr, SCM message, SCM args, SCM data)
211{
212 return gdbscm_make_exception (key, scm_list_4 (subr, message, args, data));
213}
214
215/* Version of scm_error that creates a gdb:exception object that can later
216 be passed to gdbscm_throw.
217 See gdbscm_make_error_scm for a description of the arguments. */
218
219SCM
220gdbscm_make_error (SCM key, const char *subr, const char *message,
221 SCM args, SCM data)
222{
224 (key,
225 subr == NULL ? SCM_BOOL_F : scm_from_latin1_string (subr),
226 message == NULL ? SCM_BOOL_F : scm_from_latin1_string (message),
227 args, data);
228}
229
230/* Version of SCM_ASSERT_TYPE/scm_wrong_type_arg_msg that creates a
231 gdb:exception object that can later be passed to gdbscm_throw. */
232
233SCM
234gdbscm_make_type_error (const char *subr, int arg_pos, SCM bad_value,
235 const char *expected_type)
236{
237 gdb::unique_xmalloc_ptr<char> msg;
238 SCM result;
239
240 if (arg_pos > 0)
241 {
242 if (expected_type != NULL)
243 {
244 msg = xstrprintf (_("Wrong type argument in position %d"
245 " (expecting %s): ~S"),
246 arg_pos, expected_type);
247 }
248 else
249 {
250 msg = xstrprintf (_("Wrong type argument in position %d: ~S"),
251 arg_pos);
252 }
253 }
254 else
255 {
256 if (expected_type != NULL)
257 {
258 msg = xstrprintf (_("Wrong type argument (expecting %s): ~S"),
259 expected_type);
260 }
261 else
262 msg = xstrprintf (_("Wrong type argument: ~S"));
263 }
264
265 result = gdbscm_make_error (scm_arg_type_key, subr, msg.get (),
266 scm_list_1 (bad_value), scm_list_1 (bad_value));
267 return result;
268}
269
270/* A variant of gdbscm_make_type_error for non-type argument errors.
271 ERROR_PREFIX and ERROR are combined to build the error message.
272 Care needs to be taken so that the i18n composed form is still
273 reasonable, but no one is going to translate these anyway so we don't
274 worry too much.
275 ERROR_PREFIX may be NULL, ERROR may not be NULL. */
276
277static SCM
278gdbscm_make_arg_error (SCM key, const char *subr, int arg_pos, SCM bad_value,
279 const char *error_prefix, const char *error)
280{
281 gdb::unique_xmalloc_ptr<char> msg;
282 SCM result;
283
284 if (error_prefix != NULL)
285 {
286 if (arg_pos > 0)
287 {
288 msg = xstrprintf (_("%s %s in position %d: ~S"),
289 error_prefix, error, arg_pos);
290 }
291 else
292 msg = xstrprintf (_("%s %s: ~S"), error_prefix, error);
293 }
294 else
295 {
296 if (arg_pos > 0)
297 msg = xstrprintf (_("%s in position %d: ~S"), error, arg_pos);
298 else
299 msg = xstrprintf (_("%s: ~S"), error);
300 }
301
302 result = gdbscm_make_error (key, subr, msg.get (), scm_list_1 (bad_value),
303 scm_list_1 (bad_value));
304 return result;
305}
306
307/* Make an invalid-object error <gdb:exception> object.
308 OBJECT is the name of the kind of object that is invalid. */
309
310SCM
311gdbscm_make_invalid_object_error (const char *subr, int arg_pos, SCM bad_value,
312 const char *object)
313{
315 subr, arg_pos, bad_value,
316 _("Invalid object:"), object);
317}
318
319/* Throw an invalid-object error.
320 OBJECT is the name of the kind of object that is invalid. */
321
322void
323gdbscm_invalid_object_error (const char *subr, int arg_pos, SCM bad_value,
324 const char *object)
325{
326 SCM exception
327 = gdbscm_make_invalid_object_error (subr, arg_pos, bad_value, object);
328
329 gdbscm_throw (exception);
330}
331
332/* Make an out-of-range error <gdb:exception> object. */
333
334SCM
335gdbscm_make_out_of_range_error (const char *subr, int arg_pos, SCM bad_value,
336 const char *error)
337{
338 return gdbscm_make_arg_error (scm_out_of_range_key,
339 subr, arg_pos, bad_value,
340 _("Out of range:"), error);
341}
342
343/* Throw an out-of-range error.
344 This is the standard Guile out-of-range exception. */
345
346void
347gdbscm_out_of_range_error (const char *subr, int arg_pos, SCM bad_value,
348 const char *error)
349{
350 SCM exception
351 = gdbscm_make_out_of_range_error (subr, arg_pos, bad_value, error);
352
353 gdbscm_throw (exception);
354}
355
356/* Make a misc-error <gdb:exception> object. */
357
358SCM
359gdbscm_make_misc_error (const char *subr, int arg_pos, SCM bad_value,
360 const char *error)
361{
362 return gdbscm_make_arg_error (scm_misc_error_key,
363 subr, arg_pos, bad_value, NULL, error);
364}
365
366/* Throw a misc-error error. */
367
368void
369gdbscm_misc_error (const char *subr, int arg_pos, SCM bad_value,
370 const char *error)
371{
372 SCM exception = gdbscm_make_misc_error (subr, arg_pos, bad_value, error);
373
374 gdbscm_throw (exception);
375}
376
377/* Return a <gdb:exception> object for gdb:memory-error. */
378
379SCM
380gdbscm_make_memory_error (const char *subr, const char *msg, SCM args)
381{
382 return gdbscm_make_error (memory_error_symbol, subr, msg, args,
383 SCM_EOL);
384}
385
386/* Throw a gdb:memory-error exception. */
387
388void
389gdbscm_memory_error (const char *subr, const char *msg, SCM args)
390{
391 SCM exception = gdbscm_make_memory_error (subr, msg, args);
392
393 gdbscm_throw (exception);
394}
395
396/* Return non-zero if KEY is gdb:memory-error.
397 Note: This is an excp_matcher_func function. */
398
399int
401{
402 return scm_is_eq (key, memory_error_symbol);
403}
404
405/* Return non-zero if KEY is gdb:user-error.
406 Note: This is an excp_matcher_func function. */
407
408int
410{
411 return scm_is_eq (key, user_error_symbol);
412}
413
414/* Wrapper around scm_throw to throw a gdb:exception.
415 This function does not return.
416 This function cannot be called from inside TRY_CATCH. */
417
418void
419gdbscm_throw (SCM exception)
420{
421 scm_throw (gdbscm_exception_key (exception),
422 gdbscm_exception_args (exception));
423 gdb_assert_not_reached ("scm_throw returned");
424}
425
426/* Convert a GDB exception to a <gdb:exception> object. */
427
428SCM
430{
431 SCM key;
432
433 if (exception.reason == RETURN_QUIT)
434 {
435 /* Handle this specially to be consistent with top-repl.scm. */
436 return gdbscm_make_error (signal_symbol, NULL, _("User interrupt"),
437 SCM_EOL, scm_list_1 (scm_from_int (SIGINT)));
438 }
439
440 if (exception.error == MEMORY_ERROR)
442 else
443 key = error_symbol;
444
445 return gdbscm_make_error (key, NULL, "~A",
446 scm_list_1 (gdbscm_scm_from_c_string
447 (exception.message)),
448 SCM_BOOL_F);
449}
450
451/* Convert a GDB exception to the appropriate Scheme exception and throw it.
452 This function does not return. */
453
454void
456{
457 SCM scm_exception = gdbscm_scm_from_gdb_exception (exception);
458 xfree (exception.message);
459 gdbscm_throw (scm_exception);
460}
461
462/* Print the error message portion of an exception.
463 If PORT is #f, use the standard error port.
464 KEY cannot be gdb:with-stack.
465
466 Basically this function is just a wrapper around calling
467 %print-exception-message. */
468
469static void
470gdbscm_print_exception_message (SCM port, SCM frame, SCM key, SCM args)
471{
472 SCM printer, status;
473
474 if (gdbscm_is_false (port))
475 port = scm_current_error_port ();
476
477 gdb_assert (!scm_is_eq (key, with_stack_error_symbol));
478
479 /* This does not use scm_print_exception because we tweak the output a bit.
480 Compare Guile's print-exception with our %print-exception-message for
481 details. */
483 {
485 = scm_c_private_variable (gdbscm_init_module_name,
487 /* If we can't find %print-exception-message, there's a problem on the
488 Scheme side. Don't kill GDB, just flag an error and leave it at
489 that. */
491 {
492 gdbscm_printf (port, _("Error in Scheme exception printing,"
493 " can't find %s.\n"),
495 return;
496 }
497 }
498 printer = scm_variable_ref (percent_print_exception_message_var);
499
500 status = gdbscm_safe_call_4 (printer, port, frame, key, args, NULL);
501
502 /* If that failed still tell the user something.
503 But don't use the exception printing machinery! */
505 {
506 gdbscm_printf (port, _("Error in Scheme exception printing:\n"));
507 scm_display (status, port);
508 scm_newline (port);
509 }
510}
511
512/* Print the description of exception KEY, ARGS to PORT, according to the
513 setting of "set guile print-stack".
514 If PORT is #f, use the standard error port.
515 If STACK is #f, never print the stack, regardless of whether printing it
516 is enabled. If STACK is #t, then print it if it is contained in ARGS
517 (i.e., KEY is gdb:with-stack). Otherwise STACK is the result of calling
518 scm_make_stack (which will be ignored in favor of the stack in ARGS if
519 KEY is gdb:with-stack).
520 KEY, ARGS are the standard arguments to scm_throw, et.al.
521
522 Basically this function is just a wrapper around calling
523 %print-exception-with-stack. */
524
525void
526gdbscm_print_exception_with_stack (SCM port, SCM stack, SCM key, SCM args)
527{
528 SCM printer, status;
529
530 if (gdbscm_is_false (port))
531 port = scm_current_error_port ();
532
534 {
536 = scm_c_private_variable (gdbscm_init_module_name,
538 /* If we can't find %print-exception-with-stack, there's a problem on the
539 Scheme side. Don't kill GDB, just flag an error and leave it at
540 that. */
542 {
543 gdbscm_printf (port, _("Error in Scheme exception printing,"
544 " can't find %s.\n"),
546 return;
547 }
548 }
549 printer = scm_variable_ref (percent_print_exception_with_stack_var);
550
551 status = gdbscm_safe_call_4 (printer, port, stack, key, args, NULL);
552
553 /* If that failed still tell the user something.
554 But don't use the exception printing machinery! */
556 {
557 gdbscm_printf (port, _("Error in Scheme exception printing:\n"));
558 scm_display (status, port);
559 scm_newline (port);
560 }
561}
562
563/* Print EXCEPTION, a <gdb:exception> object, to PORT.
564 If PORT is #f, use the standard error port. */
565
566void
567gdbscm_print_gdb_exception (SCM port, SCM exception)
568{
569 gdb_assert (gdbscm_is_exception (exception));
570
571 gdbscm_print_exception_with_stack (port, SCM_BOOL_T,
572 gdbscm_exception_key (exception),
573 gdbscm_exception_args (exception));
574}
575
576/* Return a string description of <gdb:exception> EXCEPTION.
577 If EXCEPTION is a gdb:with-stack exception, unwrap it, a backtrace
578 is never returned as part of the result. */
579
580gdb::unique_xmalloc_ptr<char>
582{
583 SCM port = scm_open_output_string ();
584 SCM key, args;
585
586 gdb_assert (gdbscm_is_exception (exception));
587
588 key = gdbscm_exception_key (exception);
589 args = gdbscm_exception_args (exception);
590
591 if (scm_is_eq (key, with_stack_error_symbol)
592 /* Don't crash on a badly generated gdb:with-stack exception. */
593 && scm_is_pair (args)
594 && scm_is_pair (scm_cdr (args)))
595 {
596 key = scm_car (args);
597 args = scm_cddr (args);
598 }
599
600 gdbscm_print_exception_message (port, SCM_BOOL_F, key, args);
601 gdb::unique_xmalloc_ptr<char> result
602 = gdbscm_scm_to_c_string (scm_get_output_string (port));
603 scm_close_port (port);
604 return result;
605}
606
607/* Return the value of the "guile print-stack" option as one of:
608 'none, 'message, 'full. */
609
610static SCM
612{
614 return none_symbol;
616 return message_symbol;
618 return full_symbol;
619 gdb_assert_not_reached ("bad value for \"guile print-stack\"");
620}
621
622/* Return the current <gdb:exception> counter.
623 This is for debugging purposes. */
624
625static SCM
627{
628 return scm_from_ulong (gdbscm_exception_count);
629}
630
631/* Initialize the Scheme exception support. */
632
634{
635 { "make-exception", 2, 0, 0, as_a_scm_t_subr (gdbscm_make_exception),
636 "\
637Create a <gdb:exception> object.\n\
638\n\
639 Arguments: key args\n\
640 These are the standard key,args arguments of \"throw\"." },
641
642 { "exception?", 1, 0, 0, as_a_scm_t_subr (gdbscm_exception_p),
643 "\
644Return #t if the object is a <gdb:exception> object." },
645
646 { "exception-key", 1, 0, 0, as_a_scm_t_subr (gdbscm_exception_key),
647 "\
648Return the exception's key." },
649
650 { "exception-args", 1, 0, 0, as_a_scm_t_subr (gdbscm_exception_args),
651 "\
652Return the exception's arg list." },
653
655};
656
658{
659 { "%exception-print-style", 0, 0, 0,
661 "\
662Return the value of the \"guile print-stack\" option." },
663
664 { "%exception-count", 0, 0, 0,
666 "\
667Return a count of the number of <gdb:exception> objects created.\n\
668This is for debugging purposes." },
669
671};
672
673void
675{
677 sizeof (exception_smob));
679
682
683 error_symbol = scm_from_latin1_symbol ("gdb:error");
684
685 memory_error_symbol = scm_from_latin1_symbol ("gdb:memory-error");
686
687 user_error_symbol = scm_from_latin1_symbol ("gdb:user-error");
688
690 = scm_from_latin1_symbol ("gdb:invalid-object-error");
691
692 with_stack_error_symbol = scm_from_latin1_symbol ("gdb:with-stack");
693
694 /* The text of this symbol is taken from Guile's top-repl.scm. */
695 signal_symbol = scm_from_latin1_symbol ("signal");
696
697 none_symbol = scm_from_latin1_symbol ("none");
698 message_symbol = scm_from_latin1_symbol ("message");
699 full_symbol = scm_from_latin1_symbol ("full");
700}
static struct parser_state * pstate
Definition ada-exp.c:101
void xfree(void *)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int status
Definition gnu-nat.c:1790
const char gdbscm_print_excp_none[]
Definition guile.c:57
const char * gdbscm_print_excp
Definition guile.c:74
#define END_FUNCTIONS
void gdbscm_init_gsmob(gdb_smob *base)
Definition scm-gsmob.c:140
SCM gdbscm_safe_call_4(SCM proc, SCM arg0, SCM arg1, SCM arg2, SCM arg3, excp_matcher_func *ok_excps)
const char gdbscm_print_excp_message[]
Definition guile.c:59
excp_matcher_func gdbscm_memory_error_p
#define gdbscm_is_false(scm)
void gdbscm_printf(SCM port, const char *format,...) ATTRIBUTE_PRINTF(2
gdb::unique_xmalloc_ptr< char > gdbscm_scm_to_c_string(SCM string)
Definition scm-string.c:55
const char gdbscm_init_module_name[]
static SCM scm_new_smob(scm_t_bits tc, scm_t_bits data)
void gdbscm_define_functions(const scheme_function *, int is_public)
Definition scm-utils.c:44
const char gdbscm_print_excp_full[]
Definition guile.c:58
scm_t_bits gdbscm_make_smob_type(const char *name, size_t size)
Definition scm-gsmob.c:103
static scm_t_subr as_a_scm_t_subr(SCM(*func)(void))
excp_matcher_func gdbscm_user_error_p
#define FUNC_NAME
SCM gdbscm_scm_from_c_string(const char *string)
Definition scm-string.c:45
void gdbscm_out_of_range_error(const char *subr, int arg_pos, SCM bad_value, const char *error)
SCM gdbscm_make_out_of_range_error(const char *subr, int arg_pos, SCM bad_value, const char *error)
static SCM full_symbol
static SCM signal_symbol
SCM gdbscm_make_type_error(const char *subr, int arg_pos, SCM bad_value, const char *expected_type)
static SCM gdbscm_percent_exception_print_style(void)
void gdbscm_print_exception_with_stack(SCM port, SCM stack, SCM key, SCM args)
void gdbscm_invalid_object_error(const char *subr, int arg_pos, SCM bad_value, const char *object)
static scm_t_bits exception_smob_tag
SCM gdbscm_make_invalid_object_error(const char *subr, int arg_pos, SCM bad_value, const char *object)
static SCM message_symbol
static SCM with_stack_error_symbol
void gdbscm_memory_error(const char *subr, const char *msg, SCM args)
static SCM memory_error_symbol
SCM gdbscm_make_misc_error(const char *subr, int arg_pos, SCM bad_value, const char *error)
static const scheme_function exception_functions[]
void gdbscm_print_gdb_exception(SCM port, SCM exception)
static SCM none_symbol
SCM gdbscm_scm_from_gdb_exception(const gdbscm_gdb_exception &exception)
SCM gdbscm_exception_args(SCM self)
static SCM percent_print_exception_message_var
void gdbscm_throw(SCM exception)
void gdbscm_initialize_exceptions(void)
static unsigned long gdbscm_exception_count
gdb::unique_xmalloc_ptr< char > gdbscm_exception_message_to_string(SCM exception)
SCM gdbscm_exception_key(SCM self)
SCM gdbscm_make_memory_error(const char *subr, const char *msg, SCM args)
static SCM user_error_symbol
static SCM error_symbol
static void gdbscm_print_exception_message(SCM port, SCM frame, SCM key, SCM args)
SCM gdbscm_invalid_object_error_symbol
void gdbscm_misc_error(const char *subr, int arg_pos, SCM bad_value, const char *error)
static const char percent_print_exception_with_stack_name[]
SCM gdbscm_make_error_scm(SCM key, SCM subr, SCM message, SCM args, SCM data)
static SCM gdbscm_exception_p(SCM scm)
static const scheme_function private_exception_functions[]
SCM gdbscm_make_exception_with_stack(SCM key, SCM args, SCM stack)
int gdbscm_is_exception(SCM scm)
static const char exception_smob_name[]
static SCM gdbscm_make_arg_error(SCM key, const char *subr, int arg_pos, SCM bad_value, const char *error_prefix, const char *error)
SCM gdbscm_make_exception(SCM key, SCM args)
static const char percent_print_exception_message_name[]
void gdbscm_throw_gdb_exception(gdbscm_gdb_exception exception)
static SCM gdbscm_percent_exception_count(void)
SCM gdbscm_make_error(SCM key, const char *subr, const char *message, SCM args, SCM data)
static SCM percent_print_exception_with_stack_var
static int exscm_print_exception_smob(SCM self, SCM port, scm_print_state *pstate)
enum return_reason reason