1 /* Debugging extensions for Guile
2 * Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2006, 2008, 2009 Free Software Foundation
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 3 of
7 * the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27 #include <sys/resource.h>
30 #include "libguile/_scm.h"
31 #include "libguile/async.h"
32 #include "libguile/eval.h"
33 #include "libguile/list.h"
34 #include "libguile/stackchk.h"
35 #include "libguile/throw.h"
36 #include "libguile/macros.h"
37 #include "libguile/smob.h"
38 #include "libguile/procprop.h"
39 #include "libguile/srcprop.h"
40 #include "libguile/alist.h"
41 #include "libguile/continuations.h"
42 #include "libguile/strports.h"
43 #include "libguile/read.h"
44 #include "libguile/feature.h"
45 #include "libguile/dynwind.h"
46 #include "libguile/modules.h"
47 #include "libguile/ports.h"
48 #include "libguile/root.h"
49 #include "libguile/fluids.h"
50 #include "libguile/programs.h"
51 #include "libguile/memoize.h"
52 #include "libguile/vm.h"
54 #include "libguile/validate.h"
55 #include "libguile/debug.h"
57 #include "libguile/private-options.h"
61 /* {Run time control of the debugging evaluator}
64 SCM_DEFINE (scm_debug_options
, "debug-options-interface", 0, 1, 0,
66 "Option interface for the debug options. Instead of using\n"
67 "this procedure directly, use the procedures @code{debug-enable},\n"
68 "@code{debug-disable}, @code{debug-set!} and @code{debug-options}.")
69 #define FUNC_NAME s_scm_debug_options
73 scm_dynwind_begin (0);
74 scm_dynwind_critical_section (SCM_BOOL_F
);
76 ans
= scm_options (setting
, scm_debug_opts
, FUNC_NAME
);
79 scm_options (ans
, scm_debug_opts
, FUNC_NAME
);
80 SCM_OUT_OF_RANGE (1, setting
);
83 scm_stack_checking_enabled_p
= SCM_STACK_CHECKING_P
;
93 with_traps_before (void *data
)
95 int *trap_flag
= data
;
96 *trap_flag
= SCM_TRAPS_P
;
101 with_traps_after (void *data
)
103 int *trap_flag
= data
;
104 SCM_TRAPS_P
= *trap_flag
;
108 with_traps_inner (void *data
)
110 SCM thunk
= SCM_PACK ((scm_t_bits
) data
);
111 return scm_call_0 (thunk
);
114 SCM_DEFINE (scm_with_traps
, "with-traps", 1, 0, 0,
116 "Call @var{thunk} with traps enabled.")
117 #define FUNC_NAME s_scm_with_traps
120 SCM_VALIDATE_THUNK (1, thunk
);
121 return scm_internal_dynamic_wind (with_traps_before
,
124 (void *) SCM_UNPACK (thunk
),
130 SCM_SYMBOL (scm_sym_procname
, "procname");
131 SCM_SYMBOL (scm_sym_dots
, "...");
132 SCM_SYMBOL (scm_sym_source
, "source");
134 SCM_DEFINE (scm_procedure_name
, "procedure-name", 1, 0, 0,
136 "Return the name of the procedure @var{proc}")
137 #define FUNC_NAME s_scm_procedure_name
139 SCM_VALIDATE_PROC (1, proc
);
140 switch (SCM_TYP7 (proc
)) {
142 return SCM_SUBR_NAME (proc
);
145 SCM name
= scm_procedure_property (proc
, scm_sym_name
);
146 if (scm_is_false (name
) && SCM_PROGRAM_P (proc
))
147 name
= scm_program_name (proc
);
154 SCM_DEFINE (scm_procedure_source
, "procedure-source", 1, 0, 0,
156 "Return the source of the procedure @var{proc}.")
157 #define FUNC_NAME s_scm_procedure_source
160 SCM_VALIDATE_PROC (1, proc
);
164 src
= scm_procedure_property (proc
, scm_sym_source
);
165 if (scm_is_true (src
))
168 switch (SCM_TYP7 (proc
)) {
170 if (!SCM_STRUCT_APPLICABLE_P (proc
)
171 || SCM_IMP (SCM_STRUCT_PROCEDURE (proc
)))
173 proc
= SCM_STRUCT_PROCEDURE (proc
);
176 proc
= SCM_PROCEDURE (proc
);
192 SCM_REGISTER_PROC (s_reverse_lookup
, "reverse-lookup", 2, 0, 0, scm_reverse_lookup
);
196 scm_reverse_lookup (SCM env
, SCM data
)
198 while (scm_is_pair (env
) && scm_is_pair (SCM_CAR (env
)))
200 SCM names
= SCM_CAAR (env
);
201 SCM values
= SCM_CDAR (env
);
202 while (scm_is_pair (names
))
204 if (scm_is_eq (SCM_CAR (values
), data
))
205 return SCM_CAR (names
);
206 names
= SCM_CDR (names
);
207 values
= SCM_CDR (values
);
209 if (!scm_is_null (names
) && scm_is_eq (values
, data
))
216 SCM_DEFINE (scm_sys_start_stack
, "%start-stack", 2, 0, 0,
218 "Call @var{thunk} on an evaluator stack tagged with @var{id}.")
219 #define FUNC_NAME s_scm_sys_start_stack
221 return scm_vm_call_with_new_stack (scm_the_vm (), thunk
, id
);
227 /* Undocumented debugging procedure */
229 SCM_DEFINE (scm_debug_hang
, "debug-hang", 0, 1, 0,
231 "Go into an endless loop, which can be only terminated with\n"
233 #define FUNC_NAME s_scm_debug_hang
237 return SCM_UNSPECIFIED
;
243 init_stack_limit (void)
245 #ifdef HAVE_GETRLIMIT
247 if (getrlimit (RLIMIT_STACK
, &lim
) == 0)
249 rlim_t bytes
= lim
.rlim_cur
;
251 /* set our internal stack limit to 80% of the rlimit. */
252 if (bytes
== RLIM_INFINITY
)
253 bytes
= lim
.rlim_max
;
255 if (bytes
!= RLIM_INFINITY
)
256 SCM_STACK_LIMIT
= bytes
* 8 / 10 / sizeof (scm_t_bits
);
268 scm_init_opts (scm_debug_options
, scm_debug_opts
);
270 scm_add_feature ("debug-extensions");
272 #include "libguile/debug.x"